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/blk.h>
45 #include <linux/mca.h>
46 #include <linux/init.h>
47 #include <linux/ioport.h>
49 #include <asm/system.h>
51 #include <asm/segment.h>
53 #include <asm/uaccess.h>
55 #define PS2ESDI_IRQ 14
58 #define MAX_16BIT 65536
59 #define ESDI_TIMEOUT 0xf000
60 #define ESDI_STAT_TIMEOUT 4
62 #define TYPE_0_CMD_BLK_LENGTH 2
63 #define TYPE_1_CMD_BLK_LENGTH 4
66 static void reset_ctrl(void);
68 int ps2esdi_init(void);
70 static void ps2esdi_geninit(struct gendisk
*ignored
);
72 static void do_ps2esdi_request(void);
74 static void ps2esdi_readwrite(int cmd
, u_char drive
, u_int block
, u_int count
);
76 static void ps2esdi_fill_cmd_block(u_short
* cmd_blk
, u_short cmd
,
77 u_short cyl
, u_short head
, u_short sector
, u_short length
, u_char drive
);
79 static int ps2esdi_out_cmd_blk(u_short
* cmd_blk
);
81 static void ps2esdi_prep_dma(char *buffer
, u_short length
, u_char dma_xmode
);
83 static void ps2esdi_interrupt_handler(int irq
, void *dev_id
,
84 struct pt_regs
*regs
);
85 static void (*current_int_handler
) (u_int
) = NULL
;
86 static void ps2esdi_normal_interrupt_handler(u_int
);
87 static void ps2esdi_initial_reset_int_handler(u_int
);
88 static void ps2esdi_geometry_int_handler(u_int
);
90 static void ps2esdi_continue_request(void);
92 static int ps2esdi_open(struct inode
*inode
, struct file
*file
);
94 static int ps2esdi_release(struct inode
*inode
, struct file
*file
);
96 static int ps2esdi_ioctl(struct inode
*inode
, struct file
*file
,
97 u_int cmd
, u_long arg
);
99 static int ps2esdi_reread_partitions(kdev_t dev
);
101 static int ps2esdi_read_status_words(int num_words
, int max_words
, u_short
* buffer
);
103 static void dump_cmd_complete_status(u_int int_ret_code
);
105 static void ps2esdi_get_device_cfg(void);
107 void ps2esdi_reset_timer(unsigned long unused
);
109 u_int dma_arb_level
; /* DMA arbitration level */
111 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int
);
112 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open
);
115 static int access_count
[MAX_HD
] = {0,};
116 static char ps2esdi_valid
[MAX_HD
] = {0,};
117 static int ps2esdi_sizes
[MAX_HD
<< 6] = {0,};
118 static int ps2esdi_blocksizes
[MAX_HD
<< 6] = {0,};
119 static int ps2esdi_drives
= 0;
120 static struct hd_struct ps2esdi
[MAX_HD
<< 6];
121 static u_short io_base
;
122 static struct timer_list esdi_timer
= {NULL
, NULL
, 0, 0L, ps2esdi_reset_timer
};
123 static int reset_status
;
124 static int ps2esdi_slot
= -1;
125 int tp720esdi
= 0; /* Is it Integrated ESDI of ThinkPad-720? */
127 struct ps2esdi_i_struct
{
128 unsigned int head
, sect
, cyl
, wpcom
, lzone
, ctl
;
132 #if 0 /* try both - I don't know which one is better... UB */
133 struct ps2esdi_i_struct ps2esdi_info
[] =
135 {4, 48, 1553, 0, 0, 0},
138 struct ps2esdi_i_struct ps2esdi_info
[] =
140 {64, 32, 161, 0, 0, 0},
144 struct ps2esdi_i_struct ps2esdi_info
[] =
149 static struct file_operations ps2esdi_fops
=
151 NULL
, /* lseek - default */
152 block_read
, /* read - general block-dev read */
153 block_write
, /* write - general block-dev write */
154 NULL
, /* readdir - bad */
156 ps2esdi_ioctl
, /* ioctl */
158 ps2esdi_open
, /* open */
160 ps2esdi_release
, /* release */
161 block_fsync
/* fsync */
164 static struct gendisk ps2esdi_gendisk
=
166 MAJOR_NR
, /* Major number */
167 "ed", /* Major name */
168 6, /* Bits to shift to get real from partition */
169 1 << 6, /* Number of partitions per real disk */
170 MAX_HD
, /* maximum number of real disks */
171 ps2esdi_geninit
, /* init function */
172 ps2esdi
, /* hd struct */
173 ps2esdi_sizes
, /* block sizes */
175 (void *) ps2esdi_info
, /* internal */
179 /* initialization routine called by ll_rw_blk.c */
180 __initfunc(int ps2esdi_init(void))
183 /* register the device - pass the name, major number and operations
185 if (register_blkdev(MAJOR_NR
, "ed", &ps2esdi_fops
)) {
186 printk("%s: Unable to get major number %d\n", DEVICE_NAME
, MAJOR_NR
);
189 /* set up some global information - indicating device specific info */
190 blk_dev
[MAJOR_NR
].request_fn
= DEVICE_REQUEST
;
191 read_ahead
[MAJOR_NR
] = 8; /* 8 sector (4kB) read ahead */
193 /* some minor housekeeping - setup the global gendisk structure */
194 ps2esdi_gendisk
.next
= gendisk_head
;
195 gendisk_head
= &ps2esdi_gendisk
;
202 int cyl
[2] = {-1,-1};
203 int head
[2] = {-1, -1};
204 int sect
[2] = {-1, -1};
206 MODULE_PARM(tp720esdi
, "i");
207 MODULE_PARM(cyl
, "i");
208 MODULE_PARM(head
, "i");
209 MODULE_PARM(track
, "i");
211 int init_module(void) {
214 for(drive
= 0; drive
<= 1; drive
++) {
215 struct ps2_esdi_i_struct
*info
= &ps2esdi_info
[drive
];
217 if (cyl
[drive
] != -1) {
218 info
->cyl
= info
->lzone
= cyl
[drive
];
221 if (head
[drive
] != -1) {
222 info
->head
= head
[drive
];
223 info
->ctl
= (head
[drive
] > 8 ? 8 : 0);
225 if (sect
[drive
] != -1) info
->sect
= sect
[drive
];
227 return ps2esdi_init();
235 mca_mark_as_unused(ps2esdi_slot
);
236 mca_set_adapter_procfn(ps2esdi_slot
, NULL
, NULL
);
238 release_region(io_base
, 4);
239 free_dma(dma_arb_level
);
240 free_irq(PS2ESDI_IRQ
, NULL
)
241 unregister_blkdev(MAJOR_NR
, "ed");
245 /* handles boot time command line parameters */
246 __initfunc(void tp720_setup(char *str
, int *ints
))
248 /* no params, just sets the tp720esdi flag if it exists */
250 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME
);
254 __initfunc(void ed_setup(char *str
, int *ints
))
258 /* handles 3 parameters only - corresponding to
259 1. Number of cylinders
267 /* print out the information - seen at boot time */
268 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
269 DEVICE_NAME
, ints
[0], ints
[1], ints
[2], ints
[3]);
271 /* set the index into device specific information table */
272 if (ps2esdi_info
[0].head
!= 0)
275 /* set up all the device information */
276 ps2esdi_info
[hdind
].head
= ints
[2];
277 ps2esdi_info
[hdind
].sect
= ints
[3];
278 ps2esdi_info
[hdind
].cyl
= ints
[1];
279 ps2esdi_info
[hdind
].wpcom
= 0;
280 ps2esdi_info
[hdind
].lzone
= ints
[1];
281 ps2esdi_info
[hdind
].ctl
= (ints
[2] > 8 ? 8 : 0);
282 #if 0 /* this may be needed for PS2/Mod.80, but it hurts ThinkPad! */
283 ps2esdi_drives
= hdind
+ 1; /* increment index for the next time */
287 static int ps2esdi_getinfo(char *buf
, int slot
, void *d
)
291 len
+= sprintf(buf
+ len
, "DMA Arbitration Level: %d\n",
293 len
+= sprintf(buf
+ len
, "IO Port: %x\n", io_base
);
294 len
+= sprintf(buf
+ len
, "IRQ: 14\n");
295 len
+= sprintf(buf
+ len
, "Drives: %d\n", ps2esdi_drives
);
300 /* ps2 esdi specific initialization - called thru the gendisk chain */
301 __initfunc(static void ps2esdi_geninit(struct gendisk
*ignored
))
304 The first part contains the initialization code
305 for the ESDI disk subsystem. All we really do
306 is search for the POS registers of the controller
307 to do some simple setup operations. First, we
308 must ensure that the controller is installed,
309 enabled, and configured as PRIMARY. Then we must
310 determine the DMA arbitration level being used by
311 the controller so we can handle data transfer
312 operations properly. If all of this works, then
313 we will set the INIT_FLAG to a non-zero value.
316 int slot
= 0, i
, reset_start
, reset_end
;
318 unsigned short adapterID
;
320 if ((slot
= mca_find_adapter(INTG_ESDI_ID
, 0)) != MCA_NOTFOUND
) {
321 adapterID
= INTG_ESDI_ID
;
322 printk("%s: integrated ESDI adapter found in slot %d\n",
323 DEVICE_NAME
, slot
+1);
325 mca_set_adapter_name(slot
, "PS/2 Integrated ESDI");
327 } else if ((slot
= mca_find_adapter(NRML_ESDI_ID
, 0)) != -1) {
328 adapterID
= NRML_ESDI_ID
;
329 printk("%s: normal ESDI adapter found in slot %d\n",
330 DEVICE_NAME
, slot
+1);
331 mca_set_adapter_name(slot
, "PS/2 ESDI");
337 mca_mark_as_used(slot
);
338 mca_set_adapter_procfn(slot
, (MCA_ProcFn
) ps2esdi_getinfo
, NULL
);
340 /* Found the slot - read the POS register 2 to get the necessary
341 configuration and status information. POS register 2 has the
342 following information :
347 1 - fairness disabled, linear priority assignment
348 5-2 arbitration level
351 0 - use addresses 0x3510 - 0x3517
355 status
= mca_read_stored_pos(slot
, 2);
356 /* is it enabled ? */
357 if (!(status
& STATUS_ENABLED
)) {
358 printk("%s: ESDI adapter disabled\n", DEVICE_NAME
);
361 /* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
362 share with the SCSI driver */
363 if (request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
364 SA_INTERRUPT
| SA_SHIRQ
, "PS/2 ESDI", &ps2esdi_gendisk
)
365 && request_irq(PS2ESDI_IRQ
, ps2esdi_interrupt_handler
,
366 SA_SHIRQ
, "PS/2 ESDI", &ps2esdi_gendisk
)
368 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME
, PS2ESDI_IRQ
);
371 if (status
& STATUS_ALTERNATE
)
372 io_base
= ALT_IO_BASE
;
374 io_base
= PRIMARY_IO_BASE
;
376 /* get the dma arbitration level */
377 dma_arb_level
= (status
>> 2) & 0xf;
380 printk("%s: DMA arbitration level : %d\n",
381 DEVICE_NAME
, dma_arb_level
);
384 current_int_handler
= ps2esdi_initial_reset_int_handler
;
387 reset_start
= jiffies
;
388 while (!reset_status
) {
389 esdi_timer
.expires
= 100;
391 esdi_timer
.next
= esdi_timer
.prev
= NULL
;
392 add_timer(&esdi_timer
);
393 sleep_on(&ps2esdi_int
);
397 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
398 DEVICE_NAME
, reset_end
- reset_start
, (reset_end
- reset_start
) / HZ
,
399 (reset_end
- reset_start
) % HZ
);
402 /* Integrated ESDI Disk and Controller has only one drive! */
403 if (adapterID
== INTG_ESDI_ID
) /* if not "normal" PS2 ESDI adapter */
404 ps2esdi_drives
= 1; /* then we have only one physical disk! */
408 /* finally this part sets up some global data structures etc. */
410 ps2esdi_get_device_cfg();
412 /* some annoyance in the above routine returns TWO drives?
413 Is something else happining in the background?
414 Regaurdless we fix the # of drives again. AJK */
415 /* Integrated ESDI Disk and Controller has only one drive! */
416 if (adapterID
== INTG_ESDI_ID
) /* if not "normal" PS2 ESDI adapter */
417 ps2esdi_drives
= 1; /* Not three or two, ONE DAMNIT! */
419 current_int_handler
= ps2esdi_normal_interrupt_handler
;
421 ps2esdi_gendisk
.nr_real
= ps2esdi_drives
;
423 for (i
= 0; i
< ps2esdi_drives
; i
++) {
424 ps2esdi
[i
<< 6].nr_sects
=
425 ps2esdi_info
[i
].head
*
426 ps2esdi_info
[i
].sect
*
428 ps2esdi_valid
[i
] = 1;
430 for (i
= 0; i
< (MAX_HD
<< 6); i
++)
431 ps2esdi_blocksizes
[i
] = 1024;
433 request_dma(dma_arb_level
, "ed");
434 request_region(io_base
, 4, "ed");
435 blksize_size
[MAJOR_NR
] = ps2esdi_blocksizes
;
436 } /* ps2esdi_geninit */
439 __initfunc(static void ps2esdi_get_device_cfg(void))
441 u_short cmd_blk
[TYPE_0_CMD_BLK_LENGTH
];
443 /*BA */ printk("%s: Drive 0\n", DEVICE_NAME
);
444 current_int_handler
= ps2esdi_geometry_int_handler
;
445 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| 0x600;
448 ps2esdi_out_cmd_blk(cmd_blk
);
450 sleep_on(&ps2esdi_int
);
452 if (ps2esdi_drives
> 1) {
453 printk("%s: Drive 1\n", DEVICE_NAME
); /*BA */
454 cmd_blk
[0] = CMD_GET_DEV_CONFIG
| (1 << 5) | 0x600;
457 ps2esdi_out_cmd_blk(cmd_blk
);
459 sleep_on(&ps2esdi_int
);
460 } /* if second physical drive is present */
464 /* strategy routine that handles most of the IO requests */
465 static void do_ps2esdi_request(void)
468 /* since, this routine is called with interrupts cleared - they
469 must be before it finishes */
473 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld, buffer: %p\n",
475 CURRENT_DEV
, MINOR(CURRENT
->rq_dev
),
476 CURRENT
->cmd
, CURRENT
->sector
,
477 CURRENT
->nr_sectors
, CURRENT
->buffer
);
480 /* standard macro that ensures that requests are really on the
481 list + sanity checks. */
484 if (virt_to_bus(CURRENT
->buffer
+ CURRENT
->nr_sectors
* 512) > 16 * MB
) {
485 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME
);
488 do_ps2esdi_request();
490 } /* check for above 16Mb dmas */
491 if ((CURRENT_DEV
< ps2esdi_drives
) &&
492 (CURRENT
->sector
+ CURRENT
->nr_sectors
<=
493 ps2esdi
[MINOR(CURRENT
->rq_dev
)].nr_sects
)) {
495 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld\n",
497 CURRENT_DEV
, MINOR(CURRENT
->dev
),
498 CURRENT
->cmd
, CURRENT
->sector
,
499 CURRENT
->nr_sectors
);
503 block
= CURRENT
->sector
+ ps2esdi
[MINOR(CURRENT
->rq_dev
)].start_sect
;
506 printk("%s: blocknumber : %d\n", DEVICE_NAME
, block
);
508 count
= CURRENT
->nr_sectors
;
509 switch (CURRENT
->cmd
) {
511 ps2esdi_readwrite(READ
, CURRENT_DEV
, block
, count
);
515 ps2esdi_readwrite(WRITE
, CURRENT_DEV
, block
, count
);
519 printk("%s: Unknown command\n", DEVICE_NAME
);
522 do_ps2esdi_request();
524 } /* handle different commands */
526 /* is request is valid */
528 printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives
,
529 CURRENT
->sector
, ps2esdi
[MINOR(CURRENT
->rq_dev
)].nr_sects
);
532 do_ps2esdi_request();
535 } /* main strategy routine */
537 /* resets the ESDI adapter */
538 static void reset_ctrl(void)
544 /* enable interrupts on the controller */
545 status
= inb(ESDI_INTRPT
);
546 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
); /* to be sure we don't have
547 any interrupt pending... */
548 outb_p(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
550 /* read the ESDI status port - if the controller is not busy,
551 simply do a soft reset (fast) - otherwise we'll have to do a
552 hard (slow) reset. */
553 if (!(inb_p(ESDI_STATUS
) & STATUS_BUSY
)) {
554 /*BA */ printk("%s: soft reset...\n", DEVICE_NAME
);
555 outb_p(CTRL_SOFT_RESET
, ESDI_ATTN
);
560 printk("%s: hard reset...\n", DEVICE_NAME
);
561 outb_p(CTRL_HARD_RESET
, ESDI_CONTROL
);
562 expire
= jiffies
+ 200;
563 while (time_before(jiffies
, expire
));
564 outb_p(1, ESDI_CONTROL
);
568 } /* reset the controller */
570 /* called by the strategy routine to handle read and write requests */
571 static void ps2esdi_readwrite(int cmd
, u_char drive
, u_int block
, u_int count
)
574 u_short track
, head
, cylinder
, sector
;
575 u_short cmd_blk
[TYPE_1_CMD_BLK_LENGTH
];
577 /* do some relevant arithmatic */
578 CURRENT
->current_nr_sectors
=
579 (count
< (2 * MAX_16BIT
/ SECT_SIZE
)) ? count
: (2 * MAX_16BIT
/ SECT_SIZE
);
580 track
= block
/ ps2esdi_info
[drive
].sect
;
581 head
= track
% ps2esdi_info
[drive
].head
;
582 cylinder
= track
/ ps2esdi_info
[drive
].head
;
583 sector
= block
% ps2esdi_info
[drive
].sect
;
586 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME
, cylinder
, head
, sector
);
588 /* call the routine that actually fills out a command block */
589 ps2esdi_fill_cmd_block
591 (cmd
== READ
) ? CMD_READ
: CMD_WRITE
,
592 cylinder
, head
, sector
,
593 CURRENT
->current_nr_sectors
, drive
);
595 /* send the command block to the controller */
596 if (ps2esdi_out_cmd_blk(cmd_blk
)) {
597 printk("%s: Controller failed\n", DEVICE_NAME
);
598 if ((++CURRENT
->errors
) < MAX_RETRIES
)
599 return do_ps2esdi_request();
603 do_ps2esdi_request();
606 /* check for failure to put out the command block */
609 printk("%s: waiting for xfer\n", DEVICE_NAME
);
611 /* turn disk lights on */
615 } /* ps2esdi_readwrite */
617 /* fill out the command block */
618 static void ps2esdi_fill_cmd_block(u_short
* cmd_blk
, u_short cmd
,
619 u_short cyl
, u_short head
, u_short sector
, u_short length
, u_char drive
)
622 cmd_blk
[0] = (drive
<< 5) | cmd
;
624 cmd_blk
[2] = ((cyl
& 0x1f) << 11) | (head
<< 5) | sector
;
625 cmd_blk
[3] = (cyl
& 0x3E0) >> 5;
627 } /* fill out the command block */
629 /* write a command block to the controller */
630 static int ps2esdi_out_cmd_blk(u_short
* cmd_blk
)
636 /* enable interrupts */
637 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
639 /* do not write to the controller, if it is busy */
640 for (i
= jiffies
+ ESDI_STAT_TIMEOUT
; time_after(i
, jiffies
) && (inb(ESDI_STATUS
) &
644 printk("%s: i(1)=%d\n", DEVICE_NAME
, i
);
647 /* if device is still busy - then just time out */
648 if (inb(ESDI_STATUS
) & STATUS_BUSY
) {
649 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME
);
652 /* Set up the attention register in the controller */
653 outb(((*cmd_blk
) & 0xE0) | 1, ESDI_ATTN
);
656 printk("%s: sending %d words to controller\n", DEVICE_NAME
, (((*cmd_blk
) >> 14) + 1) << 1);
659 /* one by one send each word out */
660 for (i
= (((*cmd_blk
) >> 14) + 1) << 1; i
; i
--) {
661 status
= inb(ESDI_STATUS
);
662 for (j
= jiffies
+ ESDI_STAT_TIMEOUT
;
663 time_after(j
, jiffies
) && (status
& STATUS_BUSY
) &&
664 (status
& STATUS_CMD_INF
); status
= inb(ESDI_STATUS
));
665 if ((status
& (STATUS_BUSY
| STATUS_CMD_INF
)) == STATUS_BUSY
) {
667 printk("%s: sending %04X\n", DEVICE_NAME
, *cmd_blk
);
669 outw(*cmd_blk
++, ESDI_CMD_INT
);
671 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
672 DEVICE_NAME
, status
);
675 } /* send all words out */
677 } /* send out the commands */
680 /* prepare for dma - do all the necessary setup */
681 static void ps2esdi_prep_dma(char *buffer
, u_short length
, u_char dma_xmode
)
685 buffer
=(char *)virt_to_bus(buffer
);
688 printk("ps2esdi: b_wait: %p\n", CURRENT
->bh
->b_wait
);
692 outb(dma_arb_level
| DMA_MASK_CHAN
, PORT_DMA_FN
);
694 outb(dma_arb_level
| DMA_WRITE_ADDR
, PORT_DMA_FN
);
695 outb((u_int
) buffer
& (u_int
) 0xff, PORT_DMA_EX
);
696 outb(((u_int
) buffer
>> 8) & (u_int
) 0xff, PORT_DMA_EX
);
697 outb(((u_int
) buffer
>> 16) & (u_int
) 0xff, PORT_DMA_EX
);
699 outb(dma_arb_level
| DMA_WRITE_TC
, PORT_DMA_FN
);
700 tc
= (length
* SECT_SIZE
/ 2) - 1;
701 outb(tc
& 0xff, PORT_DMA_EX
);
702 outb((tc
>> 8) & 0xff, PORT_DMA_EX
);
704 outb(dma_arb_level
| DMA_WRITE_MODE
, PORT_DMA_FN
);
705 outb(dma_xmode
, PORT_DMA_EX
);
707 outb(dma_arb_level
| DMA_UNMASK_CHAN
, PORT_DMA_FN
);
711 } /* prepare for dma */
715 static void ps2esdi_interrupt_handler(int irq
, void *dev_id
,
716 struct pt_regs
*regs
)
720 if (inb(ESDI_STATUS
) & STATUS_INTR
) {
721 int_ret_code
= inb(ESDI_INTRPT
);
722 if (current_int_handler
) {
723 /* Disable adapter interrupts till processing is finished */
724 outb(CTRL_DISABLE_INTR
, ESDI_CONTROL
);
725 current_int_handler(int_ret_code
);
727 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME
);
733 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code
)
736 switch (int_ret_code
& 0xf) {
739 printk("%s: initial reset completed.\n", DEVICE_NAME
);
740 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
741 wake_up(&ps2esdi_int
);
744 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
746 printk("%s: status: %02x\n", DEVICE_NAME
, inb(ESDI_STATUS
));
749 printk("%s: initial reset handler received interrupt: %02X\n",
750 DEVICE_NAME
, int_ret_code
);
751 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
754 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
758 static void ps2esdi_geometry_int_handler(u_int int_ret_code
)
760 u_int status
, drive_num
;
764 drive_num
= int_ret_code
>> 5;
765 switch (int_ret_code
& 0xf) {
766 case INT_CMD_COMPLETE
:
767 for (i
= ESDI_TIMEOUT
; i
& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
768 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
769 printk("%s: timeout reading status word\n", DEVICE_NAME
);
770 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
773 status
= inw(ESDI_STT_INT
);
774 if ((status
& 0x1F) == CMD_GET_DEV_CONFIG
) {
775 #define REPLY_WORDS 5 /* we already read word 0 */
776 u_short reply
[REPLY_WORDS
];
778 if (ps2esdi_read_status_words((status
>> 8) - 1, REPLY_WORDS
, reply
)) {
780 printk("%s: Device Configuration Status for drive %u\n",
781 DEVICE_NAME
, drive_num
);
783 printk("%s: Spares/cyls: %u", DEVICE_NAME
, reply
[0] >> 8);
786 ("Config bits: %s%s%s%s%s\n",
787 (reply
[0] & CONFIG_IS
) ? "Invalid Secondary, " : "",
788 ((reply
[0] & CONFIG_ZD
) && !(reply
[0] & CONFIG_IS
))
789 ? "Zero Defect, " : "Defects Present, ",
790 (reply
[0] & CONFIG_SF
) ? "Skewed Format, " : "",
791 (reply
[0] & CONFIG_FR
) ? "Removable, " : "Non-Removable, ",
792 (reply
[0] & CONFIG_RT
) ? "No Retries" : "Retries");
794 rba
= reply
[1] | ((unsigned long) reply
[2] << 16);
795 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME
, rba
);
797 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
798 DEVICE_NAME
, reply
[3], reply
[4] >> 8, reply
[4] & 0xff);
800 if (!ps2esdi_info
[drive_num
].head
) {
801 ps2esdi_info
[drive_num
].head
= 64;
802 ps2esdi_info
[drive_num
].sect
= 32;
803 ps2esdi_info
[drive_num
].cyl
= rba
/ (64 * 32);
804 ps2esdi_info
[drive_num
].wpcom
= 0;
805 ps2esdi_info
[drive_num
].lzone
= ps2esdi_info
[drive_num
].cyl
;
806 ps2esdi_info
[drive_num
].ctl
= 8;
807 if (tp720esdi
) { /* store the retrieved parameters */
808 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
809 ps2esdi_info
[0].sect
= reply
[4] >> 8;
810 ps2esdi_info
[0].cyl
= reply
[3];
811 ps2esdi_info
[0].wpcom
= 0;
812 ps2esdi_info
[0].lzone
= reply
[3];
818 if (!ps2esdi_info
[drive_num
].head
) {
819 ps2esdi_info
[drive_num
].head
= reply
[4] & 0Xff;
820 ps2esdi_info
[drive_num
].sect
= reply
[4] >> 8;
821 ps2esdi_info
[drive_num
].cyl
= reply
[3];
822 ps2esdi_info
[drive_num
].wpcom
= 0;
823 ps2esdi_info
[drive_num
].lzone
= reply
[3];
824 if (tp720esdi
) { /* store the retrieved parameters */
825 ps2esdi_info
[0].head
= reply
[4] & 0Xff;
826 ps2esdi_info
[0].sect
= reply
[4] >> 8;
827 ps2esdi_info
[0].cyl
= reply
[3];
828 ps2esdi_info
[0].wpcom
= 0;
829 ps2esdi_info
[0].lzone
= reply
[3];
837 printk("%s: failed while getting device config\n", DEVICE_NAME
);
840 printk("%s: command %02X unknown by geometry handler\n",
841 DEVICE_NAME
, status
& 0x1f);
843 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
847 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
849 printk("%s: Device not available\n", DEVICE_NAME
);
853 case INT_CMD_ECC_RETRY
:
854 case INT_CMD_WARNING
:
858 case INT_CMD_BLK_ERR
:
859 /*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME
);
860 dump_cmd_complete_status(int_ret_code
);
861 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
864 printk("%s: Unknown interrupt reason: %02X\n",
865 DEVICE_NAME
, int_ret_code
& 0xf);
866 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
870 wake_up(&ps2esdi_int
);
872 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
876 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code
)
881 switch (int_ret_code
& 0x0f) {
882 case INT_TRANSFER_REQ
:
883 ps2esdi_prep_dma(CURRENT
->buffer
, CURRENT
->current_nr_sectors
,
884 (CURRENT
->cmd
== READ
) ? DMA_READ_16
: DMA_WRITE_16
);
885 outb(CTRL_ENABLE_DMA
| CTRL_ENABLE_INTR
, ESDI_CONTROL
);
889 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME
,
891 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
894 case INT_CMD_COMPLETE
:
895 for (i
= ESDI_TIMEOUT
; i
& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
896 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
897 printk("%s: timeout reading status word\n", DEVICE_NAME
);
898 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
899 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
900 if ((++CURRENT
->errors
) < MAX_RETRIES
)
901 do_ps2esdi_request();
905 do_ps2esdi_request();
909 status
= inw(ESDI_STT_INT
);
910 switch (status
& 0x1F) {
911 case (CMD_READ
& 0xff):
912 case (CMD_WRITE
& 0xff):
914 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
915 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
917 printk("ps2esdi: cmd_complete b_wait: %p\n", CURRENT
->bh
->b_wait
);
919 ps2esdi_continue_request();
922 printk("%s: interrupt for unknown command %02X\n",
923 DEVICE_NAME
, status
& 0x1f);
924 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
925 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
931 case INT_CMD_ECC_RETRY
:
933 dump_cmd_complete_status(int_ret_code
);
934 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
935 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
936 ps2esdi_continue_request();
938 case INT_CMD_WARNING
:
943 dump_cmd_complete_status(int_ret_code
);
944 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
945 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
946 if ((++CURRENT
->errors
) < MAX_RETRIES
)
947 do_ps2esdi_request();
951 do_ps2esdi_request();
955 case INT_CMD_BLK_ERR
:
956 dump_cmd_complete_status(int_ret_code
);
957 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
958 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
961 do_ps2esdi_request();
965 printk("%s: huh ? Who issued this format command ?\n"
967 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
968 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
972 /* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
973 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
974 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
978 printk("%s: Unknown interrupt reason: %02X\n",
979 DEVICE_NAME
, int_ret_code
& 0xf);
980 outb((int_ret_code
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
981 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
985 } /* handle interrupts */
988 static void ps2esdi_continue_request(void)
990 if (CURRENT
->nr_sectors
-= CURRENT
->current_nr_sectors
) {
991 CURRENT
->buffer
+= CURRENT
->current_nr_sectors
* SECT_SIZE
;
992 CURRENT
->sector
+= CURRENT
->current_nr_sectors
;
993 do_ps2esdi_request();
997 do_ps2esdi_request();
1003 static int ps2esdi_read_status_words(int num_words
,
1009 for (; max_words
&& num_words
; max_words
--, num_words
--, buffer
++) {
1010 for (i
= ESDI_TIMEOUT
; i
&& !(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
); i
--);
1011 if (!(inb(ESDI_STATUS
) & STATUS_STAT_AVAIL
)) {
1012 printk("%s: timeout reading status word\n", DEVICE_NAME
);
1015 *buffer
= inw(ESDI_STT_INT
);
1023 static void dump_cmd_complete_status(u_int int_ret_code
)
1025 #define WAIT_FOR_STATUS \
1026 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
1027 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
1028 printk("%s: timeout reading status word\n",DEVICE_NAME); \
1036 printk("%s: Device: %u, interrupt ID: %02X\n",
1037 DEVICE_NAME
, int_ret_code
>> 5,
1038 int_ret_code
& 0xf);
1041 stat_word
= inw(ESDI_STT_INT
);
1042 word_count
= (stat_word
>> 8) - 1;
1043 printk("%s: %u status words, command: %02X\n", DEVICE_NAME
, word_count
,
1048 stat_word
= inw(ESDI_STT_INT
);
1049 printk("%s: command status code: %02X, command error code: %02X\n",
1050 DEVICE_NAME
, stat_word
>> 8, stat_word
& 0xff);
1054 stat_word
= inw(ESDI_STT_INT
);
1055 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME
,
1056 (stat_word
& 0x1000) ? "Ready, " : "Not Ready, ",
1057 (stat_word
& 0x0800) ? "Selected, " : "Not Selected, ",
1058 (stat_word
& 0x0400) ? "Write Fault, " : "",
1059 (stat_word
& 0x0200) ? "Track 0, " : "",
1060 (stat_word
& 0x0100) ? "Seek or command complete, " : "",
1065 stat_word
= inw(ESDI_STT_INT
);
1066 printk("%s: Blocks to do: %u", DEVICE_NAME
, stat_word
);
1068 if (word_count
-= 2) {
1070 rba
= inw(ESDI_STT_INT
);
1072 rba
|= inw(ESDI_STT_INT
) << 16;
1073 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1074 (u_short
) ((rba
& 0x1ff80000) >> 11),
1075 (u_short
) ((rba
& 0x7E0) >> 5), (u_short
) (rba
& 0x1f));
1081 stat_word
= inw(ESDI_STT_INT
);
1082 printk("%s: Blocks required ECC: %u", DEVICE_NAME
, stat_word
);
1086 #undef WAIT_FOR_STATUS
1091 static int ps2esdi_open(struct inode
*inode
, struct file
*file
)
1093 int dev
= DEVICE_NR(inode
->i_rdev
);
1095 if (dev
< ps2esdi_drives
) {
1096 while (!ps2esdi_valid
[dev
])
1097 sleep_on(&ps2esdi_wait_open
);
1099 access_count
[dev
]++;
1108 static int ps2esdi_release(struct inode
*inode
, struct file
*file
)
1110 int dev
= DEVICE_NR(inode
->i_rdev
);
1112 if (dev
< ps2esdi_drives
) {
1113 sync_dev(inode
->i_rdev
);
1114 access_count
[dev
]--;
1121 static int ps2esdi_ioctl(struct inode
*inode
,
1122 struct file
*file
, u_int cmd
, u_long arg
)
1125 struct ps2esdi_geometry
*geometry
= (struct ps2esdi_geometry
*) arg
;
1126 int dev
= DEVICE_NR(inode
->i_rdev
), err
;
1128 if (inode
&& (dev
< ps2esdi_drives
))
1132 if ((err
= verify_area(VERIFY_WRITE
, geometry
, sizeof(*geometry
))))
1134 put_user(ps2esdi_info
[dev
].head
, (char *) &geometry
->heads
);
1135 put_user(ps2esdi_info
[dev
].sect
, (char *) &geometry
->sectors
);
1136 put_user(ps2esdi_info
[dev
].cyl
, (short *) &geometry
->cylinders
);
1137 put_user(ps2esdi
[MINOR(inode
->i_rdev
)].start_sect
,
1138 (long *) &geometry
->start
);
1144 if (!capable(CAP_SYS_ADMIN
))
1150 read_ahead
[MAJOR(inode
->i_rdev
)] = arg
;
1154 if ((err
= verify_area(VERIFY_WRITE
, (long *) arg
, sizeof(long))))
1156 put_user(ps2esdi
[MINOR(inode
->i_rdev
)].nr_sects
, (long *) arg
);
1162 if (!capable(CAP_SYS_ADMIN
))
1166 fsync_dev(inode
->i_rdev
);
1167 invalidate_buffers(inode
->i_rdev
);
1171 if (!capable(CAP_SYS_ADMIN
))
1173 return (ps2esdi_reread_partitions(inode
->i_rdev
));
1174 RO_IOCTLS(inode
->i_rdev
, arg
);
1181 static int ps2esdi_reread_partitions(kdev_t dev
)
1183 int target
= DEVICE_NR(dev
);
1184 int start
= target
<< ps2esdi_gendisk
.minor_shift
;
1188 ps2esdi_valid
[target
] = (access_count
[target
] != 1);
1190 if (ps2esdi_valid
[target
])
1193 for (partition
= ps2esdi_gendisk
.max_p
- 1;
1194 partition
>= 0; partition
--) {
1195 int minor
= (start
| partition
);
1196 kdev_t devp
= MKDEV(MAJOR_NR
, minor
);
1197 struct super_block
* sb
= get_super(devp
);
1201 invalidate_inodes(sb
);
1202 invalidate_buffers(devp
);
1203 ps2esdi_gendisk
.part
[start
+ partition
].start_sect
= 0;
1204 ps2esdi_gendisk
.part
[start
+ partition
].nr_sects
= 0;
1207 ps2esdi_gendisk
.part
[start
].nr_sects
= ps2esdi_info
[target
].head
*
1208 ps2esdi_info
[target
].cyl
* ps2esdi_info
[target
].sect
;
1209 resetup_one_dev(&ps2esdi_gendisk
, target
);
1211 ps2esdi_valid
[target
] = 1;
1212 wake_up(&ps2esdi_wait_open
);
1217 void ps2esdi_reset_timer(unsigned long unused
)
1222 status
= inb(ESDI_INTRPT
);
1223 if ((status
& 0xf) == INT_RESET
) {
1224 outb((status
& 0xe0) | ATT_EOI
, ESDI_ATTN
);
1225 outb(CTRL_ENABLE_INTR
, ESDI_CONTROL
);
1228 wake_up(&ps2esdi_int
);