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
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 */
27 + reset after read/write error
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>
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>
50 #include <asm/mca_dma.h>
51 #include <asm/uaccess.h>
53 #define PS2ESDI_IRQ 14
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;
109 static DEFINE_SPINLOCK(ps2esdi_lock);
110 static struct request_queue *ps2esdi_queue;
111 static struct request *current_req;
114 #if 0 /* try both - I don't know which one is better... UB */
115 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
117 {4, 48, 1553, 0, 0, 0},
120 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
122 {64, 32, 161, 0, 0, 0},
126 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
131 static struct block_device_operations ps2esdi_fops =
133 .owner = THIS_MODULE,
134 .getgeo = ps2esdi_getgeo,
137 static struct gendisk *ps2esdi_gendisk[2];
139 /* initialization routine called by ll_rw_blk.c */
140 static int __init ps2esdi_init(void)
145 /* register the device - pass the name and major number */
146 if (register_blkdev(PS2ESDI_MAJOR, "ed"))
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");
156 /* some minor housekeeping - setup the global gendisk structure */
157 error = ps2esdi_geninit();
159 printk(KERN_WARNING "PS2ESDI: error initialising"
160 " device, releasing resources\n");
161 unregister_blkdev(PS2ESDI_MAJOR, "ed");
162 blk_cleanup_queue(ps2esdi_queue);
170 module_init(ps2esdi_init);
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) {
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];
194 if (head[drive] != -1) {
195 info->head = head[drive];
196 info->ctl = (head[drive] > 8 ? 8 : 0);
198 if (sect[drive] != -1) info->sect = sect[drive];
200 return ps2esdi_init();
204 cleanup_module(void) {
207 mca_mark_as_unused(ps2esdi_slot);
208 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
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]);
222 /* handles boot time command line parameters */
223 void __init tp720_setup(char *str, int *ints)
225 /* no params, just sets the tp720esdi flag if it exists */
227 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
231 void __init ed_setup(char *str, int *ints)
235 /* handles 3 parameters only - corresponding to
236 1. Number of cylinders
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)
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 */
264 static int ps2esdi_getinfo(char *buf, int slot, void *d)
268 len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
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);
277 /* ps2 esdi specific initialization - called thru the gendisk chain */
278 static int __init ps2esdi_geninit(void)
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.
293 int slot = 0, i, reset_start, reset_end;
295 unsigned short adapterID;
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);
303 mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
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");
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 :
325 1 - fairness disabled, linear priority assignment
326 5-2 arbitration level
329 0 - use addresses 0x3510 - 0x3517
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);
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)
347 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
351 if (status & STATUS_ALTERNATE)
352 io_base = ALT_IO_BASE;
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);
361 /* get the dma arbitration level */
362 dma_arb_level = (status >> 2) & 0xf;
365 printk("%s: DMA arbitration level : %d\n",
366 DEVICE_NAME, dma_arb_level);
369 current_int_handler = ps2esdi_initial_reset_int_handler;
372 reset_start = jiffies;
373 while (!reset_status) {
374 init_timer(&esdi_timer);
375 esdi_timer.expires = jiffies + HZ;
377 add_timer(&esdi_timer);
378 sleep_on(&ps2esdi_int);
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;
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);
413 blk_queue_max_sectors(ps2esdi_queue, 128);
416 for (i = 0; i < ps2esdi_drives; i++) {
417 struct gendisk *disk = alloc_disk(64);
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;
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];
438 put_disk(ps2esdi_gendisk[i]);
440 release_region(io_base, 4);
442 free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
445 mca_mark_as_unused(ps2esdi_slot);
446 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
451 static void __init ps2esdi_get_device_cfg(void)
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;
460 ps2esdi_out_cmd_blk(cmd_blk);
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;
469 ps2esdi_out_cmd_blk(cmd_blk);
471 sleep_on(&ps2esdi_int);
472 } /* if second physical drive is present */
476 /* strategy routine that handles most of the IO requests */
477 static void do_ps2esdi_request(request_queue_t * q)
480 /* since, this routine is called with interrupts cleared - they
481 must be before it finishes */
483 req = elv_next_request(q);
488 printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n",
490 req->rq_disk->disk_name,
491 req->cmd, req->sector,
492 req->current_nr_sectors, req->buffer);
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);
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);
510 switch (rq_data_dir(req)) {
512 ps2esdi_readwrite(READ, req);
515 ps2esdi_readwrite(WRITE, req);
518 printk("%s: Unknown command\n", req->rq_disk->disk_name);
519 end_request(req, FAIL);
521 } /* handle different commands */
522 } /* main strategy routine */
524 /* resets the ESDI adapter */
525 static void reset_ctrl(void)
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);
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);
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)
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;
574 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME, cylinder, head, sector);
576 /* call the routine that actually fills out a command block */
577 ps2esdi_fill_cmd_block
579 (cmd == READ) ? CMD_READ : CMD_WRITE,
580 cylinder, head, sector, count, drive);
582 /* send the command block to the controller */
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);
591 /* check for failure to put out the command block */
593 spin_lock_irq(&ps2esdi_lock);
595 printk("%s: waiting for xfer\n", DEVICE_NAME);
597 /* turn disk lights on */
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)
608 cmd_blk[0] = (drive << 5) | cmd;
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)
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); )
633 printk("%s: i(1)=%ld\n", DEVICE_NAME, jif);
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);
641 /* Set up the attention register in the controller */
642 outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
645 printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
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) {
656 printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk);
658 outw(*cmd_blk++, ESDI_CMD_INT);
660 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
661 DEVICE_NAME, status);
664 } /* send all words out */
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)
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)
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);
702 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
709 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
712 switch (int_ret_code & 0xf) {
715 printk("%s: initial reset completed.\n", DEVICE_NAME);
716 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
717 wake_up(&ps2esdi_int);
720 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
722 printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
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);
730 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
734 static void ps2esdi_geometry_int_handler(u_int int_ret_code)
736 u_int status, drive_num;
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);
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)) {
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);
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];
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];
814 printk("%s: failed while getting device config\n", DEVICE_NAME);
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);
824 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
826 printk("%s: Device not available\n", DEVICE_NAME);
830 case INT_CMD_ECC_RETRY:
831 case INT_CMD_WARNING:
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);
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);
847 wake_up(&ps2esdi_int);
849 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
853 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
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);
872 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
874 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
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)
890 status = inw(ESDI_STT_INT);
891 switch (status & 0x1F) {
892 case (CMD_READ & 0xff):
893 case (CMD_WRITE & 0xff):
895 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
896 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
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);
910 case INT_CMD_ECC_RETRY:
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);
917 case INT_CMD_WARNING:
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)
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);
939 printk("%s: huh ? Who issued this format command ?\n"
941 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
942 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
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);
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);
962 spin_lock_irqsave(&ps2esdi_lock, flags);
963 end_request(current_req, ending);
965 do_ps2esdi_request(ps2esdi_queue);
966 spin_unlock_irqrestore(&ps2esdi_lock, flags);
968 } /* handle interrupts */
972 static int ps2esdi_read_status_words(int num_words,
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);
984 *buffer = inw(ESDI_STT_INT);
992 static void dump_cmd_complete_status(u_int int_ret_code)
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); \
1005 printk("%s: Device: %u, interrupt ID: %02X\n",
1006 DEVICE_NAME, int_ret_code >> 5,
1007 int_ret_code & 0xf);
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,
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);
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, " : "",
1034 stat_word = inw(ESDI_STT_INT);
1035 printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
1037 if (word_count -= 2) {
1039 rba = inw(ESDI_STT_INT);
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));
1050 stat_word = inw(ESDI_STT_INT);
1051 printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
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;
1069 static void ps2esdi_reset_timer(unsigned long unused)
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);
1080 wake_up(&ps2esdi_int);