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/config.h>
33 #include <linux/major.h>
34 #include <linux/errno.h>
35 #include <linux/wait.h>
36 #include <linux/interrupt.h>
38 #include <linux/kernel.h>
39 #include <linux/genhd.h>
40 #include <linux/ps2esdi.h>
41 #include <linux/blkdev.h>
42 #include <linux/mca-legacy.h>
43 #include <linux/init.h>
44 #include <linux/ioport.h>
45 #include <linux/module.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_ioctl(struct inode
*inode
, struct file
*file
,
85 u_int cmd
, u_long arg
);
87 static int ps2esdi_read_status_words(int num_words
, int max_words
, u_short
* buffer
);
89 static void dump_cmd_complete_status(u_int int_ret_code
);
91 static void ps2esdi_get_device_cfg(void);
93 static void ps2esdi_reset_timer(unsigned long unused
);
95 static u_int dma_arb_level
; /* DMA arbitration level */
97 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int
);
99 static int no_int_yet
;
100 static int ps2esdi_drives
;
101 static u_short io_base
;
102 static struct timer_list esdi_timer
=
103 TIMER_INITIALIZER(ps2esdi_reset_timer
, 0, 0);
104 static int reset_status
;
105 static int ps2esdi_slot
= -1;
106 static int tp720esdi
= 0; /* Is it Integrated ESDI of ThinkPad-720? */
107 static int intg_esdi
= 0; /* If integrated adapter */
108 struct ps2esdi_i_struct
{
109 unsigned int head
, sect
, cyl
, wpcom
, lzone
, ctl
;
111 static DEFINE_SPINLOCK(ps2esdi_lock
);
112 static struct request_queue
*ps2esdi_queue
;
113 static struct request
*current_req
;
116 #if 0 /* try both - I don't know which one is better... UB */
117 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
119 {4, 48, 1553, 0, 0, 0},
122 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
124 {64, 32, 161, 0, 0, 0},
128 static struct ps2esdi_i_struct ps2esdi_info
[MAX_HD
] =
133 static struct block_device_operations ps2esdi_fops
=
135 .owner
= THIS_MODULE
,
136 .ioctl
= ps2esdi_ioctl
,
139 static struct gendisk
*ps2esdi_gendisk
[2];
141 /* initialization routine called by ll_rw_blk.c */
142 static int __init
ps2esdi_init(void)
147 /* register the device - pass the name and major number */
148 if (register_blkdev(PS2ESDI_MAJOR
, "ed"))
151 /* set up some global information - indicating device specific info */
152 ps2esdi_queue
= blk_init_queue(do_ps2esdi_request
, &ps2esdi_lock
);
153 if (!ps2esdi_queue
) {
154 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
158 /* some minor housekeeping - setup the global gendisk structure */
159 error
= ps2esdi_geninit();
161 printk(KERN_WARNING
"PS2ESDI: error initialising"
162 " device, releasing resources\n");
163 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
164 blk_cleanup_queue(ps2esdi_queue
);
172 module_init(ps2esdi_init
);
176 static int cyl
[MAX_HD
] = {-1,-1};
177 static int head
[MAX_HD
] = {-1, -1};
178 static int sect
[MAX_HD
] = {-1, -1};
180 module_param(tp720esdi
, bool, 0);
181 module_param_array(cyl
, int, NULL
, 0);
182 module_param_array(head
, int, NULL
, 0);
183 module_param_array(sect
, int, NULL
, 0);
184 MODULE_LICENSE("GPL");
186 int init_module(void) {
189 for(drive
= 0; drive
< MAX_HD
; drive
++) {
190 struct ps2esdi_i_struct
*info
= &ps2esdi_info
[drive
];
192 if (cyl
[drive
] != -1) {
193 info
->cyl
= info
->lzone
= cyl
[drive
];
196 if (head
[drive
] != -1) {
197 info
->head
= head
[drive
];
198 info
->ctl
= (head
[drive
] > 8 ? 8 : 0);
200 if (sect
[drive
] != -1) info
->sect
= sect
[drive
];
202 return ps2esdi_init();
206 cleanup_module(void) {
209 mca_mark_as_unused(ps2esdi_slot
);
210 mca_set_adapter_procfn(ps2esdi_slot
, NULL
, NULL
);
212 release_region(io_base
, 4);
213 free_dma(dma_arb_level
);
214 free_irq(PS2ESDI_IRQ
, &ps2esdi_gendisk
);
215 unregister_blkdev(PS2ESDI_MAJOR
, "ed");
216 blk_cleanup_queue(ps2esdi_queue
);
217 for (i
= 0; i
< ps2esdi_drives
; i
++) {
218 del_gendisk(ps2esdi_gendisk
[i
]);
219 put_disk(ps2esdi_gendisk
[i
]);
224 /* handles boot time command line parameters */
225 void __init
tp720_setup(char *str
, int *ints
)
227 /* no params, just sets the tp720esdi flag if it exists */
229 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME
);
233 void __init
ed_setup(char *str
, int *ints
)
237 /* handles 3 parameters only - corresponding to
238 1. Number of cylinders
246 /* print out the information - seen at boot time */
247 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
248 DEVICE_NAME
, ints
[0], ints
[1], ints
[2], ints
[3]);
250 /* set the index into device specific information table */
251 if (ps2esdi_info
[0].head
!= 0)
254 /* set up all the device information */
255 ps2esdi_info
[hdind
].head
= ints
[2];
256 ps2esdi_info
[hdind
].sect
= ints
[3];
257 ps2esdi_info
[hdind
].cyl
= ints
[1];
258 ps2esdi_info
[hdind
].wpcom
= 0;
259 ps2esdi_info
[hdind
].lzone
= ints
[1];
260 ps2esdi_info
[hdind
].ctl
= (ints
[2] > 8 ? 8 : 0);
261 #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
262 ps2esdi_drives
= hdind
+ 1; /* increment index for the next time */
266 static int ps2esdi_getinfo(char *buf
, int slot
, void *d
)
270 len
+= sprintf(buf
+ len
, "DMA Arbitration Level: %d\n",
272 len
+= sprintf(buf
+ len
, "IO Port: %x\n", io_base
);
273 len
+= sprintf(buf
+ len
, "IRQ: 14\n");
274 len
+= sprintf(buf
+ len
, "Drives: %d\n", ps2esdi_drives
);
279 /* ps2 esdi specific initialization - called thru the gendisk chain */
280 static int __init
ps2esdi_geninit(void)
283 The first part contains the initialization code
284 for the ESDI disk subsystem. All we really do
285 is search for the POS registers of the controller
286 to do some simple setup operations. First, we
287 must ensure that the controller is installed,
288 enabled, and configured as PRIMARY. Then we must
289 determine the DMA arbitration level being used by
290 the controller so we can handle data transfer
291 operations properly. If all of this works, then
292 we will set the INIT_FLAG to a non-zero value.
295 int slot
= 0, i
, reset_start
, reset_end
;
297 unsigned short adapterID
;
300 if ((slot
= mca_find_adapter(INTG_ESDI_ID
, 0)) != MCA_NOTFOUND
) {
301 adapterID
= INTG_ESDI_ID
;
302 printk("%s: integrated ESDI adapter found in slot %d\n",
303 DEVICE_NAME
, slot
+1);
305 mca_set_adapter_name(slot
, "PS/2 Integrated ESDI");
307 } else if ((slot
= mca_find_adapter(NRML_ESDI_ID
, 0)) != -1) {
308 adapterID
= NRML_ESDI_ID
;
309 printk("%s: normal ESDI adapter found in slot %d\n",
310 DEVICE_NAME
, slot
+1);
311 mca_set_adapter_name(slot
, "PS/2 ESDI");
317 mca_mark_as_used(slot
);
318 mca_set_adapter_procfn(slot
, (MCA_ProcFn
) ps2esdi_getinfo
, NULL
);
320 /* Found the slot - read the POS register 2 to get the necessary
321 configuration and status information. POS register 2 has the
322 following information :
327 1 - fairness disabled, linear priority assignment
328 5-2 arbitration level
331 0 - use addresses 0x3510 - 0x3517
335 status
= mca_read_stored_pos(slot
, 2);
336 /* is it enabled ? */
337 if (!(status
& STATUS_ENABLED
)) {
338 printk("%s: ESDI adapter disabled\n", DEVICE_NAME
);
342 /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
343 share with the SCSI driver */
344 if (request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
345 SA_INTERRUPT
| SA_SHIRQ
, "PS/2 ESDI", &ps2esdi_gendisk
)
346 && request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
347 SA_SHIRQ
, "PS/2 ESDI", &ps2esdi_gendisk
)
349 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME
, PS2ESDI_IRQ
);
353 if (status
& STATUS_ALTERNATE
)
354 io_base
= ALT_IO_BASE
;
356 io_base
= PRIMARY_IO_BASE
;
358 if (!request_region(io_base
, 4, "ed")) {
359 printk(KERN_WARNING
"Unable to request region 0x%x\n", io_base
);
363 /* get the dma arbitration level */
364 dma_arb_level
= (status
>> 2) & 0xf;
367 printk("%s: DMA arbitration level : %d\n",
368 DEVICE_NAME
, dma_arb_level
);
371 current_int_handler
= ps2esdi_initial_reset_int_handler
;
374 reset_start
= jiffies
;
375 while (!reset_status
) {
376 init_timer(&esdi_timer
);
377 esdi_timer
.expires
= jiffies
+ HZ
;
379 add_timer(&esdi_timer
);
380 sleep_on(&ps2esdi_int
);
384 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
385 DEVICE_NAME
, reset_end
- reset_start
, (reset_end
- reset_start
) / HZ
,
386 (reset_end
- reset_start
) % HZ
);
389 /* Integrated ESDI Disk and Controller has only one drive! */
390 if (adapterID
== INTG_ESDI_ID
) {/* if not "normal" PS2 ESDI adapter */
391 ps2esdi_drives
= 1; /* then we have only one physical disk! */ intg_esdi
= 1;
396 /* finally this part sets up some global data structures etc. */
398 ps2esdi_get_device_cfg();
400 /* some annoyance in the above routine returns TWO drives?
401 Is something else happining in the background?
402 Regaurdless we fix the # of drives again. AJK */
403 /* Integrated ESDI Disk and Controller has only one drive! */
404 if (adapterID
== INTG_ESDI_ID
) /* if not "normal" PS2 ESDI adapter */
405 ps2esdi_drives
= 1; /* Not three or two, ONE DAMNIT! */
407 current_int_handler
= ps2esdi_normal_interrupt_handler
;
409 if (request_dma(dma_arb_level
, "ed") !=0) {
410 printk(KERN_WARNING
"PS2ESDI: Can't request dma-channel %d\n"
411 ,(int) dma_arb_level
);
415 blk_queue_max_sectors(ps2esdi_queue
, 128);
418 for (i
= 0; i
< ps2esdi_drives
; i
++) {
419 struct gendisk
*disk
= alloc_disk(64);
422 disk
->major
= PS2ESDI_MAJOR
;
423 disk
->first_minor
= i
<<6;
424 sprintf(disk
->disk_name
, "ed%c", 'a'+i
);
425 sprintf(disk
->devfs_name
, "ed/target%d", i
);
426 disk
->fops
= &ps2esdi_fops
;
427 ps2esdi_gendisk
[i
] = disk
;
430 for (i
= 0; i
< ps2esdi_drives
; i
++) {
431 struct gendisk
*disk
= ps2esdi_gendisk
[i
];
432 set_capacity(disk
, ps2esdi_info
[i
].head
* ps2esdi_info
[i
].sect
*
433 ps2esdi_info
[i
].cyl
);
434 disk
->queue
= ps2esdi_queue
;
435 disk
->private_data
= &ps2esdi_info
[i
];
441 put_disk(ps2esdi_gendisk
[i
]);
443 release_region(io_base
, 4);
445 free_irq(PS2ESDI_IRQ
, &ps2esdi_gendisk
);
448 mca_mark_as_unused(ps2esdi_slot
);
449 mca_set_adapter_procfn(ps2esdi_slot
, NULL
, NULL
);
454 static void __init
ps2esdi_get_device_cfg(void)
456 u_short cmd_blk
[TYPE_0_CMD_BLK_LENGTH
];
458 /*BA */ printk("%s: Drive 0\n", DEVICE_NAME
);
459 current_int_handler
= ps2esdi_geometry_int_handler
;
460 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| 0x600;
463 ps2esdi_out_cmd_blk(cmd_blk
);
465 sleep_on(&ps2esdi_int
);
467 if (ps2esdi_drives
> 1) {
468 printk("%s: Drive 1\n", DEVICE_NAME
); /*BA */
469 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| (1 << 5) | 0x600;
472 ps2esdi_out_cmd_blk(cmd_blk
);
474 sleep_on(&ps2esdi_int
);
475 } /* if second physical drive is present */
479 /* strategy routine that handles most of the IO requests */
480 static void do_ps2esdi_request(request_queue_t
* q
)
483 /* since, this routine is called with interrupts cleared - they
484 must be before it finishes */
486 req
= elv_next_request(q
);
491 printk("%s:got request. device : %s command : %d sector : %ld count : %ld, buffer: %p\n",
493 req
->rq_disk
->disk_name
,
494 req
->cmd
, req
->sector
,
495 req
->current_nr_sectors
, req
->buffer
);
498 /* check for above 16Mb dmas */
499 if (isa_virt_to_bus(req
->buffer
+ req
->current_nr_sectors
* 512) > 16 * MB
) {
500 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME
);
501 end_request(req
, FAIL
);
505 if (req
->sector
+req
->current_nr_sectors
> get_capacity(req
->rq_disk
)) {
506 printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n",
507 ps2esdi_drives
, req
->sector
,
508 (unsigned long long)get_capacity(req
->rq_disk
));
509 end_request(req
, FAIL
);
513 switch (rq_data_dir(req
)) {
515 ps2esdi_readwrite(READ
, req
);
518 ps2esdi_readwrite(WRITE
, req
);
521 printk("%s: Unknown command\n", req
->rq_disk
->disk_name
);
522 end_request(req
, FAIL
);
524 } /* handle different commands */
525 } /* main strategy routine */
527 /* resets the ESDI adapter */
528 static void reset_ctrl(void)
534 /* enable interrupts on the controller */
535 status
= inb(ESDI_INTRPT
);
536 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
); /* to be sure we don't have
537 any interrupt pending... */
538 outb_p(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
540 /* read the ESDI status port - if the controller is not busy,
541 simply do a soft reset (fast) - otherwise we'll have to do a
542 hard (slow) reset. */
543 if (!(inb_p(ESDI_STATUS
) & STATUS_BUSY
)) {
544 /*BA */ printk("%s: soft reset...\n", DEVICE_NAME
);
545 outb_p(CTRL_SOFT_RESET
, ESDI_ATTN
);
550 printk("%s: hard reset...\n", DEVICE_NAME
);
551 outb_p(CTRL_HARD_RESET
, ESDI_CONTROL
);
552 expire
= jiffies
+ 2*HZ
;
553 while (time_before(jiffies
, expire
));
554 outb_p(1, ESDI_CONTROL
);
558 } /* reset the controller */
560 /* called by the strategy routine to handle read and write requests */
561 static void ps2esdi_readwrite(int cmd
, struct request
*req
)
563 struct ps2esdi_i_struct
*p
= req
->rq_disk
->private_data
;
564 unsigned block
= req
->sector
;
565 unsigned count
= req
->current_nr_sectors
;
566 int drive
= p
- ps2esdi_info
;
567 u_short track
, head
, cylinder
, sector
;
568 u_short cmd_blk
[TYPE_1_CMD_BLK_LENGTH
];
570 /* do some relevant arithmatic */
571 track
= block
/ p
->sect
;
572 head
= track
% p
->head
;
573 cylinder
= track
/ p
->head
;
574 sector
= block
% p
->sect
;
577 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME
, cylinder
, head
, sector
);
579 /* call the routine that actually fills out a command block */
580 ps2esdi_fill_cmd_block
582 (cmd
== READ
) ? CMD_READ
: CMD_WRITE
,
583 cylinder
, head
, sector
, count
, drive
);
585 /* send the command block to the controller */
587 spin_unlock_irq(&ps2esdi_lock
);
588 if (ps2esdi_out_cmd_blk(cmd_blk
)) {
589 spin_lock_irq(&ps2esdi_lock
);
590 printk("%s: Controller failed\n", DEVICE_NAME
);
591 if ((++req
->errors
) >= MAX_RETRIES
)
592 end_request(req
, FAIL
);
594 /* check for failure to put out the command block */
596 spin_lock_irq(&ps2esdi_lock
);
598 printk("%s: waiting for xfer\n", DEVICE_NAME
);
600 /* turn disk lights on */
604 } /* ps2esdi_readwrite */
606 /* fill out the command block */
607 static void ps2esdi_fill_cmd_block(u_short
* cmd_blk
, u_short cmd
,
608 u_short cyl
, u_short head
, u_short sector
, u_short length
, u_char drive
)
611 cmd_blk
[0] = (drive
<< 5) | cmd
;
613 cmd_blk
[2] = ((cyl
& 0x1f) << 11) | (head
<< 5) | sector
;
614 cmd_blk
[3] = (cyl
& 0x3E0) >> 5;
616 } /* fill out the command block */
618 /* write a command block to the controller */
619 static int ps2esdi_out_cmd_blk(u_short
* cmd_blk
)
626 /* enable interrupts */
627 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
629 /* do not write to the controller, if it is busy */
630 for (jif
= jiffies
+ ESDI_STAT_TIMEOUT
;
631 time_after(jif
, jiffies
) &&
632 (inb(ESDI_STATUS
) & STATUS_BUSY
); )
636 printk("%s: i(1)=%ld\n", DEVICE_NAME
, jif
);
639 /* if device is still busy - then just time out */
640 if (inb(ESDI_STATUS
) & STATUS_BUSY
) {
641 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME
);
644 /* Set up the attention register in the controller */
645 outb(((*cmd_blk
) & 0xE0) | 1, ESDI_ATTN
);
648 printk("%s: sending %d words to controller\n", DEVICE_NAME
, (((*cmd_blk
) >> 14) + 1) << 1);
651 /* one by one send each word out */
652 for (i
= (((*cmd_blk
) >> 14) + 1) << 1; i
; i
--) {
653 status
= inb(ESDI_STATUS
);
654 for (jif
= jiffies
+ ESDI_STAT_TIMEOUT
;
655 time_after(jif
, jiffies
) && (status
& STATUS_BUSY
) &&
656 (status
& STATUS_CMD_INF
); status
= inb(ESDI_STATUS
));
657 if ((status
& (STATUS_BUSY
| STATUS_CMD_INF
)) == STATUS_BUSY
) {
659 printk("%s: sending %04X\n", DEVICE_NAME
, *cmd_blk
);
661 outw(*cmd_blk
++, ESDI_CMD_INT
);
663 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
664 DEVICE_NAME
, status
);
667 } /* send all words out */
669 } /* send out the commands */
672 /* prepare for dma - do all the necessary setup */
673 static void ps2esdi_prep_dma(char *buffer
, u_short length
, u_char dma_xmode
)
675 unsigned long flags
= claim_dma_lock();
677 mca_disable_dma(dma_arb_level
);
679 mca_set_dma_addr(dma_arb_level
, isa_virt_to_bus(buffer
));
681 mca_set_dma_count(dma_arb_level
, length
* 512 / 2);
683 mca_set_dma_mode(dma_arb_level
, dma_xmode
);
685 mca_enable_dma(dma_arb_level
);
687 release_dma_lock(flags
);
689 } /* prepare for dma */
693 static irqreturn_t
ps2esdi_interrupt_handler(int irq
, void *dev_id
,
694 struct pt_regs
*regs
)
698 if (inb(ESDI_STATUS
) & STATUS_INTR
) {
699 int_ret_code
= inb(ESDI_INTRPT
);
700 if (current_int_handler
) {
701 /* Disable adapter interrupts till processing is finished */
702 outb(CTRL_DISABLE_INTR
, ESDI_CONTROL
);
703 current_int_handler(int_ret_code
);
705 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME
);
712 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code
)
715 switch (int_ret_code
& 0xf) {
718 printk("%s: initial reset completed.\n", DEVICE_NAME
);
719 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
720 wake_up(&ps2esdi_int
);
723 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
725 printk("%s: status: %02x\n", DEVICE_NAME
, inb(ESDI_STATUS
));
728 printk("%s: initial reset handler received interrupt: %02X\n",
729 DEVICE_NAME
, int_ret_code
);
730 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
733 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
737 static void ps2esdi_geometry_int_handler(u_int int_ret_code
)
739 u_int status
, drive_num
;
743 drive_num
= int_ret_code
>> 5;
744 switch (int_ret_code
& 0xf) {
745 case INT_CMD_COMPLETE
:
746 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
747 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
748 printk("%s: timeout reading status word\n", DEVICE_NAME
);
749 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
752 status
= inw(ESDI_STT_INT
);
753 if ((status
& 0x1F) == CMD_GET_DEV_CONFIG
) {
754 #define REPLY_WORDS 5 /* we already read word 0 */
755 u_short reply
[REPLY_WORDS
];
757 if (ps2esdi_read_status_words((status
>> 8) - 1, REPLY_WORDS
, reply
)) {
759 printk("%s: Device Configuration Status for drive %u\n",
760 DEVICE_NAME
, drive_num
);
762 printk("%s: Spares/cyls: %u", DEVICE_NAME
, reply
[0] >> 8);
765 ("Config bits: %s%s%s%s%s\n",
766 (reply
[0] & CONFIG_IS
) ? "Invalid Secondary, " : "",
767 ((reply
[0] & CONFIG_ZD
) && !(reply
[0] & CONFIG_IS
))
768 ? "Zero Defect, " : "Defects Present, ",
769 (reply
[0] & CONFIG_SF
) ? "Skewed Format, " : "",
770 (reply
[0] & CONFIG_FR
) ? "Removable, " : "Non-Removable, ",
771 (reply
[0] & CONFIG_RT
) ? "No Retries" : "Retries");
773 rba
= reply
[1] | ((unsigned long) reply
[2] << 16);
774 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME
, rba
);
776 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
777 DEVICE_NAME
, reply
[3], reply
[4] >> 8, reply
[4] & 0xff);
779 if (!ps2esdi_info
[drive_num
].head
) {
780 ps2esdi_info
[drive_num
].head
= 64;
781 ps2esdi_info
[drive_num
].sect
= 32;
782 ps2esdi_info
[drive_num
].cyl
= rba
/ (64 * 32);
783 ps2esdi_info
[drive_num
].wpcom
= 0;
784 ps2esdi_info
[drive_num
].lzone
= ps2esdi_info
[drive_num
].cyl
;
785 ps2esdi_info
[drive_num
].ctl
= 8;
786 if (tp720esdi
) { /* store the retrieved parameters */
787 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
788 ps2esdi_info
[0].sect
= reply
[4] >> 8;
789 ps2esdi_info
[0].cyl
= reply
[3];
790 ps2esdi_info
[0].wpcom
= 0;
791 ps2esdi_info
[0].lzone
= reply
[3];
798 if (!ps2esdi_info
[drive_num
].head
) {
799 ps2esdi_info
[drive_num
].head
= reply
[4] & 0Xff;
800 ps2esdi_info
[drive_num
].sect
= reply
[4] >> 8;
801 ps2esdi_info
[drive_num
].cyl
= reply
[3];
802 ps2esdi_info
[drive_num
].wpcom
= 0;
803 ps2esdi_info
[drive_num
].lzone
= reply
[3];
804 if (tp720esdi
) { /* store the retrieved parameters */
805 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
806 ps2esdi_info
[0].sect
= reply
[4] >> 8;
807 ps2esdi_info
[0].cyl
= reply
[3];
808 ps2esdi_info
[0].wpcom
= 0;
809 ps2esdi_info
[0].lzone
= reply
[3];
817 printk("%s: failed while getting device config\n", DEVICE_NAME
);
820 printk("%s: command %02X unknown by geometry handler\n",
821 DEVICE_NAME
, status
& 0x1f);
823 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
827 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
829 printk("%s: Device not available\n", DEVICE_NAME
);
833 case INT_CMD_ECC_RETRY
:
834 case INT_CMD_WARNING
:
838 case INT_CMD_BLK_ERR
:
839 /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME
);
840 dump_cmd_complete_status(int_ret_code
);
841 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
844 printk("%s: Unknown interrupt reason: %02X\n",
845 DEVICE_NAME
, int_ret_code
& 0xf);
846 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
850 wake_up(&ps2esdi_int
);
852 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
856 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code
)
863 switch (int_ret_code
& 0x0f) {
864 case INT_TRANSFER_REQ
:
865 ps2esdi_prep_dma(current_req
->buffer
,
866 current_req
->current_nr_sectors
,
867 (rq_data_dir(current_req
) == READ
)
868 ? MCA_DMA_MODE_16
| MCA_DMA_MODE_WRITE
| MCA_DMA_MODE_XFER
869 : MCA_DMA_MODE_16
| MCA_DMA_MODE_READ
);
870 outb(CTRL_ENABLE_DMA
| CTRL_ENABLE_INTR
, ESDI_CONTROL
);
875 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
877 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
881 case INT_CMD_COMPLETE
:
882 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
883 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
884 printk("%s: timeout reading status word\n", DEVICE_NAME
);
885 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
886 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
887 if ((++current_req
->errors
) >= MAX_RETRIES
)
893 status
= inw(ESDI_STT_INT
);
894 switch (status
& 0x1F) {
895 case (CMD_READ
& 0xff):
896 case (CMD_WRITE
& 0xff):
898 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
899 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
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_req
->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(&ps2esdi_lock
, flags
);
966 end_request(current_req
, ending
);
968 do_ps2esdi_request(ps2esdi_queue
);
969 spin_unlock_irqrestore(&ps2esdi_lock
, flags
);
971 } /* handle interrupts */
975 static int ps2esdi_read_status_words(int num_words
,
981 for (; max_words
&& num_words
; max_words
--, num_words
--, buffer
++) {
982 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
983 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
984 printk("%s: timeout reading status word\n", DEVICE_NAME
);
987 *buffer
= inw(ESDI_STT_INT
);
995 static void dump_cmd_complete_status(u_int int_ret_code
)
997 #define WAIT_FOR_STATUS \
998 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
999 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
1000 printk("%s: timeout reading status word\n",DEVICE_NAME); \
1008 printk("%s: Device: %u, interrupt ID: %02X\n",
1009 DEVICE_NAME
, int_ret_code
>> 5,
1010 int_ret_code
& 0xf);
1013 stat_word
= inw(ESDI_STT_INT
);
1014 word_count
= (stat_word
>> 8) - 1;
1015 printk("%s: %u status words, command: %02X\n", DEVICE_NAME
, word_count
,
1020 stat_word
= inw(ESDI_STT_INT
);
1021 printk("%s: command status code: %02X, command error code: %02X\n",
1022 DEVICE_NAME
, stat_word
>> 8, stat_word
& 0xff);
1026 stat_word
= inw(ESDI_STT_INT
);
1027 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME
,
1028 (stat_word
& 0x1000) ? "Ready, " : "Not Ready, ",
1029 (stat_word
& 0x0800) ? "Selected, " : "Not Selected, ",
1030 (stat_word
& 0x0400) ? "Write Fault, " : "",
1031 (stat_word
& 0x0200) ? "Track 0, " : "",
1032 (stat_word
& 0x0100) ? "Seek or command complete, " : "",
1037 stat_word
= inw(ESDI_STT_INT
);
1038 printk("%s: Blocks to do: %u", DEVICE_NAME
, stat_word
);
1040 if (word_count
-= 2) {
1042 rba
= inw(ESDI_STT_INT
);
1044 rba
|= inw(ESDI_STT_INT
) << 16;
1045 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1046 (u_short
) ((rba
& 0x1ff80000) >> 11),
1047 (u_short
) ((rba
& 0x7E0) >> 5), (u_short
) (rba
& 0x1f));
1053 stat_word
= inw(ESDI_STT_INT
);
1054 printk("%s: Blocks required ECC: %u", DEVICE_NAME
, stat_word
);
1058 #undef WAIT_FOR_STATUS
1062 static int ps2esdi_ioctl(struct inode
*inode
,
1063 struct file
*file
, u_int cmd
, u_long arg
)
1065 struct ps2esdi_i_struct
*p
= inode
->i_bdev
->bd_disk
->private_data
;
1066 struct ps2esdi_geometry geom
;
1068 if (cmd
!= HDIO_GETGEO
)
1070 memset(&geom
, 0, sizeof(geom
));
1071 geom
.heads
= p
->head
;
1072 geom
.sectors
= p
->sect
;
1073 geom
.cylinders
= p
->cyl
;
1074 geom
.start
= get_start_sect(inode
->i_bdev
);
1075 if (copy_to_user((void __user
*)arg
, &geom
, sizeof(geom
)))
1080 static void ps2esdi_reset_timer(unsigned long unused
)
1085 status
= inb(ESDI_INTRPT
);
1086 if ((status
& 0xf) == INT_RESET
) {
1087 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
1088 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
1091 wake_up(&ps2esdi_int
);