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 #include <linux/config.h>
31 #include <linux/major.h>
33 #ifdef CONFIG_BLK_DEV_PS2
35 #define MAJOR_NR PS2ESDI_MAJOR
37 #include <linux/errno.h>
38 #include <linux/sched.h>
41 #include <linux/kernel.h>
42 #include <linux/genhd.h>
43 #include <linux/ps2esdi.h>
44 #include <linux/devfs_fs_kernel.h>
45 #include <linux/blk.h>
46 #include <linux/blkpg.h>
47 #include <linux/mca.h>
48 #include <linux/init.h>
49 #include <linux/ioport.h>
50 #include <linux/module.h>
52 #include <asm/system.h>
54 #include <asm/segment.h>
56 #include <asm/mca_dma.h>
57 #include <asm/uaccess.h>
59 #define PS2ESDI_IRQ 14
62 #define MAX_16BIT 65536
63 #define ESDI_TIMEOUT 0xf000
64 #define ESDI_STAT_TIMEOUT 4
66 #define TYPE_0_CMD_BLK_LENGTH 2
67 #define TYPE_1_CMD_BLK_LENGTH 4
70 static void reset_ctrl(void);
72 int ps2esdi_init(void);
74 static void ps2esdi_geninit(void);
76 static void do_ps2esdi_request(request_queue_t * q);
78 static void ps2esdi_readwrite(int cmd, u_char drive, u_int block, u_int count);
80 static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
81 u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
83 static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
85 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
87 static void ps2esdi_interrupt_handler(int irq, void *dev_id,
88 struct pt_regs *regs);
89 static void (*current_int_handler) (u_int) = NULL;
90 static void ps2esdi_normal_interrupt_handler(u_int);
91 static void ps2esdi_initial_reset_int_handler(u_int);
92 static void ps2esdi_geometry_int_handler(u_int);
94 static int ps2esdi_open(struct inode *inode, struct file *file);
96 static int ps2esdi_release(struct inode *inode, struct file *file);
98 static int ps2esdi_ioctl(struct inode *inode, struct file *file,
99 u_int cmd, u_long arg);
101 static int ps2esdi_reread_partitions(kdev_t dev);
103 static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
105 static void dump_cmd_complete_status(u_int int_ret_code);
107 static void ps2esdi_get_device_cfg(void);
109 static void ps2esdi_reset_timer(unsigned long unused);
111 static u_int dma_arb_level; /* DMA arbitration level */
113 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
114 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open);
116 static int no_int_yet;
117 static int access_count[MAX_HD];
118 static char ps2esdi_valid[MAX_HD];
119 static int ps2esdi_sizes[MAX_HD << 6];
120 static int ps2esdi_blocksizes[MAX_HD << 6];
121 static int ps2esdi_maxsect[MAX_HD << 6];
122 static int ps2esdi_drives;
123 static struct hd_struct ps2esdi[MAX_HD << 6];
124 static u_short io_base;
125 static struct timer_list esdi_timer = { function: ps2esdi_reset_timer };
126 static int reset_status;
127 static int ps2esdi_slot = -1;
128 static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
129 static int intg_esdi = 0; /* If integrated adapter */
130 struct ps2esdi_i_struct {
131 unsigned int head, sect, cyl, wpcom, lzone, ctl;
135 #if 0 /* try both - I don't know which one is better... UB */
136 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
138 {4, 48, 1553, 0, 0, 0},
141 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
143 {64, 32, 161, 0, 0, 0},
147 static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
152 static struct block_device_operations ps2esdi_fops =
156 release: ps2esdi_release,
157 ioctl: ps2esdi_ioctl,
160 static struct gendisk ps2esdi_gendisk =
167 sizes: ps2esdi_sizes,
168 real_devices: (void *)ps2esdi_info,
172 /* initialization routine called by ll_rw_blk.c */
173 int __init ps2esdi_init(void)
176 /* register the device - pass the name, major number and operations
178 if (devfs_register_blkdev(MAJOR_NR, "ed", &ps2esdi_fops)) {
179 printk("%s: Unable to get major number %d\n", DEVICE_NAME, MAJOR_NR);
182 /* set up some global information - indicating device specific info */
183 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
184 read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read ahead */
186 /* some minor housekeeping - setup the global gendisk structure */
187 add_gendisk(&ps2esdi_gendisk);
194 static int cyl[MAX_HD] = {-1,-1};
195 static int head[MAX_HD] = {-1, -1};
196 static int sect[MAX_HD] = {-1, -1};
198 MODULE_PARM(tp720esdi, "i");
199 MODULE_PARM(cyl, "i");
200 MODULE_PARM(head, "i");
201 MODULE_PARM(track, "i");
202 MODULE_LICENSE("GPL");
204 int init_module(void) {
207 for(drive = 0; drive < MAX_HD; drive++) {
208 struct ps2_esdi_i_struct *info = &ps2esdi_info[drive];
210 if (cyl[drive] != -1) {
211 info->cyl = info->lzone = cyl[drive];
214 if (head[drive] != -1) {
215 info->head = head[drive];
216 info->ctl = (head[drive] > 8 ? 8 : 0);
218 if (sect[drive] != -1) info->sect = sect[drive];
220 return ps2esdi_init();
227 mca_mark_as_unused(ps2esdi_slot);
228 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
230 release_region(io_base, 4);
231 free_dma(dma_arb_level);
232 free_irq(PS2ESDI_IRQ, NULL);
233 devfs_unregister_blkdev(MAJOR_NR, "ed");
234 del_gendisk(&ps2esdi_gendisk);
235 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
239 /* handles boot time command line parameters */
240 void __init tp720_setup(char *str, int *ints)
242 /* no params, just sets the tp720esdi flag if it exists */
244 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
248 void __init ed_setup(char *str, int *ints)
252 /* handles 3 parameters only - corresponding to
253 1. Number of cylinders
261 /* print out the information - seen at boot time */
262 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
263 DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]);
265 /* set the index into device specific information table */
266 if (ps2esdi_info[0].head != 0)
269 /* set up all the device information */
270 ps2esdi_info[hdind].head = ints[2];
271 ps2esdi_info[hdind].sect = ints[3];
272 ps2esdi_info[hdind].cyl = ints[1];
273 ps2esdi_info[hdind].wpcom = 0;
274 ps2esdi_info[hdind].lzone = ints[1];
275 ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
276 #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
277 ps2esdi_drives = hdind + 1; /* increment index for the next time */
281 static int ps2esdi_getinfo(char *buf, int slot, void *d)
285 len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
287 len += sprintf(buf + len, "IO Port: %x\n", io_base);
288 len += sprintf(buf + len, "IRQ: 14\n");
289 len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives);
294 /* ps2 esdi specific initialization - called thru the gendisk chain */
295 static void __init ps2esdi_geninit(void)
298 The first part contains the initialization code
299 for the ESDI disk subsystem. All we really do
300 is search for the POS registers of the controller
301 to do some simple setup operations. First, we
302 must ensure that the controller is installed,
303 enabled, and configured as PRIMARY. Then we must
304 determine the DMA arbitration level being used by
305 the controller so we can handle data transfer
306 operations properly. If all of this works, then
307 we will set the INIT_FLAG to a non-zero value.
310 int slot = 0, i, reset_start, reset_end;
312 unsigned short adapterID;
314 if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
315 adapterID = INTG_ESDI_ID;
316 printk("%s: integrated ESDI adapter found in slot %d\n",
317 DEVICE_NAME, slot+1);
319 mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
321 } else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) {
322 adapterID = NRML_ESDI_ID;
323 printk("%s: normal ESDI adapter found in slot %d\n",
324 DEVICE_NAME, slot+1);
325 mca_set_adapter_name(slot, "PS/2 ESDI");
331 mca_mark_as_used(slot);
332 mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL);
334 /* Found the slot - read the POS register 2 to get the necessary
335 configuration and status information. POS register 2 has the
336 following information :
341 1 - fairness disabled, linear priority assignment
342 5-2 arbitration level
345 0 - use addresses 0x3510 - 0x3517
349 status = mca_read_stored_pos(slot, 2);
350 /* is it enabled ? */
351 if (!(status & STATUS_ENABLED)) {
352 printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
355 /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
356 share with the SCSI driver */
357 if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
358 SA_INTERRUPT | SA_SHIRQ, "PS/2 ESDI", &ps2esdi_gendisk)
359 && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
360 SA_SHIRQ, "PS/2 ESDI", &ps2esdi_gendisk)
362 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
365 if (status & STATUS_ALTERNATE)
366 io_base = ALT_IO_BASE;
368 io_base = PRIMARY_IO_BASE;
370 /* get the dma arbitration level */
371 dma_arb_level = (status >> 2) & 0xf;
374 printk("%s: DMA arbitration level : %d\n",
375 DEVICE_NAME, dma_arb_level);
378 current_int_handler = ps2esdi_initial_reset_int_handler;
381 reset_start = jiffies;
382 while (!reset_status) {
383 init_timer(&esdi_timer);
384 esdi_timer.expires = jiffies + HZ;
386 add_timer(&esdi_timer);
387 sleep_on(&ps2esdi_int);
391 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
392 DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
393 (reset_end - reset_start) % HZ);
396 /* Integrated ESDI Disk and Controller has only one drive! */
397 if (adapterID == INTG_ESDI_ID) {/* if not "normal" PS2 ESDI adapter */
398 ps2esdi_drives = 1; /* then we have only one physical disk! */ intg_esdi = 1;
403 /* finally this part sets up some global data structures etc. */
405 ps2esdi_get_device_cfg();
407 /* some annoyance in the above routine returns TWO drives?
408 Is something else happining in the background?
409 Regaurdless we fix the # of drives again. AJK */
410 /* Integrated ESDI Disk and Controller has only one drive! */
411 if (adapterID == INTG_ESDI_ID) /* if not "normal" PS2 ESDI adapter */
412 ps2esdi_drives = 1; /* Not three or two, ONE DAMNIT! */
414 current_int_handler = ps2esdi_normal_interrupt_handler;
416 ps2esdi_gendisk.nr_real = ps2esdi_drives;
418 /* 128 was old default, maybe maxsect=255 is ok too? - Paul G. */
419 for (i = 0; i < (MAX_HD << 6); i++) {
420 ps2esdi_maxsect[i] = 128;
421 ps2esdi_blocksizes[i] = 1024;
424 request_dma(dma_arb_level, "ed");
425 request_region(io_base, 4, "ed");
426 blksize_size[MAJOR_NR] = ps2esdi_blocksizes;
427 max_sectors[MAJOR_NR] = ps2esdi_maxsect;
429 for (i = 0; i < ps2esdi_drives; i++) {
430 register_disk(&ps2esdi_gendisk,MKDEV(MAJOR_NR,i<<6),1<<6,
432 ps2esdi_info[i].head * ps2esdi_info[i].sect *
433 ps2esdi_info[i].cyl);
434 ps2esdi_valid[i] = 1;
438 static void __init ps2esdi_get_device_cfg(void)
440 u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH];
442 /*BA */ printk("%s: Drive 0\n", DEVICE_NAME);
443 current_int_handler = ps2esdi_geometry_int_handler;
444 cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600;
447 ps2esdi_out_cmd_blk(cmd_blk);
449 sleep_on(&ps2esdi_int);
451 if (ps2esdi_drives > 1) {
452 printk("%s: Drive 1\n", DEVICE_NAME); /*BA */
453 cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600;
456 ps2esdi_out_cmd_blk(cmd_blk);
458 sleep_on(&ps2esdi_int);
459 } /* if second physical drive is present */
463 /* strategy routine that handles most of the IO requests */
464 static void do_ps2esdi_request(request_queue_t * q)
467 /* since, this routine is called with interrupts cleared - they
468 must be before it finishes */
471 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld, buffer: %p\n",
473 CURRENT_DEV, MINOR(CURRENT->rq_dev),
474 CURRENT->cmd, CURRENT->sector,
475 CURRENT->current_nr_sectors, CURRENT->buffer);
478 /* standard macro that ensures that requests are really on the
479 list + sanity checks. */
482 if (virt_to_bus(CURRENT->buffer + CURRENT->current_nr_sectors * 512) > 16 * MB) {
483 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
485 } /* check for above 16Mb dmas */
486 else if ((CURRENT_DEV < ps2esdi_drives) &&
487 (CURRENT->sector + CURRENT->current_nr_sectors <=
488 ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects)) {
490 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld\n",
492 CURRENT_DEV, MINOR(CURRENT->rq_dev),
493 CURRENT->cmd, CURRENT->sector,
494 CURRENT->current_nr_sectors);
498 block = CURRENT->sector + ps2esdi[MINOR(CURRENT->rq_dev)].start_sect;
501 printk("%s: blocknumber : %d\n", DEVICE_NAME, block);
503 count = CURRENT->current_nr_sectors;
504 switch (CURRENT->cmd) {
506 ps2esdi_readwrite(READ, CURRENT_DEV, block, count);
509 ps2esdi_readwrite(WRITE, CURRENT_DEV, block, count);
512 printk("%s: Unknown command\n", DEVICE_NAME);
515 } /* handle different commands */
517 /* is request is valid */
519 printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives,
520 CURRENT->sector, ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects);
524 } /* main strategy routine */
526 /* resets the ESDI adapter */
527 static void reset_ctrl(void)
533 /* enable interrupts on the controller */
534 status = inb(ESDI_INTRPT);
535 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN); /* to be sure we don't have
536 any interrupt pending... */
537 outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL);
539 /* read the ESDI status port - if the controller is not busy,
540 simply do a soft reset (fast) - otherwise we'll have to do a
541 hard (slow) reset. */
542 if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) {
543 /*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
544 outb_p(CTRL_SOFT_RESET, ESDI_ATTN);
549 printk("%s: hard reset...\n", DEVICE_NAME);
550 outb_p(CTRL_HARD_RESET, ESDI_CONTROL);
551 expire = jiffies + 2*HZ;
552 while (time_before(jiffies, expire));
553 outb_p(1, ESDI_CONTROL);
557 } /* reset the controller */
559 /* called by the strategy routine to handle read and write requests */
560 static void ps2esdi_readwrite(int cmd, u_char drive, u_int block, u_int count)
563 u_short track, head, cylinder, sector;
564 u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
567 /* do some relevant arithmatic */
568 track = block / ps2esdi_info[drive].sect;
569 head = track % ps2esdi_info[drive].head;
570 cylinder = track / ps2esdi_info[drive].head;
571 sector = block % ps2esdi_info[drive].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,
581 CURRENT->current_nr_sectors, drive);
583 spin_unlock_irq(&io_request_lock);
584 /* send the command block to the controller */
585 err = ps2esdi_out_cmd_blk(cmd_blk);
586 spin_lock_irq(&io_request_lock);
589 printk(KERN_ERR "%s: Controller failed\n", DEVICE_NAME);
590 if ((++CURRENT->errors) >= MAX_RETRIES)
593 /* check for failure to put out the command block */
596 printk("%s: waiting for xfer\n", DEVICE_NAME);
598 /* turn disk lights on */
602 } /* ps2esdi_readwrite */
604 /* fill out the command block */
605 static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
606 u_short cyl, u_short head, u_short sector, u_short length, u_char drive)
609 cmd_blk[0] = (drive << 5) | cmd;
611 cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
612 cmd_blk[3] = (cyl & 0x3E0) >> 5;
614 } /* fill out the command block */
616 /* write a command block to the controller */
617 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 (i = jiffies + ESDI_STAT_TIMEOUT; time_after(i, jiffies) && (inb(ESDI_STATUS) &
631 printk("%s: i(1)=%d\n", DEVICE_NAME, i);
634 /* if device is still busy - then just time out */
635 if (inb(ESDI_STATUS) & STATUS_BUSY) {
636 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
639 /* Set up the attention register in the controller */
640 outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
643 printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
646 /* one by one send each word out */
647 for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) {
648 status = inb(ESDI_STATUS);
649 for (j = jiffies + ESDI_STAT_TIMEOUT;
650 time_after(j, jiffies) && (status & STATUS_BUSY) &&
651 (status & STATUS_CMD_INF); status = inb(ESDI_STATUS));
652 if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) {
654 printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk);
656 outw(*cmd_blk++, ESDI_CMD_INT);
658 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
659 DEVICE_NAME, status);
662 } /* send all words out */
664 } /* send out the commands */
667 /* prepare for dma - do all the necessary setup */
668 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
672 printk("ps2esdi: b_wait: %p\n", &CURRENT->bh->b_wait);
674 flags = claim_dma_lock();
676 mca_disable_dma(dma_arb_level);
678 mca_set_dma_addr(dma_arb_level, virt_to_bus(buffer));
680 mca_set_dma_count(dma_arb_level, length * 512 / 2);
682 mca_set_dma_mode(dma_arb_level, dma_xmode);
684 mca_enable_dma(dma_arb_level);
686 release_dma_lock(flags);
688 } /* prepare for dma */
692 static void ps2esdi_interrupt_handler(int irq, void *dev_id,
693 struct pt_regs *regs)
697 if (inb(ESDI_STATUS) & STATUS_INTR) {
698 int_ret_code = inb(ESDI_INTRPT);
699 if (current_int_handler) {
700 /* Disable adapter interrupts till processing is finished */
701 outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
702 current_int_handler(int_ret_code);
704 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
710 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
713 switch (int_ret_code & 0xf) {
716 printk("%s: initial reset completed.\n", DEVICE_NAME);
717 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
718 wake_up(&ps2esdi_int);
721 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
723 printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
726 printk("%s: initial reset handler received interrupt: %02X\n",
727 DEVICE_NAME, int_ret_code);
728 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
731 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
735 static void ps2esdi_geometry_int_handler(u_int int_ret_code)
737 u_int status, drive_num;
741 drive_num = int_ret_code >> 5;
742 switch (int_ret_code & 0xf) {
743 case INT_CMD_COMPLETE:
744 for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
745 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
746 printk("%s: timeout reading status word\n", DEVICE_NAME);
747 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
750 status = inw(ESDI_STT_INT);
751 if ((status & 0x1F) == CMD_GET_DEV_CONFIG) {
752 #define REPLY_WORDS 5 /* we already read word 0 */
753 u_short reply[REPLY_WORDS];
755 if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) {
757 printk("%s: Device Configuration Status for drive %u\n",
758 DEVICE_NAME, drive_num);
760 printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
763 ("Config bits: %s%s%s%s%s\n",
764 (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
765 ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
766 ? "Zero Defect, " : "Defects Present, ",
767 (reply[0] & CONFIG_SF) ? "Skewed Format, " : "",
768 (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ",
769 (reply[0] & CONFIG_RT) ? "No Retries" : "Retries");
771 rba = reply[1] | ((unsigned long) reply[2] << 16);
772 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba);
774 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
775 DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff);
777 if (!ps2esdi_info[drive_num].head) {
778 ps2esdi_info[drive_num].head = 64;
779 ps2esdi_info[drive_num].sect = 32;
780 ps2esdi_info[drive_num].cyl = rba / (64 * 32);
781 ps2esdi_info[drive_num].wpcom = 0;
782 ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl;
783 ps2esdi_info[drive_num].ctl = 8;
784 if (tp720esdi) { /* store the retrieved parameters */
785 ps2esdi_info[0].head = reply[4] & 0Xff;
786 ps2esdi_info[0].sect = reply[4] >> 8;
787 ps2esdi_info[0].cyl = reply[3];
788 ps2esdi_info[0].wpcom = 0;
789 ps2esdi_info[0].lzone = reply[3];
796 if (!ps2esdi_info[drive_num].head) {
797 ps2esdi_info[drive_num].head = reply[4] & 0Xff;
798 ps2esdi_info[drive_num].sect = reply[4] >> 8;
799 ps2esdi_info[drive_num].cyl = reply[3];
800 ps2esdi_info[drive_num].wpcom = 0;
801 ps2esdi_info[drive_num].lzone = reply[3];
802 if (tp720esdi) { /* store the retrieved parameters */
803 ps2esdi_info[0].head = reply[4] & 0Xff;
804 ps2esdi_info[0].sect = reply[4] >> 8;
805 ps2esdi_info[0].cyl = reply[3];
806 ps2esdi_info[0].wpcom = 0;
807 ps2esdi_info[0].lzone = reply[3];
815 printk("%s: failed while getting device config\n", DEVICE_NAME);
818 printk("%s: command %02X unknown by geometry handler\n",
819 DEVICE_NAME, status & 0x1f);
821 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
825 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
827 printk("%s: Device not available\n", DEVICE_NAME);
831 case INT_CMD_ECC_RETRY:
832 case INT_CMD_WARNING:
836 case INT_CMD_BLK_ERR:
837 /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
838 dump_cmd_complete_status(int_ret_code);
839 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
842 printk("%s: Unknown interrupt reason: %02X\n",
843 DEVICE_NAME, int_ret_code & 0xf);
844 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
848 wake_up(&ps2esdi_int);
850 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
854 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
861 switch (int_ret_code & 0x0f) {
862 case INT_TRANSFER_REQ:
863 ps2esdi_prep_dma(CURRENT->buffer, CURRENT->current_nr_sectors,
864 (CURRENT->cmd == 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->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);
898 printk("ps2esdi: cmd_complete b_wait: %p\n", &CURRENT->bh->b_wait);
903 printk("%s: interrupt for unknown command %02X\n",
904 DEVICE_NAME, status & 0x1f);
905 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
906 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
913 case INT_CMD_ECC_RETRY:
915 dump_cmd_complete_status(int_ret_code);
916 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
917 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
920 case INT_CMD_WARNING:
925 dump_cmd_complete_status(int_ret_code);
926 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
927 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
928 if ((++CURRENT->errors) >= MAX_RETRIES)
934 case INT_CMD_BLK_ERR:
935 dump_cmd_complete_status(int_ret_code);
936 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
937 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
942 printk("%s: huh ? Who issued this format command ?\n"
944 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
945 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
950 /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
951 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
952 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
957 printk("%s: Unknown interrupt reason: %02X\n",
958 DEVICE_NAME, int_ret_code & 0xf);
959 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
960 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
965 spin_lock_irqsave(&io_request_lock, flags);
967 do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
968 spin_unlock_irqrestore(&io_request_lock, flags);
970 } /* handle interrupts */
974 static int ps2esdi_read_status_words(int num_words,
980 for (; max_words && num_words; max_words--, num_words--, buffer++) {
981 for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
982 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
983 printk("%s: timeout reading status word\n", DEVICE_NAME);
986 *buffer = inw(ESDI_STT_INT);
994 static void dump_cmd_complete_status(u_int int_ret_code)
996 #define WAIT_FOR_STATUS \
997 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
998 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
999 printk("%s: timeout reading status word\n",DEVICE_NAME); \
1007 printk("%s: Device: %u, interrupt ID: %02X\n",
1008 DEVICE_NAME, int_ret_code >> 5,
1009 int_ret_code & 0xf);
1012 stat_word = inw(ESDI_STT_INT);
1013 word_count = (stat_word >> 8) - 1;
1014 printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,
1019 stat_word = inw(ESDI_STT_INT);
1020 printk("%s: command status code: %02X, command error code: %02X\n",
1021 DEVICE_NAME, stat_word >> 8, stat_word & 0xff);
1025 stat_word = inw(ESDI_STT_INT);
1026 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,
1027 (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",
1028 (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",
1029 (stat_word & 0x0400) ? "Write Fault, " : "",
1030 (stat_word & 0x0200) ? "Track 0, " : "",
1031 (stat_word & 0x0100) ? "Seek or command complete, " : "",
1036 stat_word = inw(ESDI_STT_INT);
1037 printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
1039 if (word_count -= 2) {
1041 rba = inw(ESDI_STT_INT);
1043 rba |= inw(ESDI_STT_INT) << 16;
1044 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1045 (u_short) ((rba & 0x1ff80000) >> 11),
1046 (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));
1052 stat_word = inw(ESDI_STT_INT);
1053 printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
1057 #undef WAIT_FOR_STATUS
1062 static int ps2esdi_open(struct inode *inode, struct file *file)
1064 int dev = DEVICE_NR(inode->i_rdev);
1066 if (dev < ps2esdi_drives) {
1067 while (!ps2esdi_valid[dev])
1068 sleep_on(&ps2esdi_wait_open);
1070 access_count[dev]++;
1079 static int ps2esdi_release(struct inode *inode, struct file *file)
1081 int dev = DEVICE_NR(inode->i_rdev);
1083 if (dev < ps2esdi_drives) {
1084 access_count[dev]--;
1091 static int ps2esdi_ioctl(struct inode *inode,
1092 struct file *file, u_int cmd, u_long arg)
1095 struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
1096 int dev = DEVICE_NR(inode->i_rdev), err;
1098 if (inode && (dev < ps2esdi_drives))
1102 if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
1104 put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
1105 put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
1106 put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
1107 put_user(ps2esdi[MINOR(inode->i_rdev)].start_sect,
1108 (long *) &geometry->start);
1115 if (!capable(CAP_SYS_ADMIN))
1117 return (ps2esdi_reread_partitions(inode->i_rdev));
1129 return blk_ioctl(inode->i_rdev, cmd, arg);
1136 static int ps2esdi_reread_partitions(kdev_t dev)
1138 int target = DEVICE_NR(dev);
1139 int start = target << ps2esdi_gendisk.minor_shift;
1142 ps2esdi_valid[target] = (access_count[target] != 1);
1143 if (ps2esdi_valid[target])
1146 for (partition = ps2esdi_gendisk.max_p - 1;
1147 partition >= 0; partition--) {
1148 int minor = (start | partition);
1149 invalidate_device(MKDEV(MAJOR_NR, minor), 1);
1150 ps2esdi_gendisk.part[minor].start_sect = 0;
1151 ps2esdi_gendisk.part[minor].nr_sects = 0;
1154 grok_partitions(&ps2esdi_gendisk, target, 1<<6,
1155 ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect);
1157 ps2esdi_valid[target] = 1;
1158 wake_up(&ps2esdi_wait_open);
1163 static void ps2esdi_reset_timer(unsigned long unused)
1168 status = inb(ESDI_INTRPT);
1169 if ((status & 0xf) == INT_RESET) {
1170 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
1171 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
1174 wake_up(&ps2esdi_int);