ia64/linux-2.6.18-xen.hg

view drivers/block/ps2esdi.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /* ps2esdi driver based on assembler code by Arindam Banerji,
2 written by Peter De Schrijver */
3 /* Reassuring note to IBM : This driver was NOT developed by vice-versa
4 engineering the PS/2's BIOS */
5 /* Dedicated to Wannes, Tofke, Ykke, Godot, Killroy and all those
6 other lovely fish out there... */
7 /* This code was written during the long and boring WINA
8 elections 1994 */
9 /* Thanks to Arindam Banerij for giving me the source of his driver */
10 /* This code may be freely distributed and modified in any way,
11 as long as these notes remain intact */
13 /* Revised: 05/07/94 by Arindam Banerji (axb@cse.nd.edu) */
14 /* Revised: 09/08/94 by Peter De Schrijver (stud11@cc4.kuleuven.ac.be)
15 Thanks to Arindam Banerij for sending me the docs of the adapter */
17 /* BA Modified for ThinkPad 720 by Boris Ashkinazi */
18 /* (bash@vnet.ibm.com) 08/08/95 */
20 /* Modified further for ThinkPad-720C by Uri Blumenthal */
21 /* (uri@watson.ibm.com) Sep 11, 1995 */
23 /* TODO :
24 + Timeouts
25 + Get disk parameters
26 + DMA above 16MB
27 + reset after read/write error
28 */
30 #define DEVICE_NAME "PS/2 ESDI"
32 #include <linux/major.h>
33 #include <linux/errno.h>
34 #include <linux/wait.h>
35 #include <linux/interrupt.h>
36 #include <linux/fs.h>
37 #include <linux/kernel.h>
38 #include <linux/genhd.h>
39 #include <linux/ps2esdi.h>
40 #include <linux/blkdev.h>
41 #include <linux/mca-legacy.h>
42 #include <linux/init.h>
43 #include <linux/ioport.h>
44 #include <linux/module.h>
45 #include <linux/hdreg.h>
47 #include <asm/system.h>
48 #include <asm/io.h>
49 #include <asm/dma.h>
50 #include <asm/mca_dma.h>
51 #include <asm/uaccess.h>
53 #define PS2ESDI_IRQ 14
54 #define MAX_HD 2
55 #define MAX_RETRIES 5
56 #define MAX_16BIT 65536
57 #define ESDI_TIMEOUT 0xf000
58 #define ESDI_STAT_TIMEOUT 4
60 #define TYPE_0_CMD_BLK_LENGTH 2
61 #define TYPE_1_CMD_BLK_LENGTH 4
63 static void reset_ctrl(void);
65 static int ps2esdi_geninit(void);
67 static void do_ps2esdi_request(request_queue_t * q);
69 static void ps2esdi_readwrite(int cmd, struct request *req);
71 static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
72 u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
74 static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
76 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
78 static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id,
79 struct pt_regs *regs);
80 static void (*current_int_handler) (u_int) = NULL;
81 static void ps2esdi_normal_interrupt_handler(u_int);
82 static void ps2esdi_initial_reset_int_handler(u_int);
83 static void ps2esdi_geometry_int_handler(u_int);
84 static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
86 static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
88 static void dump_cmd_complete_status(u_int int_ret_code);
90 static void ps2esdi_get_device_cfg(void);
92 static void ps2esdi_reset_timer(unsigned long unused);
94 static u_int dma_arb_level; /* DMA arbitration level */
96 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
98 static int no_int_yet;
99 static int ps2esdi_drives;
100 static u_short io_base;
101 static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0);
102 static int reset_status;
103 static int ps2esdi_slot = -1;
104 static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
105 static int intg_esdi = 0; /* If integrated adapter */
106 struct ps2esdi_i_struct {
107 unsigned int head, sect, cyl, wpcom, lzone, ctl;
108 };
109 static DEFINE_SPINLOCK(ps2esdi_lock);
110 static struct request_queue *ps2esdi_queue;
111 static struct request *current_req;
113 #if 0
114 #if 0 /* try both - I don't know which one is better... UB */
115 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
116 {
117 {4, 48, 1553, 0, 0, 0},
118 {0, 0, 0, 0, 0, 0}};
119 #else
120 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
121 {
122 {64, 32, 161, 0, 0, 0},
123 {0, 0, 0, 0, 0, 0}};
124 #endif
125 #endif
126 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
127 {
128 {0, 0, 0, 0, 0, 0},
129 {0, 0, 0, 0, 0, 0}};
131 static struct block_device_operations ps2esdi_fops =
132 {
133 .owner = THIS_MODULE,
134 .getgeo = ps2esdi_getgeo,
135 };
137 static struct gendisk *ps2esdi_gendisk[2];
139 /* initialization routine called by ll_rw_blk.c */
140 static int __init ps2esdi_init(void)
141 {
143 int error = 0;
145 /* register the device - pass the name and major number */
146 if (register_blkdev(PS2ESDI_MAJOR, "ed"))
147 return -EBUSY;
149 /* set up some global information - indicating device specific info */
150 ps2esdi_queue = blk_init_queue(do_ps2esdi_request, &ps2esdi_lock);
151 if (!ps2esdi_queue) {
152 unregister_blkdev(PS2ESDI_MAJOR, "ed");
153 return -ENOMEM;
154 }
156 /* some minor housekeeping - setup the global gendisk structure */
157 error = ps2esdi_geninit();
158 if (error) {
159 printk(KERN_WARNING "PS2ESDI: error initialising"
160 " device, releasing resources\n");
161 unregister_blkdev(PS2ESDI_MAJOR, "ed");
162 blk_cleanup_queue(ps2esdi_queue);
163 return error;
164 }
165 return 0;
166 } /* ps2esdi_init */
168 #ifndef MODULE
170 module_init(ps2esdi_init);
172 #else
174 static int cyl[MAX_HD] = {-1,-1};
175 static int head[MAX_HD] = {-1, -1};
176 static int sect[MAX_HD] = {-1, -1};
178 module_param(tp720esdi, bool, 0);
179 module_param_array(cyl, int, NULL, 0);
180 module_param_array(head, int, NULL, 0);
181 module_param_array(sect, int, NULL, 0);
182 MODULE_LICENSE("GPL");
184 int init_module(void) {
185 int drive;
187 for(drive = 0; drive < MAX_HD; drive++) {
188 struct ps2esdi_i_struct *info = &ps2esdi_info[drive];
190 if (cyl[drive] != -1) {
191 info->cyl = info->lzone = cyl[drive];
192 info->wpcom = 0;
193 }
194 if (head[drive] != -1) {
195 info->head = head[drive];
196 info->ctl = (head[drive] > 8 ? 8 : 0);
197 }
198 if (sect[drive] != -1) info->sect = sect[drive];
199 }
200 return ps2esdi_init();
201 }
203 void
204 cleanup_module(void) {
205 int i;
206 if(ps2esdi_slot) {
207 mca_mark_as_unused(ps2esdi_slot);
208 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
209 }
210 release_region(io_base, 4);
211 free_dma(dma_arb_level);
212 free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
213 unregister_blkdev(PS2ESDI_MAJOR, "ed");
214 blk_cleanup_queue(ps2esdi_queue);
215 for (i = 0; i < ps2esdi_drives; i++) {
216 del_gendisk(ps2esdi_gendisk[i]);
217 put_disk(ps2esdi_gendisk[i]);
218 }
219 }
220 #endif /* MODULE */
222 /* handles boot time command line parameters */
223 void __init tp720_setup(char *str, int *ints)
224 {
225 /* no params, just sets the tp720esdi flag if it exists */
227 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
228 tp720esdi = 1;
229 }
231 void __init ed_setup(char *str, int *ints)
232 {
233 int hdind = 0;
235 /* handles 3 parameters only - corresponding to
236 1. Number of cylinders
237 2. Number of heads
238 3. Sectors/track
239 */
241 if (ints[0] != 3)
242 return;
244 /* print out the information - seen at boot time */
245 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
246 DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]);
248 /* set the index into device specific information table */
249 if (ps2esdi_info[0].head != 0)
250 hdind = 1;
252 /* set up all the device information */
253 ps2esdi_info[hdind].head = ints[2];
254 ps2esdi_info[hdind].sect = ints[3];
255 ps2esdi_info[hdind].cyl = ints[1];
256 ps2esdi_info[hdind].wpcom = 0;
257 ps2esdi_info[hdind].lzone = ints[1];
258 ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
259 #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
260 ps2esdi_drives = hdind + 1; /* increment index for the next time */
261 #endif
262 } /* ed_setup */
264 static int ps2esdi_getinfo(char *buf, int slot, void *d)
265 {
266 int len = 0;
268 len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
269 dma_arb_level);
270 len += sprintf(buf + len, "IO Port: %x\n", io_base);
271 len += sprintf(buf + len, "IRQ: 14\n");
272 len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives);
274 return len;
275 }
277 /* ps2 esdi specific initialization - called thru the gendisk chain */
278 static int __init ps2esdi_geninit(void)
279 {
280 /*
281 The first part contains the initialization code
282 for the ESDI disk subsystem. All we really do
283 is search for the POS registers of the controller
284 to do some simple setup operations. First, we
285 must ensure that the controller is installed,
286 enabled, and configured as PRIMARY. Then we must
287 determine the DMA arbitration level being used by
288 the controller so we can handle data transfer
289 operations properly. If all of this works, then
290 we will set the INIT_FLAG to a non-zero value.
291 */
293 int slot = 0, i, reset_start, reset_end;
294 u_char status;
295 unsigned short adapterID;
296 int error = 0;
298 if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
299 adapterID = INTG_ESDI_ID;
300 printk("%s: integrated ESDI adapter found in slot %d\n",
301 DEVICE_NAME, slot+1);
302 #ifndef MODULE
303 mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
304 #endif
305 } else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) {
306 adapterID = NRML_ESDI_ID;
307 printk("%s: normal ESDI adapter found in slot %d\n",
308 DEVICE_NAME, slot+1);
309 mca_set_adapter_name(slot, "PS/2 ESDI");
310 } else {
311 return -ENODEV;
312 }
314 ps2esdi_slot = slot;
315 mca_mark_as_used(slot);
316 mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL);
318 /* Found the slot - read the POS register 2 to get the necessary
319 configuration and status information. POS register 2 has the
320 following information :
321 Bit Function
322 7 reserved = 0
323 6 arbitration method
324 0 - fairness enabled
325 1 - fairness disabled, linear priority assignment
326 5-2 arbitration level
327 1 alternate address
328 1 alternate address
329 0 - use addresses 0x3510 - 0x3517
330 0 adapter enable
331 */
333 status = mca_read_stored_pos(slot, 2);
334 /* is it enabled ? */
335 if (!(status & STATUS_ENABLED)) {
336 printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
337 error = -ENODEV;
338 goto err_out1;
339 }
340 /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
341 share with the SCSI driver */
342 if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
343 IRQF_DISABLED | IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
344 && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
345 IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
346 ) {
347 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
348 error = -EBUSY;
349 goto err_out1;
350 }
351 if (status & STATUS_ALTERNATE)
352 io_base = ALT_IO_BASE;
353 else
354 io_base = PRIMARY_IO_BASE;
356 if (!request_region(io_base, 4, "ed")) {
357 printk(KERN_WARNING"Unable to request region 0x%x\n", io_base);
358 error = -EBUSY;
359 goto err_out2;
360 }
361 /* get the dma arbitration level */
362 dma_arb_level = (status >> 2) & 0xf;
364 /* BA */
365 printk("%s: DMA arbitration level : %d\n",
366 DEVICE_NAME, dma_arb_level);
368 LITE_ON;
369 current_int_handler = ps2esdi_initial_reset_int_handler;
370 reset_ctrl();
371 reset_status = 0;
372 reset_start = jiffies;
373 while (!reset_status) {
374 init_timer(&esdi_timer);
375 esdi_timer.expires = jiffies + HZ;
376 esdi_timer.data = 0;
377 add_timer(&esdi_timer);
378 sleep_on(&ps2esdi_int);
379 }
380 reset_end = jiffies;
381 LITE_OFF;
382 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
383 DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
384 (reset_end - reset_start) % HZ);
387 /* Integrated ESDI Disk and Controller has only one drive! */
388 if (adapterID == INTG_ESDI_ID) {/* if not "normal" PS2 ESDI adapter */
389 ps2esdi_drives = 1; /* then we have only one physical disk! */ intg_esdi = 1;
390 }
394 /* finally this part sets up some global data structures etc. */
396 ps2esdi_get_device_cfg();
398 /* some annoyance in the above routine returns TWO drives?
399 Is something else happining in the background?
400 Regaurdless we fix the # of drives again. AJK */
401 /* Integrated ESDI Disk and Controller has only one drive! */
402 if (adapterID == INTG_ESDI_ID) /* if not "normal" PS2 ESDI adapter */
403 ps2esdi_drives = 1; /* Not three or two, ONE DAMNIT! */
405 current_int_handler = ps2esdi_normal_interrupt_handler;
407 if (request_dma(dma_arb_level, "ed") !=0) {
408 printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n"
409 ,(int) dma_arb_level);
410 error = -EBUSY;
411 goto err_out3;
412 }
413 blk_queue_max_sectors(ps2esdi_queue, 128);
415 error = -ENOMEM;
416 for (i = 0; i < ps2esdi_drives; i++) {
417 struct gendisk *disk = alloc_disk(64);
418 if (!disk)
419 goto err_out4;
420 disk->major = PS2ESDI_MAJOR;
421 disk->first_minor = i<<6;
422 sprintf(disk->disk_name, "ed%c", 'a'+i);
423 disk->fops = &ps2esdi_fops;
424 ps2esdi_gendisk[i] = disk;
425 }
427 for (i = 0; i < ps2esdi_drives; i++) {
428 struct gendisk *disk = ps2esdi_gendisk[i];
429 set_capacity(disk, ps2esdi_info[i].head * ps2esdi_info[i].sect *
430 ps2esdi_info[i].cyl);
431 disk->queue = ps2esdi_queue;
432 disk->private_data = &ps2esdi_info[i];
433 add_disk(disk);
434 }
435 return 0;
436 err_out4:
437 while (i--)
438 put_disk(ps2esdi_gendisk[i]);
439 err_out3:
440 release_region(io_base, 4);
441 err_out2:
442 free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
443 err_out1:
444 if(ps2esdi_slot) {
445 mca_mark_as_unused(ps2esdi_slot);
446 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
447 }
448 return error;
449 }
451 static void __init ps2esdi_get_device_cfg(void)
452 {
453 u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH];
455 /*BA */ printk("%s: Drive 0\n", DEVICE_NAME);
456 current_int_handler = ps2esdi_geometry_int_handler;
457 cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600;
458 cmd_blk[1] = 0;
459 no_int_yet = TRUE;
460 ps2esdi_out_cmd_blk(cmd_blk);
461 if (no_int_yet)
462 sleep_on(&ps2esdi_int);
464 if (ps2esdi_drives > 1) {
465 printk("%s: Drive 1\n", DEVICE_NAME); /*BA */
466 cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600;
467 cmd_blk[1] = 0;
468 no_int_yet = TRUE;
469 ps2esdi_out_cmd_blk(cmd_blk);
470 if (no_int_yet)
471 sleep_on(&ps2esdi_int);
472 } /* if second physical drive is present */
473 return;
474 }
476 /* strategy routine that handles most of the IO requests */
477 static void do_ps2esdi_request(request_queue_t * q)
478 {
479 struct request *req;
480 /* since, this routine is called with interrupts cleared - they
481 must be before it finishes */
483 req = elv_next_request(q);
484 if (!req)
485 return;
487 #if 0
488 printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n",
489 DEVICE_NAME,
490 req->rq_disk->disk_name,
491 req->cmd, req->sector,
492 req->current_nr_sectors, req->buffer);
493 #endif
495 /* check for above 16Mb dmas */
496 if (isa_virt_to_bus(req->buffer + req->current_nr_sectors * 512) > 16 * MB) {
497 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
498 end_request(req, FAIL);
499 return;
500 }
502 if (req->sector+req->current_nr_sectors > get_capacity(req->rq_disk)) {
503 printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n",
504 ps2esdi_drives, req->sector,
505 (unsigned long long)get_capacity(req->rq_disk));
506 end_request(req, FAIL);
507 return;
508 }
510 switch (rq_data_dir(req)) {
511 case READ:
512 ps2esdi_readwrite(READ, req);
513 break;
514 case WRITE:
515 ps2esdi_readwrite(WRITE, req);
516 break;
517 default:
518 printk("%s: Unknown command\n", req->rq_disk->disk_name);
519 end_request(req, FAIL);
520 break;
521 } /* handle different commands */
522 } /* main strategy routine */
524 /* resets the ESDI adapter */
525 static void reset_ctrl(void)
526 {
528 u_long expire;
529 u_short status;
531 /* enable interrupts on the controller */
532 status = inb(ESDI_INTRPT);
533 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN); /* to be sure we don't have
534 any interrupt pending... */
535 outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL);
537 /* read the ESDI status port - if the controller is not busy,
538 simply do a soft reset (fast) - otherwise we'll have to do a
539 hard (slow) reset. */
540 if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) {
541 /*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
542 outb_p(CTRL_SOFT_RESET, ESDI_ATTN);
543 }
544 /* soft reset */
545 else {
546 /*BA */
547 printk("%s: hard reset...\n", DEVICE_NAME);
548 outb_p(CTRL_HARD_RESET, ESDI_CONTROL);
549 expire = jiffies + 2*HZ;
550 while (time_before(jiffies, expire));
551 outb_p(1, ESDI_CONTROL);
552 } /* hard reset */
555 } /* reset the controller */
557 /* called by the strategy routine to handle read and write requests */
558 static void ps2esdi_readwrite(int cmd, struct request *req)
559 {
560 struct ps2esdi_i_struct *p = req->rq_disk->private_data;
561 unsigned block = req->sector;
562 unsigned count = req->current_nr_sectors;
563 int drive = p - ps2esdi_info;
564 u_short track, head, cylinder, sector;
565 u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
567 /* do some relevant arithmatic */
568 track = block / p->sect;
569 head = track % p->head;
570 cylinder = track / p->head;
571 sector = block % p->sect;
573 #if 0
574 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME, cylinder, head, sector);
575 #endif
576 /* call the routine that actually fills out a command block */
577 ps2esdi_fill_cmd_block
578 (cmd_blk,
579 (cmd == READ) ? CMD_READ : CMD_WRITE,
580 cylinder, head, sector, count, drive);
582 /* send the command block to the controller */
583 current_req = req;
584 spin_unlock_irq(&ps2esdi_lock);
585 if (ps2esdi_out_cmd_blk(cmd_blk)) {
586 spin_lock_irq(&ps2esdi_lock);
587 printk("%s: Controller failed\n", DEVICE_NAME);
588 if ((++req->errors) >= MAX_RETRIES)
589 end_request(req, FAIL);
590 }
591 /* check for failure to put out the command block */
592 else {
593 spin_lock_irq(&ps2esdi_lock);
594 #if 0
595 printk("%s: waiting for xfer\n", DEVICE_NAME);
596 #endif
597 /* turn disk lights on */
598 LITE_ON;
599 }
601 } /* ps2esdi_readwrite */
603 /* fill out the command block */
604 static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
605 u_short cyl, u_short head, u_short sector, u_short length, u_char drive)
606 {
608 cmd_blk[0] = (drive << 5) | cmd;
609 cmd_blk[1] = length;
610 cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
611 cmd_blk[3] = (cyl & 0x3E0) >> 5;
613 } /* fill out the command block */
615 /* write a command block to the controller */
616 static int ps2esdi_out_cmd_blk(u_short * cmd_blk)
617 {
619 int i;
620 unsigned long jif;
621 u_char status;
623 /* enable interrupts */
624 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
626 /* do not write to the controller, if it is busy */
627 for (jif = jiffies + ESDI_STAT_TIMEOUT;
628 time_after(jif, jiffies) &&
629 (inb(ESDI_STATUS) & STATUS_BUSY); )
630 ;
632 #if 0
633 printk("%s: i(1)=%ld\n", DEVICE_NAME, jif);
634 #endif
636 /* if device is still busy - then just time out */
637 if (inb(ESDI_STATUS) & STATUS_BUSY) {
638 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
639 return ERROR;
640 } /* timeout ??? */
641 /* Set up the attention register in the controller */
642 outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
644 #if 0
645 printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
646 #endif
648 /* one by one send each word out */
649 for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) {
650 status = inb(ESDI_STATUS);
651 for (jif = jiffies + ESDI_STAT_TIMEOUT;
652 time_after(jif, jiffies) && (status & STATUS_BUSY) &&
653 (status & STATUS_CMD_INF); status = inb(ESDI_STATUS));
654 if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) {
655 #if 0
656 printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk);
657 #endif
658 outw(*cmd_blk++, ESDI_CMD_INT);
659 } else {
660 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
661 DEVICE_NAME, status);
662 return ERROR;
663 }
664 } /* send all words out */
665 return OK;
666 } /* send out the commands */
669 /* prepare for dma - do all the necessary setup */
670 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
671 {
672 unsigned long flags = claim_dma_lock();
674 mca_disable_dma(dma_arb_level);
676 mca_set_dma_addr(dma_arb_level, isa_virt_to_bus(buffer));
678 mca_set_dma_count(dma_arb_level, length * 512 / 2);
680 mca_set_dma_mode(dma_arb_level, dma_xmode);
682 mca_enable_dma(dma_arb_level);
684 release_dma_lock(flags);
686 } /* prepare for dma */
690 static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id,
691 struct pt_regs *regs)
692 {
693 u_int int_ret_code;
695 if (inb(ESDI_STATUS) & STATUS_INTR) {
696 int_ret_code = inb(ESDI_INTRPT);
697 if (current_int_handler) {
698 /* Disable adapter interrupts till processing is finished */
699 outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
700 current_int_handler(int_ret_code);
701 } else
702 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
703 } else {
704 return IRQ_NONE;
705 }
706 return IRQ_HANDLED;
707 }
709 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
710 {
712 switch (int_ret_code & 0xf) {
713 case INT_RESET:
714 /*BA */
715 printk("%s: initial reset completed.\n", DEVICE_NAME);
716 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
717 wake_up(&ps2esdi_int);
718 break;
719 case INT_ATTN_ERROR:
720 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
721 int_ret_code);
722 printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
723 break;
724 default:
725 printk("%s: initial reset handler received interrupt: %02X\n",
726 DEVICE_NAME, int_ret_code);
727 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
728 break;
729 }
730 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
731 }
734 static void ps2esdi_geometry_int_handler(u_int int_ret_code)
735 {
736 u_int status, drive_num;
737 unsigned long rba;
738 int i;
740 drive_num = int_ret_code >> 5;
741 switch (int_ret_code & 0xf) {
742 case INT_CMD_COMPLETE:
743 for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
744 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
745 printk("%s: timeout reading status word\n", DEVICE_NAME);
746 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
747 break;
748 }
749 status = inw(ESDI_STT_INT);
750 if ((status & 0x1F) == CMD_GET_DEV_CONFIG) {
751 #define REPLY_WORDS 5 /* we already read word 0 */
752 u_short reply[REPLY_WORDS];
754 if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) {
755 /*BA */
756 printk("%s: Device Configuration Status for drive %u\n",
757 DEVICE_NAME, drive_num);
759 printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
761 printk
762 ("Config bits: %s%s%s%s%s\n",
763 (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
764 ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
765 ? "Zero Defect, " : "Defects Present, ",
766 (reply[0] & CONFIG_SF) ? "Skewed Format, " : "",
767 (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ",
768 (reply[0] & CONFIG_RT) ? "No Retries" : "Retries");
770 rba = reply[1] | ((unsigned long) reply[2] << 16);
771 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba);
773 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
774 DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff);
776 if (!ps2esdi_info[drive_num].head) {
777 ps2esdi_info[drive_num].head = 64;
778 ps2esdi_info[drive_num].sect = 32;
779 ps2esdi_info[drive_num].cyl = rba / (64 * 32);
780 ps2esdi_info[drive_num].wpcom = 0;
781 ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl;
782 ps2esdi_info[drive_num].ctl = 8;
783 if (tp720esdi) { /* store the retrieved parameters */
784 ps2esdi_info[0].head = reply[4] & 0Xff;
785 ps2esdi_info[0].sect = reply[4] >> 8;
786 ps2esdi_info[0].cyl = reply[3];
787 ps2esdi_info[0].wpcom = 0;
788 ps2esdi_info[0].lzone = reply[3];
789 } else {
790 if (!intg_esdi)
791 ps2esdi_drives++;
792 }
793 }
794 #ifdef OBSOLETE
795 if (!ps2esdi_info[drive_num].head) {
796 ps2esdi_info[drive_num].head = reply[4] & 0Xff;
797 ps2esdi_info[drive_num].sect = reply[4] >> 8;
798 ps2esdi_info[drive_num].cyl = reply[3];
799 ps2esdi_info[drive_num].wpcom = 0;
800 ps2esdi_info[drive_num].lzone = reply[3];
801 if (tp720esdi) { /* store the retrieved parameters */
802 ps2esdi_info[0].head = reply[4] & 0Xff;
803 ps2esdi_info[0].sect = reply[4] >> 8;
804 ps2esdi_info[0].cyl = reply[3];
805 ps2esdi_info[0].wpcom = 0;
806 ps2esdi_info[0].lzone = reply[3];
807 } else {
808 ps2esdi_drives++;
809 }
810 }
811 #endif
813 } else
814 printk("%s: failed while getting device config\n", DEVICE_NAME);
815 #undef REPLY_WORDS
816 } else
817 printk("%s: command %02X unknown by geometry handler\n",
818 DEVICE_NAME, status & 0x1f);
820 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
821 break;
823 case INT_ATTN_ERROR:
824 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
825 int_ret_code);
826 printk("%s: Device not available\n", DEVICE_NAME);
827 break;
828 case INT_CMD_ECC:
829 case INT_CMD_RETRY:
830 case INT_CMD_ECC_RETRY:
831 case INT_CMD_WARNING:
832 case INT_CMD_ABORT:
833 case INT_CMD_FAILED:
834 case INT_DMA_ERR:
835 case INT_CMD_BLK_ERR:
836 /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
837 dump_cmd_complete_status(int_ret_code);
838 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
839 break;
840 default:
841 printk("%s: Unknown interrupt reason: %02X\n",
842 DEVICE_NAME, int_ret_code & 0xf);
843 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
844 break;
845 }
847 wake_up(&ps2esdi_int);
848 no_int_yet = FALSE;
849 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
851 }
853 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
854 {
855 unsigned long flags;
856 u_int status;
857 u_int ending;
858 int i;
860 switch (int_ret_code & 0x0f) {
861 case INT_TRANSFER_REQ:
862 ps2esdi_prep_dma(current_req->buffer,
863 current_req->current_nr_sectors,
864 (rq_data_dir(current_req) == READ)
865 ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
866 : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
867 outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
868 ending = -1;
869 break;
871 case INT_ATTN_ERROR:
872 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
873 int_ret_code);
874 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
875 ending = FAIL;
876 break;
878 case INT_CMD_COMPLETE:
879 for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
880 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
881 printk("%s: timeout reading status word\n", DEVICE_NAME);
882 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
883 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
884 if ((++current_req->errors) >= MAX_RETRIES)
885 ending = FAIL;
886 else
887 ending = -1;
888 break;
889 }
890 status = inw(ESDI_STT_INT);
891 switch (status & 0x1F) {
892 case (CMD_READ & 0xff):
893 case (CMD_WRITE & 0xff):
894 LITE_OFF;
895 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
896 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
897 ending = SUCCES;
898 break;
899 default:
900 printk("%s: interrupt for unknown command %02X\n",
901 DEVICE_NAME, status & 0x1f);
902 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
903 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
904 ending = -1;
905 break;
906 }
907 break;
908 case INT_CMD_ECC:
909 case INT_CMD_RETRY:
910 case INT_CMD_ECC_RETRY:
911 LITE_OFF;
912 dump_cmd_complete_status(int_ret_code);
913 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
914 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
915 ending = SUCCES;
916 break;
917 case INT_CMD_WARNING:
918 case INT_CMD_ABORT:
919 case INT_CMD_FAILED:
920 case INT_DMA_ERR:
921 LITE_OFF;
922 dump_cmd_complete_status(int_ret_code);
923 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
924 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
925 if ((++current_req->errors) >= MAX_RETRIES)
926 ending = FAIL;
927 else
928 ending = -1;
929 break;
931 case INT_CMD_BLK_ERR:
932 dump_cmd_complete_status(int_ret_code);
933 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
934 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
935 ending = FAIL;
936 break;
938 case INT_CMD_FORMAT:
939 printk("%s: huh ? Who issued this format command ?\n"
940 ,DEVICE_NAME);
941 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
942 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
943 ending = -1;
944 break;
946 case INT_RESET:
947 /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
948 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
949 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
950 ending = -1;
951 break;
953 default:
954 printk("%s: Unknown interrupt reason: %02X\n",
955 DEVICE_NAME, int_ret_code & 0xf);
956 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
957 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
958 ending = -1;
959 break;
960 }
961 if(ending != -1) {
962 spin_lock_irqsave(&ps2esdi_lock, flags);
963 end_request(current_req, ending);
964 current_req = NULL;
965 do_ps2esdi_request(ps2esdi_queue);
966 spin_unlock_irqrestore(&ps2esdi_lock, flags);
967 }
968 } /* handle interrupts */
972 static int ps2esdi_read_status_words(int num_words,
973 int max_words,
974 u_short * buffer)
975 {
976 int i;
978 for (; max_words && num_words; max_words--, num_words--, buffer++) {
979 for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
980 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
981 printk("%s: timeout reading status word\n", DEVICE_NAME);
982 return FAIL;
983 }
984 *buffer = inw(ESDI_STT_INT);
985 }
986 return SUCCES;
987 }
992 static void dump_cmd_complete_status(u_int int_ret_code)
993 {
994 #define WAIT_FOR_STATUS \
995 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
996 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
997 printk("%s: timeout reading status word\n",DEVICE_NAME); \
998 return; \
999 }
1001 int i, word_count;
1002 u_short stat_word;
1003 u_long rba;
1005 printk("%s: Device: %u, interrupt ID: %02X\n",
1006 DEVICE_NAME, int_ret_code >> 5,
1007 int_ret_code & 0xf);
1009 WAIT_FOR_STATUS;
1010 stat_word = inw(ESDI_STT_INT);
1011 word_count = (stat_word >> 8) - 1;
1012 printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,
1013 stat_word & 0xff);
1015 if (word_count--) {
1016 WAIT_FOR_STATUS;
1017 stat_word = inw(ESDI_STT_INT);
1018 printk("%s: command status code: %02X, command error code: %02X\n",
1019 DEVICE_NAME, stat_word >> 8, stat_word & 0xff);
1021 if (word_count--) {
1022 WAIT_FOR_STATUS;
1023 stat_word = inw(ESDI_STT_INT);
1024 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,
1025 (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",
1026 (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",
1027 (stat_word & 0x0400) ? "Write Fault, " : "",
1028 (stat_word & 0x0200) ? "Track 0, " : "",
1029 (stat_word & 0x0100) ? "Seek or command complete, " : "",
1030 stat_word >> 8);
1032 if (word_count--) {
1033 WAIT_FOR_STATUS;
1034 stat_word = inw(ESDI_STT_INT);
1035 printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
1037 if (word_count -= 2) {
1038 WAIT_FOR_STATUS;
1039 rba = inw(ESDI_STT_INT);
1040 WAIT_FOR_STATUS;
1041 rba |= inw(ESDI_STT_INT) << 16;
1042 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1043 (u_short) ((rba & 0x1ff80000) >> 11),
1044 (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));
1045 } else
1046 printk("\n");
1048 if (word_count--) {
1049 WAIT_FOR_STATUS;
1050 stat_word = inw(ESDI_STT_INT);
1051 printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
1053 printk("\n");
1055 #undef WAIT_FOR_STATUS
1059 static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1061 struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
1063 geo->heads = p->head;
1064 geo->sectors = p->sect;
1065 geo->cylinders = p->cyl;
1066 return 0;
1069 static void ps2esdi_reset_timer(unsigned long unused)
1072 int status;
1074 status = inb(ESDI_INTRPT);
1075 if ((status & 0xf) == INT_RESET) {
1076 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
1077 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
1078 reset_status = 1;
1080 wake_up(&ps2esdi_int);