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(struct request_queue
* 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 static void (*current_int_handler
) (u_int
) = NULL
;
80 static void ps2esdi_normal_interrupt_handler(u_int
);
81 static void ps2esdi_initial_reset_int_handler(u_int
);
82 static void ps2esdi_geometry_int_handler(u_int
);
83 static int ps2esdi_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
);
85 static int ps2esdi_read_status_words(int num_words
, int max_words
, u_short
* buffer
);
87 static void dump_cmd_complete_status(u_int int_ret_code
);
89 static void ps2esdi_get_device_cfg(void);
91 static void ps2esdi_reset_timer(unsigned long unused
);
93 static u_int dma_arb_level
; /* DMA arbitration level */
95 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int
);
97 static int no_int_yet
;
98 static int ps2esdi_drives
;
99 static u_short io_base
;
100 static DEFINE_TIMER(esdi_timer
, ps2esdi_reset_timer
, 0, 0);
101 static int reset_status
;
102 static int ps2esdi_slot
= -1;
103 static int tp720esdi
= 0; /* Is it Integrated ESDI of ThinkPad-720? */
104 static int intg_esdi
= 0; /* If integrated adapter */
105 struct ps2esdi_i_struct
{
106 unsigned int head
, sect
, cyl
, wpcom
, lzone
, ctl
;
108 static DEFINE_SPINLOCK(ps2esdi_lock
);
109 static struct request_queue
*ps2esdi_queue
;
110 static struct request
*current_req
;
113 #if 0 /* try both - I don't know which one is better... UB */
114 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
116 {4, 48, 1553, 0, 0, 0},
119 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
121 {64, 32, 161, 0, 0, 0},
125 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
130 static struct block_device_operations ps2esdi_fops
=
132 .owner
= THIS_MODULE
,
133 .getgeo
= ps2esdi_getgeo
,
136 static struct gendisk
*ps2esdi_gendisk
[2];
138 /* initialization routine called by ll_rw_blk.c */
139 static int __init
ps2esdi_init(void)
144 /* register the device - pass the name and major number */
145 if (register_blkdev(PS2ESDI_MAJOR
, "ed"))
148 /* set up some global information - indicating device specific info */
149 ps2esdi_queue
= blk_init_queue(do_ps2esdi_request
, &ps2esdi_lock
);
150 if (!ps2esdi_queue
) {
151 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
155 /* some minor housekeeping - setup the global gendisk structure */
156 error
= ps2esdi_geninit();
158 printk(KERN_WARNING
"PS2ESDI: error initialising"
159 " device, releasing resources\n");
160 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
161 blk_cleanup_queue(ps2esdi_queue
);
169 module_init(ps2esdi_init
);
173 static int cyl
[MAX_HD
] = {-1,-1};
174 static int head
[MAX_HD
] = {-1, -1};
175 static int sect
[MAX_HD
] = {-1, -1};
177 module_param(tp720esdi
, bool, 0);
178 module_param_array(cyl
, int, NULL
, 0);
179 module_param_array(head
, int, NULL
, 0);
180 module_param_array(sect
, int, NULL
, 0);
181 MODULE_LICENSE("GPL");
183 int init_module(void) {
186 for(drive
= 0; drive
< MAX_HD
; drive
++) {
187 struct ps2esdi_i_struct
*info
= &ps2esdi_info
[drive
];
189 if (cyl
[drive
] != -1) {
190 info
->cyl
= info
->lzone
= cyl
[drive
];
193 if (head
[drive
] != -1) {
194 info
->head
= head
[drive
];
195 info
->ctl
= (head
[drive
] > 8 ? 8 : 0);
197 if (sect
[drive
] != -1) info
->sect
= sect
[drive
];
199 return ps2esdi_init();
203 cleanup_module(void) {
206 mca_mark_as_unused(ps2esdi_slot
);
207 mca_set_adapter_procfn(ps2esdi_slot
, NULL
, NULL
);
209 release_region(io_base
, 4);
210 free_dma(dma_arb_level
);
211 free_irq(PS2ESDI_IRQ
, &ps2esdi_gendisk
);
212 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
213 blk_cleanup_queue(ps2esdi_queue
);
214 for (i
= 0; i
< ps2esdi_drives
; i
++) {
215 del_gendisk(ps2esdi_gendisk
[i
]);
216 put_disk(ps2esdi_gendisk
[i
]);
221 /* handles boot time command line parameters */
222 void __init
tp720_setup(char *str
, int *ints
)
224 /* no params, just sets the tp720esdi flag if it exists */
226 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME
);
230 void __init
ed_setup(char *str
, int *ints
)
234 /* handles 3 parameters only - corresponding to
235 1. Number of cylinders
243 /* print out the information - seen at boot time */
244 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
245 DEVICE_NAME
, ints
[0], ints
[1], ints
[2], ints
[3]);
247 /* set the index into device specific information table */
248 if (ps2esdi_info
[0].head
!= 0)
251 /* set up all the device information */
252 ps2esdi_info
[hdind
].head
= ints
[2];
253 ps2esdi_info
[hdind
].sect
= ints
[3];
254 ps2esdi_info
[hdind
].cyl
= ints
[1];
255 ps2esdi_info
[hdind
].wpcom
= 0;
256 ps2esdi_info
[hdind
].lzone
= ints
[1];
257 ps2esdi_info
[hdind
].ctl
= (ints
[2] > 8 ? 8 : 0);
258 #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
259 ps2esdi_drives
= hdind
+ 1; /* increment index for the next time */
263 static int ps2esdi_getinfo(char *buf
, int slot
, void *d
)
267 len
+= sprintf(buf
+ len
, "DMA Arbitration Level: %d\n",
269 len
+= sprintf(buf
+ len
, "IO Port: %x\n", io_base
);
270 len
+= sprintf(buf
+ len
, "IRQ: 14\n");
271 len
+= sprintf(buf
+ len
, "Drives: %d\n", ps2esdi_drives
);
276 /* ps2 esdi specific initialization - called thru the gendisk chain */
277 static int __init
ps2esdi_geninit(void)
280 The first part contains the initialization code
281 for the ESDI disk subsystem. All we really do
282 is search for the POS registers of the controller
283 to do some simple setup operations. First, we
284 must ensure that the controller is installed,
285 enabled, and configured as PRIMARY. Then we must
286 determine the DMA arbitration level being used by
287 the controller so we can handle data transfer
288 operations properly. If all of this works, then
289 we will set the INIT_FLAG to a non-zero value.
292 int slot
= 0, i
, reset_start
, reset_end
;
294 unsigned short adapterID
;
297 if ((slot
= mca_find_adapter(INTG_ESDI_ID
, 0)) != MCA_NOTFOUND
) {
298 adapterID
= INTG_ESDI_ID
;
299 printk("%s: integrated ESDI adapter found in slot %d\n",
300 DEVICE_NAME
, slot
+1);
302 mca_set_adapter_name(slot
, "PS/2 Integrated ESDI");
304 } else if ((slot
= mca_find_adapter(NRML_ESDI_ID
, 0)) != -1) {
305 adapterID
= NRML_ESDI_ID
;
306 printk("%s: normal ESDI adapter found in slot %d\n",
307 DEVICE_NAME
, slot
+1);
308 mca_set_adapter_name(slot
, "PS/2 ESDI");
314 mca_mark_as_used(slot
);
315 mca_set_adapter_procfn(slot
, (MCA_ProcFn
) ps2esdi_getinfo
, NULL
);
317 /* Found the slot - read the POS register 2 to get the necessary
318 configuration and status information. POS register 2 has the
319 following information :
324 1 - fairness disabled, linear priority assignment
325 5-2 arbitration level
328 0 - use addresses 0x3510 - 0x3517
332 status
= mca_read_stored_pos(slot
, 2);
333 /* is it enabled ? */
334 if (!(status
& STATUS_ENABLED
)) {
335 printk("%s: ESDI adapter disabled\n", DEVICE_NAME
);
339 /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
340 share with the SCSI driver */
341 if (request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
342 IRQF_DISABLED
| IRQF_SHARED
, "PS/2 ESDI", &ps2esdi_gendisk
)
343 && request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
344 IRQF_SHARED
, "PS/2 ESDI", &ps2esdi_gendisk
)
346 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME
, PS2ESDI_IRQ
);
350 if (status
& STATUS_ALTERNATE
)
351 io_base
= ALT_IO_BASE
;
353 io_base
= PRIMARY_IO_BASE
;
355 if (!request_region(io_base
, 4, "ed")) {
356 printk(KERN_WARNING
"Unable to request region 0x%x\n", io_base
);
360 /* get the dma arbitration level */
361 dma_arb_level
= (status
>> 2) & 0xf;
364 printk("%s: DMA arbitration level : %d\n",
365 DEVICE_NAME
, dma_arb_level
);
368 current_int_handler
= ps2esdi_initial_reset_int_handler
;
371 reset_start
= jiffies
;
372 while (!reset_status
) {
373 init_timer(&esdi_timer
);
374 esdi_timer
.expires
= jiffies
+ HZ
;
376 add_timer(&esdi_timer
);
377 sleep_on(&ps2esdi_int
);
381 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
382 DEVICE_NAME
, reset_end
- reset_start
, (reset_end
- reset_start
) / HZ
,
383 (reset_end
- reset_start
) % HZ
);
386 /* Integrated ESDI Disk and Controller has only one drive! */
387 if (adapterID
== INTG_ESDI_ID
) {/* if not "normal" PS2 ESDI adapter */
388 ps2esdi_drives
= 1; /* then we have only one physical disk! */ intg_esdi
= 1;
393 /* finally this part sets up some global data structures etc. */
395 ps2esdi_get_device_cfg();
397 /* some annoyance in the above routine returns TWO drives?
398 Is something else happining in the background?
399 Regaurdless we fix the # of drives again. AJK */
400 /* Integrated ESDI Disk and Controller has only one drive! */
401 if (adapterID
== INTG_ESDI_ID
) /* if not "normal" PS2 ESDI adapter */
402 ps2esdi_drives
= 1; /* Not three or two, ONE DAMNIT! */
404 current_int_handler
= ps2esdi_normal_interrupt_handler
;
406 if (request_dma(dma_arb_level
, "ed") !=0) {
407 printk(KERN_WARNING
"PS2ESDI: Can't request dma-channel %d\n"
408 ,(int) dma_arb_level
);
412 blk_queue_max_sectors(ps2esdi_queue
, 128);
415 for (i
= 0; i
< ps2esdi_drives
; i
++) {
416 struct gendisk
*disk
= alloc_disk(64);
419 disk
->major
= PS2ESDI_MAJOR
;
420 disk
->first_minor
= i
<<6;
421 sprintf(disk
->disk_name
, "ed%c", 'a'+i
);
422 disk
->fops
= &ps2esdi_fops
;
423 ps2esdi_gendisk
[i
] = disk
;
426 for (i
= 0; i
< ps2esdi_drives
; i
++) {
427 struct gendisk
*disk
= ps2esdi_gendisk
[i
];
428 set_capacity(disk
, ps2esdi_info
[i
].head
* ps2esdi_info
[i
].sect
*
429 ps2esdi_info
[i
].cyl
);
430 disk
->queue
= ps2esdi_queue
;
431 disk
->private_data
= &ps2esdi_info
[i
];
437 put_disk(ps2esdi_gendisk
[i
]);
439 release_region(io_base
, 4);
441 free_irq(PS2ESDI_IRQ
, &ps2esdi_gendisk
);
444 mca_mark_as_unused(ps2esdi_slot
);
445 mca_set_adapter_procfn(ps2esdi_slot
, NULL
, NULL
);
450 static void __init
ps2esdi_get_device_cfg(void)
452 u_short cmd_blk
[TYPE_0_CMD_BLK_LENGTH
];
454 /*BA */ printk("%s: Drive 0\n", DEVICE_NAME
);
455 current_int_handler
= ps2esdi_geometry_int_handler
;
456 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| 0x600;
459 ps2esdi_out_cmd_blk(cmd_blk
);
461 sleep_on(&ps2esdi_int
);
463 if (ps2esdi_drives
> 1) {
464 printk("%s: Drive 1\n", DEVICE_NAME
); /*BA */
465 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| (1 << 5) | 0x600;
468 ps2esdi_out_cmd_blk(cmd_blk
);
470 sleep_on(&ps2esdi_int
);
471 } /* if second physical drive is present */
475 /* strategy routine that handles most of the IO requests */
476 static void do_ps2esdi_request(struct request_queue
* q
)
479 /* since, this routine is called with interrupts cleared - they
480 must be before it finishes */
482 req
= elv_next_request(q
);
487 printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n",
489 req
->rq_disk
->disk_name
,
490 req
->cmd
, req
->sector
,
491 req
->current_nr_sectors
, req
->buffer
);
494 /* check for above 16Mb dmas */
495 if (isa_virt_to_bus(req
->buffer
+ req
->current_nr_sectors
* 512) > 16 * MB
) {
496 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME
);
497 end_request(req
, FAIL
);
501 if (req
->sector
+req
->current_nr_sectors
> get_capacity(req
->rq_disk
)) {
502 printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n",
503 ps2esdi_drives
, req
->sector
,
504 (unsigned long long)get_capacity(req
->rq_disk
));
505 end_request(req
, FAIL
);
509 switch (rq_data_dir(req
)) {
511 ps2esdi_readwrite(READ
, req
);
514 ps2esdi_readwrite(WRITE
, req
);
517 printk("%s: Unknown command\n", req
->rq_disk
->disk_name
);
518 end_request(req
, FAIL
);
520 } /* handle different commands */
521 } /* main strategy routine */
523 /* resets the ESDI adapter */
524 static void reset_ctrl(void)
530 /* enable interrupts on the controller */
531 status
= inb(ESDI_INTRPT
);
532 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
); /* to be sure we don't have
533 any interrupt pending... */
534 outb_p(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
536 /* read the ESDI status port - if the controller is not busy,
537 simply do a soft reset (fast) - otherwise we'll have to do a
538 hard (slow) reset. */
539 if (!(inb_p(ESDI_STATUS
) & STATUS_BUSY
)) {
540 /*BA */ printk("%s: soft reset...\n", DEVICE_NAME
);
541 outb_p(CTRL_SOFT_RESET
, ESDI_ATTN
);
546 printk("%s: hard reset...\n", DEVICE_NAME
);
547 outb_p(CTRL_HARD_RESET
, ESDI_CONTROL
);
548 expire
= jiffies
+ 2*HZ
;
549 while (time_before(jiffies
, expire
));
550 outb_p(1, ESDI_CONTROL
);
554 } /* reset the controller */
556 /* called by the strategy routine to handle read and write requests */
557 static void ps2esdi_readwrite(int cmd
, struct request
*req
)
559 struct ps2esdi_i_struct
*p
= req
->rq_disk
->private_data
;
560 unsigned block
= req
->sector
;
561 unsigned count
= req
->current_nr_sectors
;
562 int drive
= p
- ps2esdi_info
;
563 u_short track
, head
, cylinder
, sector
;
564 u_short cmd_blk
[TYPE_1_CMD_BLK_LENGTH
];
566 /* do some relevant arithmatic */
567 track
= block
/ p
->sect
;
568 head
= track
% p
->head
;
569 cylinder
= track
/ p
->head
;
570 sector
= block
% p
->sect
;
573 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME
, cylinder
, head
, sector
);
575 /* call the routine that actually fills out a command block */
576 ps2esdi_fill_cmd_block
578 (cmd
== READ
) ? CMD_READ
: CMD_WRITE
,
579 cylinder
, head
, sector
, count
, drive
);
581 /* send the command block to the controller */
583 spin_unlock_irq(&ps2esdi_lock
);
584 if (ps2esdi_out_cmd_blk(cmd_blk
)) {
585 spin_lock_irq(&ps2esdi_lock
);
586 printk("%s: Controller failed\n", DEVICE_NAME
);
587 if ((++req
->errors
) >= MAX_RETRIES
)
588 end_request(req
, FAIL
);
590 /* check for failure to put out the command block */
592 spin_lock_irq(&ps2esdi_lock
);
594 printk("%s: waiting for xfer\n", DEVICE_NAME
);
596 /* turn disk lights on */
600 } /* ps2esdi_readwrite */
602 /* fill out the command block */
603 static void ps2esdi_fill_cmd_block(u_short
* cmd_blk
, u_short cmd
,
604 u_short cyl
, u_short head
, u_short sector
, u_short length
, u_char drive
)
607 cmd_blk
[0] = (drive
<< 5) | cmd
;
609 cmd_blk
[2] = ((cyl
& 0x1f) << 11) | (head
<< 5) | sector
;
610 cmd_blk
[3] = (cyl
& 0x3E0) >> 5;
612 } /* fill out the command block */
614 /* write a command block to the controller */
615 static int ps2esdi_out_cmd_blk(u_short
* cmd_blk
)
622 /* enable interrupts */
623 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
625 /* do not write to the controller, if it is busy */
626 for (jif
= jiffies
+ ESDI_STAT_TIMEOUT
;
627 time_after(jif
, jiffies
) &&
628 (inb(ESDI_STATUS
) & STATUS_BUSY
); )
632 printk("%s: i(1)=%ld\n", DEVICE_NAME
, jif
);
635 /* if device is still busy - then just time out */
636 if (inb(ESDI_STATUS
) & STATUS_BUSY
) {
637 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME
);
640 /* Set up the attention register in the controller */
641 outb(((*cmd_blk
) & 0xE0) | 1, ESDI_ATTN
);
644 printk("%s: sending %d words to controller\n", DEVICE_NAME
, (((*cmd_blk
) >> 14) + 1) << 1);
647 /* one by one send each word out */
648 for (i
= (((*cmd_blk
) >> 14) + 1) << 1; i
; i
--) {
649 status
= inb(ESDI_STATUS
);
650 for (jif
= jiffies
+ ESDI_STAT_TIMEOUT
;
651 time_after(jif
, jiffies
) && (status
& STATUS_BUSY
) &&
652 (status
& STATUS_CMD_INF
); status
= inb(ESDI_STATUS
));
653 if ((status
& (STATUS_BUSY
| STATUS_CMD_INF
)) == STATUS_BUSY
) {
655 printk("%s: sending %04X\n", DEVICE_NAME
, *cmd_blk
);
657 outw(*cmd_blk
++, ESDI_CMD_INT
);
659 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
660 DEVICE_NAME
, status
);
663 } /* send all words out */
665 } /* send out the commands */
668 /* prepare for dma - do all the necessary setup */
669 static void ps2esdi_prep_dma(char *buffer
, u_short length
, u_char dma_xmode
)
671 unsigned long flags
= claim_dma_lock();
673 mca_disable_dma(dma_arb_level
);
675 mca_set_dma_addr(dma_arb_level
, isa_virt_to_bus(buffer
));
677 mca_set_dma_count(dma_arb_level
, length
* 512 / 2);
679 mca_set_dma_mode(dma_arb_level
, dma_xmode
);
681 mca_enable_dma(dma_arb_level
);
683 release_dma_lock(flags
);
685 } /* prepare for dma */
689 static irqreturn_t
ps2esdi_interrupt_handler(int irq
, void *dev_id
)
693 if (inb(ESDI_STATUS
) & STATUS_INTR
) {
694 int_ret_code
= inb(ESDI_INTRPT
);
695 if (current_int_handler
) {
696 /* Disable adapter interrupts till processing is finished */
697 outb(CTRL_DISABLE_INTR
, ESDI_CONTROL
);
698 current_int_handler(int_ret_code
);
700 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME
);
707 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code
)
710 switch (int_ret_code
& 0xf) {
713 printk("%s: initial reset completed.\n", DEVICE_NAME
);
714 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
715 wake_up(&ps2esdi_int
);
718 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
720 printk("%s: status: %02x\n", DEVICE_NAME
, inb(ESDI_STATUS
));
723 printk("%s: initial reset handler received interrupt: %02X\n",
724 DEVICE_NAME
, int_ret_code
);
725 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
728 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
732 static void ps2esdi_geometry_int_handler(u_int int_ret_code
)
734 u_int status
, drive_num
;
738 drive_num
= int_ret_code
>> 5;
739 switch (int_ret_code
& 0xf) {
740 case INT_CMD_COMPLETE
:
741 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
742 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
743 printk("%s: timeout reading status word\n", DEVICE_NAME
);
744 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
747 status
= inw(ESDI_STT_INT
);
748 if ((status
& 0x1F) == CMD_GET_DEV_CONFIG
) {
749 #define REPLY_WORDS 5 /* we already read word 0 */
750 u_short reply
[REPLY_WORDS
];
752 if (ps2esdi_read_status_words((status
>> 8) - 1, REPLY_WORDS
, reply
)) {
754 printk("%s: Device Configuration Status for drive %u\n",
755 DEVICE_NAME
, drive_num
);
757 printk("%s: Spares/cyls: %u", DEVICE_NAME
, reply
[0] >> 8);
760 ("Config bits: %s%s%s%s%s\n",
761 (reply
[0] & CONFIG_IS
) ? "Invalid Secondary, " : "",
762 ((reply
[0] & CONFIG_ZD
) && !(reply
[0] & CONFIG_IS
))
763 ? "Zero Defect, " : "Defects Present, ",
764 (reply
[0] & CONFIG_SF
) ? "Skewed Format, " : "",
765 (reply
[0] & CONFIG_FR
) ? "Removable, " : "Non-Removable, ",
766 (reply
[0] & CONFIG_RT
) ? "No Retries" : "Retries");
768 rba
= reply
[1] | ((unsigned long) reply
[2] << 16);
769 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME
, rba
);
771 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
772 DEVICE_NAME
, reply
[3], reply
[4] >> 8, reply
[4] & 0xff);
774 if (!ps2esdi_info
[drive_num
].head
) {
775 ps2esdi_info
[drive_num
].head
= 64;
776 ps2esdi_info
[drive_num
].sect
= 32;
777 ps2esdi_info
[drive_num
].cyl
= rba
/ (64 * 32);
778 ps2esdi_info
[drive_num
].wpcom
= 0;
779 ps2esdi_info
[drive_num
].lzone
= ps2esdi_info
[drive_num
].cyl
;
780 ps2esdi_info
[drive_num
].ctl
= 8;
781 if (tp720esdi
) { /* store the retrieved parameters */
782 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
783 ps2esdi_info
[0].sect
= reply
[4] >> 8;
784 ps2esdi_info
[0].cyl
= reply
[3];
785 ps2esdi_info
[0].wpcom
= 0;
786 ps2esdi_info
[0].lzone
= reply
[3];
793 if (!ps2esdi_info
[drive_num
].head
) {
794 ps2esdi_info
[drive_num
].head
= reply
[4] & 0Xff;
795 ps2esdi_info
[drive_num
].sect
= reply
[4] >> 8;
796 ps2esdi_info
[drive_num
].cyl
= reply
[3];
797 ps2esdi_info
[drive_num
].wpcom
= 0;
798 ps2esdi_info
[drive_num
].lzone
= reply
[3];
799 if (tp720esdi
) { /* store the retrieved parameters */
800 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
801 ps2esdi_info
[0].sect
= reply
[4] >> 8;
802 ps2esdi_info
[0].cyl
= reply
[3];
803 ps2esdi_info
[0].wpcom
= 0;
804 ps2esdi_info
[0].lzone
= reply
[3];
812 printk("%s: failed while getting device config\n", DEVICE_NAME
);
815 printk("%s: command %02X unknown by geometry handler\n",
816 DEVICE_NAME
, status
& 0x1f);
818 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
822 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
824 printk("%s: Device not available\n", DEVICE_NAME
);
828 case INT_CMD_ECC_RETRY
:
829 case INT_CMD_WARNING
:
833 case INT_CMD_BLK_ERR
:
834 /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME
);
835 dump_cmd_complete_status(int_ret_code
);
836 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
839 printk("%s: Unknown interrupt reason: %02X\n",
840 DEVICE_NAME
, int_ret_code
& 0xf);
841 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
845 wake_up(&ps2esdi_int
);
847 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
851 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code
)
858 switch (int_ret_code
& 0x0f) {
859 case INT_TRANSFER_REQ
:
860 ps2esdi_prep_dma(current_req
->buffer
,
861 current_req
->current_nr_sectors
,
862 (rq_data_dir(current_req
) == READ
)
863 ? MCA_DMA_MODE_16
| MCA_DMA_MODE_WRITE
| MCA_DMA_MODE_XFER
864 : MCA_DMA_MODE_16
| MCA_DMA_MODE_READ
);
865 outb(CTRL_ENABLE_DMA
| CTRL_ENABLE_INTR
, ESDI_CONTROL
);
870 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
872 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
876 case INT_CMD_COMPLETE
:
877 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
878 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
879 printk("%s: timeout reading status word\n", DEVICE_NAME
);
880 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
881 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
882 if ((++current_req
->errors
) >= MAX_RETRIES
)
888 status
= inw(ESDI_STT_INT
);
889 switch (status
& 0x1F) {
890 case (CMD_READ
& 0xff):
891 case (CMD_WRITE
& 0xff):
893 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
894 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
898 printk("%s: interrupt for unknown command %02X\n",
899 DEVICE_NAME
, status
& 0x1f);
900 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
901 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
908 case INT_CMD_ECC_RETRY
:
910 dump_cmd_complete_status(int_ret_code
);
911 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
912 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
915 case INT_CMD_WARNING
:
920 dump_cmd_complete_status(int_ret_code
);
921 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
922 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
923 if ((++current_req
->errors
) >= MAX_RETRIES
)
929 case INT_CMD_BLK_ERR
:
930 dump_cmd_complete_status(int_ret_code
);
931 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
932 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
937 printk("%s: huh ? Who issued this format command ?\n"
939 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
940 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
945 /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
946 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
947 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
952 printk("%s: Unknown interrupt reason: %02X\n",
953 DEVICE_NAME
, int_ret_code
& 0xf);
954 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
955 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
960 spin_lock_irqsave(&ps2esdi_lock
, flags
);
961 end_request(current_req
, ending
);
963 do_ps2esdi_request(ps2esdi_queue
);
964 spin_unlock_irqrestore(&ps2esdi_lock
, flags
);
966 } /* handle interrupts */
970 static int ps2esdi_read_status_words(int num_words
,
976 for (; max_words
&& num_words
; max_words
--, num_words
--, buffer
++) {
977 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
978 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
979 printk("%s: timeout reading status word\n", DEVICE_NAME
);
982 *buffer
= inw(ESDI_STT_INT
);
990 static void dump_cmd_complete_status(u_int int_ret_code
)
992 #define WAIT_FOR_STATUS \
993 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
994 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
995 printk("%s: timeout reading status word\n",DEVICE_NAME); \
1003 printk("%s: Device: %u, interrupt ID: %02X\n",
1004 DEVICE_NAME
, int_ret_code
>> 5,
1005 int_ret_code
& 0xf);
1008 stat_word
= inw(ESDI_STT_INT
);
1009 word_count
= (stat_word
>> 8) - 1;
1010 printk("%s: %u status words, command: %02X\n", DEVICE_NAME
, word_count
,
1015 stat_word
= inw(ESDI_STT_INT
);
1016 printk("%s: command status code: %02X, command error code: %02X\n",
1017 DEVICE_NAME
, stat_word
>> 8, stat_word
& 0xff);
1021 stat_word
= inw(ESDI_STT_INT
);
1022 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME
,
1023 (stat_word
& 0x1000) ? "Ready, " : "Not Ready, ",
1024 (stat_word
& 0x0800) ? "Selected, " : "Not Selected, ",
1025 (stat_word
& 0x0400) ? "Write Fault, " : "",
1026 (stat_word
& 0x0200) ? "Track 0, " : "",
1027 (stat_word
& 0x0100) ? "Seek or command complete, " : "",
1032 stat_word
= inw(ESDI_STT_INT
);
1033 printk("%s: Blocks to do: %u", DEVICE_NAME
, stat_word
);
1035 if (word_count
-= 2) {
1037 rba
= inw(ESDI_STT_INT
);
1039 rba
|= inw(ESDI_STT_INT
) << 16;
1040 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1041 (u_short
) ((rba
& 0x1ff80000) >> 11),
1042 (u_short
) ((rba
& 0x7E0) >> 5), (u_short
) (rba
& 0x1f));
1048 stat_word
= inw(ESDI_STT_INT
);
1049 printk("%s: Blocks required ECC: %u", DEVICE_NAME
, stat_word
);
1053 #undef WAIT_FOR_STATUS
1057 static int ps2esdi_getgeo(struct block_device
*bdev
, struct hd_geometry
*geo
)
1059 struct ps2esdi_i_struct
*p
= bdev
->bd_disk
->private_data
;
1061 geo
->heads
= p
->head
;
1062 geo
->sectors
= p
->sect
;
1063 geo
->cylinders
= p
->cyl
;
1067 static void ps2esdi_reset_timer(unsigned long unused
)
1072 status
= inb(ESDI_INTRPT
);
1073 if ((status
& 0xf) == INT_RESET
) {
1074 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
1075 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
1078 wake_up(&ps2esdi_int
);