2 * This file contains the driver for an XT hard disk controller
3 * (at least the DTC 5150X) for Linux.
5 * Author: Pat Mackinlay, pat@it.com.au
8 * Revised: 01/01/93, ...
10 * Ref: DTC 5150X Controller Specification (thanks to Kevin Fowler,
11 * kevinf@agora.rain.com)
12 * Also thanks to: Salvador Abreu, Dave Thaler, Risto Kankkunen and
15 * Revised: 04/04/94 by Risto Kankkunen
16 * Moved the detection code from xd_init() to xd_geninit() as it needed
17 * interrupts enabled and Linus didn't want to enable them in that first
18 * phase. xd_geninit() is the place to do these kinds of things anyway,
21 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
23 * Revised: 13/12/97 by Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl
24 * Fixed some problems with disk initialization and module initiation.
25 * Added support for manual geometry setting (except Seagate controllers)
27 * xd_geo=<cyl_xda>,<head_xda>,<sec_xda>[,<cyl_xdb>,<head_xdb>,<sec_xdb>]
28 * Recovered DMA access. Abridged messages. Added support for DTC5051CX,
29 * WD1002-27X & XEBEC controllers. Driver uses now some jumper settings.
30 * Extended ioctl() support.
32 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
36 #include <linux/module.h>
37 #include <linux/errno.h>
38 #include <linux/interrupt.h>
41 #include <linux/kernel.h>
42 #include <linux/timer.h>
43 #include <linux/genhd.h>
44 #include <linux/hdreg.h>
45 #include <linux/ioport.h>
46 #include <linux/init.h>
47 #include <linux/wait.h>
48 #include <linux/blkdev.h>
49 #include <linux/blkpg.h>
50 #include <linux/delay.h>
52 #include <asm/system.h>
54 #include <asm/uaccess.h>
59 static void __init
do_xd_setup (int *integers
);
61 static int xd
[5] = { -1,-1,-1,-1, };
64 #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
65 "nodma" module option */
66 #define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
68 /* Above may need to be increased if a problem with the 2nd drive detection
69 (ST11M controller) or resetting a controller (WD) appears */
71 static XD_INFO xd_info
[XD_MAXDRIVES
];
73 /* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
74 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
75 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
76 command. Run DEBUG, and then you can examine your BIOS signature with:
80 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
81 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
82 in the table are, in order:
84 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
85 signature ; this is the actual text of the signature
86 xd_?_init_controller ; this is the controller init routine used by your controller
87 xd_?_init_drive ; this is the drive init routine used by your controller
89 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
90 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
91 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
92 may work with your card. If none of these seem to work, try sending me some email and I'll see what I can do <grin>.
94 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
95 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
98 #define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
99 #define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
100 static char *xd_dma_buffer
;
102 static XD_SIGNATURE xd_sigs
[] __initdata
= {
103 { 0x0000,"Override geometry handler",NULL
,xd_override_init_drive
,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
104 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller
,xd_dtc5150cx_init_drive
," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
105 { 0x000B,"CRD18A Not an IBM rom. (C) Copyright Data Technology Corp. 05/31/88",xd_dtc_init_controller
,xd_dtc_init_drive
," DTC 5150X" }, /* Todd Fries, tfries@umr.edu */
106 { 0x000B,"CXD23A Not an IBM ROM (C)Copyright Data Technology Corp 12/03/88",xd_dtc_init_controller
,xd_dtc_init_drive
," DTC 5150X" }, /* Pat Mackinlay, pat@it.com.au */
107 { 0x0008,"07/15/86(C) Copyright 1986 Western Digital Corp.",xd_wd_init_controller
,xd_wd_init_drive
," Western Dig. 1002-27X" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
108 { 0x0008,"06/24/88(C) Copyright 1988 Western Digital Corp.",xd_wd_init_controller
,xd_wd_init_drive
," Western Dig. WDXT-GEN2" }, /* Dan Newcombe, newcombe@aa.csc.peachnet.edu */
109 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
110 { 0x0010,"ST11R BIOS",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
111 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller
,xd_seagate_init_drive
," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
112 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller
,xd_omti_init_drive
,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
113 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller
,xd_xebec_init_drive
," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
114 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller
, xd_wd_init_drive
," Western Dig. 1002s-wx2" },
115 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller
, xd_wd_init_drive
," 1986 Western Digital" }, /* jfree@sovereign.org */
118 static unsigned int xd_bases
[] __initdata
=
120 0xC8000, 0xCA000, 0xCC000,
121 0xCE000, 0xD0000, 0xD2000,
122 0xD4000, 0xD6000, 0xD8000,
123 0xDA000, 0xDC000, 0xDE000,
127 static DEFINE_SPINLOCK(xd_lock
);
129 static struct gendisk
*xd_gendisk
[2];
131 static struct block_device_operations xd_fops
= {
132 .owner
= THIS_MODULE
,
135 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int
);
136 static u_char xd_drives
, xd_irq
= 5, xd_dma
= 3, xd_maxsectors
;
137 static u_char xd_override __initdata
= 0, xd_type __initdata
= 0;
138 static u_short xd_iobase
= 0x320;
139 static int xd_geo
[XD_MAXDRIVES
*3] __initdata
= { 0, };
141 static volatile int xdc_busy
;
142 static struct timer_list xd_watchdog_int
;
144 static volatile u_char xd_error
;
145 static int nodma
= XD_DONT_USE_DMA
;
147 static struct request_queue
*xd_queue
;
149 /* xd_init: register the block device number and set up pointer tables */
150 static int __init
xd_init(void)
153 unsigned int address
;
159 for (i
= 4; i
> 0; i
--)
160 if (((xd
[i
] = xd
[i
-1]) >= 0) && !count
)
167 init_timer (&xd_watchdog_int
); xd_watchdog_int
.function
= xd_watchdog
;
170 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
171 if (!xd_dma_buffer
) {
172 printk(KERN_ERR
"xd: Out of memory.\n");
177 if (register_blkdev(XT_DISK_MAJOR
, "xd"))
181 xd_queue
= blk_init_queue(do_xd_request
, &xd_lock
);
185 if (xd_detect(&controller
,&address
)) {
187 printk("Detected a%s controller (type %d) at address %06x\n",
188 xd_sigs
[controller
].name
,controller
,address
);
189 if (!request_region(xd_iobase
,4,"xd")) {
190 printk("xd: Ports at 0x%x are not available\n",
195 xd_sigs
[controller
].init_controller(address
);
196 xd_drives
= xd_initdrives(xd_sigs
[controller
].init_drive
);
198 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
199 xd_drives
,xd_drives
== 1 ? "" : "s",xd_irq
,xd_dma
);
206 for (i
= 0; i
< xd_drives
; i
++) {
207 XD_INFO
*p
= &xd_info
[i
];
208 struct gendisk
*disk
= alloc_disk(64);
212 disk
->major
= XT_DISK_MAJOR
;
213 disk
->first_minor
= i
<<6;
214 sprintf(disk
->disk_name
, "xd%c", i
+'a');
215 sprintf(disk
->devfs_name
, "xd/target%d", i
);
216 disk
->fops
= &xd_fops
;
217 disk
->private_data
= p
;
218 disk
->queue
= xd_queue
;
219 set_capacity(disk
, p
->heads
* p
->cylinders
* p
->sectors
);
220 printk(" %s: CHS=%d/%d/%d\n", disk
->disk_name
,
221 p
->cylinders
, p
->heads
, p
->sectors
);
222 xd_gendisk
[i
] = disk
;
226 if (request_irq(xd_irq
,xd_interrupt_handler
, 0, "XT hard disk", NULL
)) {
227 printk("xd: unable to get IRQ%d\n",xd_irq
);
231 if (request_dma(xd_dma
,"xd")) {
232 printk("xd: unable to get DMA%d\n",xd_dma
);
236 /* xd_maxsectors depends on controller - so set after detection */
237 blk_queue_max_sectors(xd_queue
, xd_maxsectors
);
239 for (i
= 0; i
< xd_drives
; i
++)
240 add_disk(xd_gendisk
[i
]);
245 free_irq(xd_irq
, NULL
);
247 for (i
= 0; i
< xd_drives
; i
++)
248 put_disk(xd_gendisk
[i
]);
250 release_region(xd_iobase
,4);
252 blk_cleanup_queue(xd_queue
);
254 unregister_blkdev(XT_DISK_MAJOR
, "xd");
257 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
258 xd_maxsectors
* 0x200);
263 put_disk(xd_gendisk
[i
]);
267 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
268 static u_char __init
xd_detect (u_char
*controller
, unsigned int *address
)
274 *controller
= xd_type
;
279 for (i
= 0; i
< (sizeof(xd_bases
) / sizeof(xd_bases
[0])); i
++) {
280 void __iomem
*p
= ioremap(xd_bases
[i
], 0x2000);
283 for (j
= 1; j
< (sizeof(xd_sigs
) / sizeof(xd_sigs
[0])); j
++) {
284 const char *s
= xd_sigs
[j
].string
;
285 if (check_signature(p
+ xd_sigs
[j
].offset
, s
, strlen(s
))) {
288 *address
= xd_bases
[i
];
298 /* do_xd_request: handle an incoming request */
299 static void do_xd_request (request_queue_t
* q
)
306 while ((req
= elv_next_request(q
)) != NULL
) {
307 unsigned block
= req
->sector
;
308 unsigned count
= req
->nr_sectors
;
309 int rw
= rq_data_dir(req
);
310 XD_INFO
*disk
= req
->rq_disk
->private_data
;
314 if (!(req
->flags
& REQ_CMD
)) {
318 if (block
+ count
> get_capacity(req
->rq_disk
)) {
322 if (rw
!= READ
&& rw
!= WRITE
) {
323 printk("do_xd_request: unknown request\n");
327 for (retry
= 0; (retry
< XD_RETRIES
) && !res
; retry
++)
328 res
= xd_readwrite(rw
, disk
, req
->buffer
, block
, count
);
329 end_request(req
, res
); /* wrap up, 0 = fail, 1 = success */
333 /* xd_ioctl: handle device ioctl's */
334 static int xd_ioctl (struct inode
*inode
,struct file
*file
,u_int cmd
,u_long arg
)
336 XD_INFO
*p
= inode
->i_bdev
->bd_disk
->private_data
;
341 struct hd_geometry g
;
342 struct hd_geometry __user
*geom
= (void __user
*)arg
;
344 g
.sectors
= p
->sectors
;
345 g
.cylinders
= p
->cylinders
;
346 g
.start
= get_start_sect(inode
->i_bdev
);
347 return copy_to_user(geom
, &g
, sizeof(g
)) ? -EFAULT
: 0;
350 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
351 if (xdc_busy
) return -EBUSY
;
353 if (nodma
&& xd_dma_buffer
) {
354 xd_dma_mem_free((unsigned long)xd_dma_buffer
,
355 xd_maxsectors
* 0x200);
356 xd_dma_buffer
= NULL
;
357 } else if (!nodma
&& !xd_dma_buffer
) {
358 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
359 if (!xd_dma_buffer
) {
360 nodma
= XD_DONT_USE_DMA
;
366 return put_user(!nodma
, (long __user
*) arg
);
367 case HDIO_GET_MULTCOUNT
:
368 return put_user(xd_maxsectors
, (long __user
*) arg
);
374 /* xd_readwrite: handle a read/write request */
375 static int xd_readwrite (u_char operation
,XD_INFO
*p
,char *buffer
,u_int block
,u_int count
)
378 u_char cmdblk
[6],sense
[4];
379 u_short track
,cylinder
;
380 u_char head
,sector
,control
,mode
= PIO_MODE
,temp
;
384 #ifdef DEBUG_READWRITE
385 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation
== READ
? "read" : "write",drive
,buffer
,block
,count
);
386 #endif /* DEBUG_READWRITE */
388 spin_unlock_irq(&xd_lock
);
390 control
= p
->control
;
392 xd_dma_buffer
= (char *)xd_dma_mem_alloc(xd_maxsectors
* 0x200);
394 temp
= count
< xd_maxsectors
? count
: xd_maxsectors
;
396 track
= block
/ p
->sectors
;
397 head
= track
% p
->heads
;
398 cylinder
= track
/ p
->heads
;
399 sector
= block
% p
->sectors
;
401 #ifdef DEBUG_READWRITE
402 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive
,head
,cylinder
,sector
,temp
);
403 #endif /* DEBUG_READWRITE */
406 mode
= xd_setup_dma(operation
== READ
? DMA_MODE_READ
: DMA_MODE_WRITE
,(u_char
*)(xd_dma_buffer
),temp
* 0x200);
407 real_buffer
= &xd_dma_buffer
;
408 for (i
=0; i
< (temp
* 0x200); i
++)
409 xd_dma_buffer
[i
] = buffer
[i
];
412 real_buffer
= &buffer
;
414 xd_build(cmdblk
,operation
== READ
? CMD_READ
: CMD_WRITE
,drive
,head
,cylinder
,sector
,temp
& 0xFF,control
);
416 switch (xd_command(cmdblk
,mode
,(u_char
*)(*real_buffer
),(u_char
*)(*real_buffer
),sense
,XD_TIMEOUT
)) {
418 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive
,(operation
== READ
? "read" : "write"));
419 xd_recalibrate(drive
);
420 spin_lock_irq(&xd_lock
);
423 if (sense
[0] & 0x30) {
424 printk("xd%c: %s - ",'a'+drive
,(operation
== READ
? "reading" : "writing"));
425 switch ((sense
[0] & 0x30) >> 4) {
426 case 0: printk("drive error, code = 0x%X",sense
[0] & 0x0F);
428 case 1: printk("controller error, code = 0x%X",sense
[0] & 0x0F);
430 case 2: printk("command error, code = 0x%X",sense
[0] & 0x0F);
432 case 3: printk("miscellaneous error, code = 0x%X",sense
[0] & 0x0F);
437 printk(" - CHS = %d/%d/%d\n",((sense
[2] & 0xC0) << 2) | sense
[3],sense
[1] & 0x1F,sense
[2] & 0x3F);
438 /* reported drive number = (sense[1] & 0xE0) >> 5 */
440 printk(" - no valid disk address\n");
441 spin_lock_irq(&xd_lock
);
445 for (i
=0; i
< (temp
* 0x200); i
++)
446 buffer
[i
] = xd_dma_buffer
[i
];
448 count
-= temp
, buffer
+= temp
* 0x200, block
+= temp
;
450 spin_lock_irq(&xd_lock
);
454 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
455 static void xd_recalibrate (u_char drive
)
459 xd_build(cmdblk
,CMD_RECALIBRATE
,drive
,0,0,0,0,0);
460 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 8))
461 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive
);
464 /* xd_interrupt_handler: interrupt service routine */
465 static irqreturn_t
xd_interrupt_handler(int irq
, void *dev_id
,
466 struct pt_regs
*regs
)
468 if (inb(XD_STATUS
) & STAT_INTERRUPT
) { /* check if it was our device */
470 printk("xd_interrupt_handler: interrupt detected\n");
471 #endif /* DEBUG_OTHER */
472 outb(0,XD_CONTROL
); /* acknowledge interrupt */
473 wake_up(&xd_wait_int
); /* and wake up sleeping processes */
477 printk("xd: unexpected interrupt\n");
481 /* xd_setup_dma: set up the DMA controller for a data transfer */
482 static u_char
xd_setup_dma (u_char mode
,u_char
*buffer
,u_int count
)
488 if (((unsigned long) buffer
& 0xFFFF0000) != (((unsigned long) buffer
+ count
) & 0xFFFF0000)) {
490 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
491 #endif /* DEBUG_OTHER */
497 clear_dma_ff(xd_dma
);
498 set_dma_mode(xd_dma
,mode
);
499 set_dma_addr(xd_dma
, (unsigned long) buffer
);
500 set_dma_count(xd_dma
,count
);
504 return (DMA_MODE
); /* use DMA and INT */
507 /* xd_build: put stuff into an array in a format suitable for the controller */
508 static u_char
*xd_build (u_char
*cmdblk
,u_char command
,u_char drive
,u_char head
,u_short cylinder
,u_char sector
,u_char count
,u_char control
)
511 cmdblk
[1] = ((drive
& 0x07) << 5) | (head
& 0x1F);
512 cmdblk
[2] = ((cylinder
& 0x300) >> 2) | (sector
& 0x3F);
513 cmdblk
[3] = cylinder
& 0xFF;
520 static void xd_watchdog (unsigned long unused
)
523 wake_up(&xd_wait_int
);
526 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
527 static inline u_char
xd_waitport (u_short port
,u_char flags
,u_char mask
,u_long timeout
)
529 u_long expiry
= jiffies
+ timeout
;
533 while ((success
= ((inb(port
) & mask
) != flags
)) && time_before(jiffies
, expiry
)) {
534 set_current_state(TASK_UNINTERRUPTIBLE
);
541 static inline u_int
xd_wait_for_IRQ (void)
544 xd_watchdog_int
.expires
= jiffies
+ 8 * HZ
;
545 add_timer(&xd_watchdog_int
);
547 flags
=claim_dma_lock();
549 release_dma_lock(flags
);
551 sleep_on(&xd_wait_int
);
552 del_timer(&xd_watchdog_int
);
555 flags
=claim_dma_lock();
557 release_dma_lock(flags
);
560 printk("xd: missed IRQ - command aborted\n");
567 /* xd_command: handle all data transfers necessary for a single command */
568 static u_int
xd_command (u_char
*command
,u_char mode
,u_char
*indata
,u_char
*outdata
,u_char
*sense
,u_long timeout
)
570 u_char cmdblk
[6],csb
,complete
= 0;
573 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command
,mode
,indata
,outdata
,sense
);
574 #endif /* DEBUG_COMMAND */
577 outb(mode
,XD_CONTROL
);
579 if (xd_waitport(XD_STATUS
,STAT_SELECT
,STAT_SELECT
,timeout
))
583 if (xd_waitport(XD_STATUS
,STAT_READY
,STAT_READY
,timeout
))
586 switch (inb(XD_STATUS
) & (STAT_COMMAND
| STAT_INPUT
)) {
588 if (mode
== DMA_MODE
) {
589 if (xd_wait_for_IRQ())
592 outb(outdata
? *outdata
++ : 0,XD_DATA
);
595 if (mode
== DMA_MODE
) {
596 if (xd_wait_for_IRQ())
600 *indata
++ = inb(XD_DATA
);
605 outb(command
? *command
++ : 0,XD_DATA
);
607 case STAT_COMMAND
| STAT_INPUT
:
614 if (xd_waitport(XD_STATUS
,0,STAT_SELECT
,timeout
)) /* wait until deselected */
617 if (csb
& CSB_ERROR
) { /* read sense data if error */
618 xd_build(cmdblk
,CMD_SENSE
,(csb
& CSB_LUN
) >> 5,0,0,0,0,0);
619 if (xd_command(cmdblk
,0,sense
,NULL
,NULL
,XD_TIMEOUT
))
620 printk("xd: warning! sense command failed!\n");
624 printk("xd_command: completed with csb = 0x%X\n",csb
);
625 #endif /* DEBUG_COMMAND */
627 return (csb
& CSB_ERROR
);
630 static u_char __init
xd_initdrives (void (*init_drive
)(u_char drive
))
632 u_char cmdblk
[6],i
,count
= 0;
634 for (i
= 0; i
< XD_MAXDRIVES
; i
++) {
635 xd_build(cmdblk
,CMD_TESTREADY
,i
,0,0,0,0,0);
636 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
*8)) {
637 msleep_interruptible(XD_INIT_DISK_DELAY
);
642 msleep_interruptible(XD_INIT_DISK_DELAY
);
648 static void __init
xd_manual_geo_set (u_char drive
)
650 xd_info
[drive
].heads
= (u_char
)(xd_geo
[3 * drive
+ 1]);
651 xd_info
[drive
].cylinders
= (u_short
)(xd_geo
[3 * drive
]);
652 xd_info
[drive
].sectors
= (u_char
)(xd_geo
[3 * drive
+ 2]);
655 static void __init
xd_dtc_init_controller (unsigned int address
)
659 case 0xC8000: break; /*initial: 0x320 */
660 case 0xCA000: xd_iobase
= 0x324;
661 case 0xD0000: /*5150CX*/
662 case 0xD8000: break; /*5150CX & 5150XL*/
663 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address
);
666 xd_maxsectors
= 0x01; /* my card seems to have trouble doing multi-block transfers? */
668 outb(0,XD_RESET
); /* reset the controller */
672 static void __init
xd_dtc5150cx_init_drive (u_char drive
)
674 /* values from controller's BIOS - BIOS chip may be removed */
675 static u_short geometry_table
[][4] = {
676 {0x200,8,0x200,0x100},
677 {0x267,2,0x267,0x267},
678 {0x264,4,0x264,0x80},
680 {0x132,2,0x80, 0x132},
684 {0x132,6,0x80, 0x100},
685 {0x200,6,0x100,0x100},
686 {0x264,2,0x264,0x80},
687 {0x280,4,0x280,0x100},
688 {0x2B9,3,0x2B9,0x2B9},
689 {0x2B9,5,0x2B9,0x2B9},
690 {0x280,6,0x280,0x100},
691 {0x132,4,0x132,0x0}};
695 n
= (drive
? n
: (n
>> 2)) & 0x33;
696 n
= (n
| (n
>> 2)) & 0x0F;
698 xd_manual_geo_set(drive
);
701 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
702 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
703 xd_info
[drive
].sectors
= 17; /* sectors */
705 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
706 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
707 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
711 printk("xd%c: undetermined drive geometry\n",'a'+drive
);
714 xd_info
[drive
].control
= 5; /* control byte */
715 xd_setparam(CMD_DTCSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
716 xd_recalibrate(drive
);
719 static void __init
xd_dtc_init_drive (u_char drive
)
721 u_char cmdblk
[6],buf
[64];
723 xd_build(cmdblk
,CMD_DTCGETGEOM
,drive
,0,0,0,0,0);
724 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
725 xd_info
[drive
].heads
= buf
[0x0A]; /* heads */
726 xd_info
[drive
].cylinders
= ((u_short
*) (buf
))[0x04]; /* cylinders */
727 xd_info
[drive
].sectors
= 17; /* sectors */
729 xd_manual_geo_set(drive
);
731 xd_info
[drive
].rwrite
= ((u_short
*) (buf
+ 1))[0x05]; /* reduced write */
732 xd_info
[drive
].precomp
= ((u_short
*) (buf
+ 1))[0x06]; /* write precomp */
733 xd_info
[drive
].ecc
= buf
[0x0F]; /* ecc length */
735 xd_info
[drive
].control
= 0; /* control byte */
737 xd_setparam(CMD_DTCSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,((u_short
*) (buf
+ 1))[0x05],((u_short
*) (buf
+ 1))[0x06],buf
[0x0F]);
738 xd_build(cmdblk
,CMD_DTCSETSTEP
,drive
,0,0,0,0,7);
739 if (xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
740 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive
);
743 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive
);
746 static void __init
xd_wd_init_controller (unsigned int address
)
750 case 0xC8000: break; /*initial: 0x320 */
751 case 0xCA000: xd_iobase
= 0x324; break;
752 case 0xCC000: xd_iobase
= 0x328; break;
753 case 0xCE000: xd_iobase
= 0x32C; break;
754 case 0xD0000: xd_iobase
= 0x328; break; /* ? */
755 case 0xD8000: xd_iobase
= 0x32C; break; /* ? */
756 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address
);
759 xd_maxsectors
= 0x01; /* this one doesn't wrap properly either... */
761 outb(0,XD_RESET
); /* reset the controller */
763 msleep(XD_INIT_DISK_DELAY
);
766 static void __init
xd_wd_init_drive (u_char drive
)
768 /* values from controller's BIOS - BIOS may be disabled */
769 static u_short geometry_table
[][4] = {
770 {0x264,4,0x1C2,0x1C2}, /* common part */
772 {0x267,2,0x1C2,0x1C2},
773 {0x267,4,0x1C2,0x1C2},
775 {0x334,6,0x335,0x335}, /* 1004 series RLL */
776 {0x30E,4,0x30F,0x3DC},
777 {0x30E,2,0x30F,0x30F},
778 {0x267,4,0x268,0x268},
780 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
781 {0x3DB,7,0x3DC,0x3DC},
782 {0x264,4,0x265,0x265},
783 {0x267,4,0x268,0x268}};
785 u_char cmdblk
[6],buf
[0x200];
786 u_char n
= 0,rll
,jumper_state
,use_jumper_geo
;
787 u_char wd_1002
= (xd_sigs
[xd_type
].string
[7] == '6');
789 jumper_state
= ~(inb(0x322));
790 if (jumper_state
& 0x40)
792 rll
= (jumper_state
& 0x30) ? (0x04 << wd_1002
) : 0;
793 xd_build(cmdblk
,CMD_READ
,drive
,0,0,0,1,0);
794 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
795 xd_info
[drive
].heads
= buf
[0x1AF]; /* heads */
796 xd_info
[drive
].cylinders
= ((u_short
*) (buf
+ 1))[0xD6]; /* cylinders */
797 xd_info
[drive
].sectors
= 17; /* sectors */
799 xd_manual_geo_set(drive
);
801 xd_info
[drive
].rwrite
= ((u_short
*) (buf
))[0xD8]; /* reduced write */
802 xd_info
[drive
].wprecomp
= ((u_short
*) (buf
))[0xDA]; /* write precomp */
803 xd_info
[drive
].ecc
= buf
[0x1B4]; /* ecc length */
805 xd_info
[drive
].control
= buf
[0x1B5]; /* control byte */
806 use_jumper_geo
= !(xd_info
[drive
].heads
) || !(xd_info
[drive
].cylinders
);
807 if (xd_geo
[3*drive
]) {
808 xd_manual_geo_set(drive
);
809 xd_info
[drive
].control
= rll
? 7 : 5;
811 else if (use_jumper_geo
) {
812 n
= (((jumper_state
& 0x0F) >> (drive
<< 1)) & 0x03) | rll
;
813 xd_info
[drive
].cylinders
= geometry_table
[n
][0];
814 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]);
815 xd_info
[drive
].control
= rll
? 7 : 5;
817 xd_info
[drive
].rwrite
= geometry_table
[n
][2];
818 xd_info
[drive
].wprecomp
= geometry_table
[n
][3];
819 xd_info
[drive
].ecc
= 0x0B;
824 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
825 geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
827 xd_setparam(CMD_WDSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,
828 ((u_short
*) (buf
))[0xD8],((u_short
*) (buf
))[0xDA],buf
[0x1B4]);
830 /* 1002 based RLL controller requests converted addressing, but reports physical
831 (physical 26 sec., logical 17 sec.)
834 if ((xd_info
[drive
].cylinders
*= 26,
835 xd_info
[drive
].cylinders
/= 17) > 1023)
836 xd_info
[drive
].cylinders
= 1023; /* 1024 ? */
838 xd_info
[drive
].rwrite
*= 26;
839 xd_info
[drive
].rwrite
/= 17;
840 xd_info
[drive
].wprecomp
*= 26
841 xd_info
[drive
].wprecomp
/= 17;
846 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive
);
850 static void __init
xd_seagate_init_controller (unsigned int address
)
854 case 0xC8000: break; /*initial: 0x320 */
855 case 0xD0000: xd_iobase
= 0x324; break;
856 case 0xD8000: xd_iobase
= 0x328; break;
857 case 0xE0000: xd_iobase
= 0x32C; break;
858 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address
);
861 xd_maxsectors
= 0x40;
863 outb(0,XD_RESET
); /* reset the controller */
866 static void __init
xd_seagate_init_drive (u_char drive
)
868 u_char cmdblk
[6],buf
[0x200];
870 xd_build(cmdblk
,CMD_ST11GETGEOM
,drive
,0,0,0,1,0);
871 if (!xd_command(cmdblk
,PIO_MODE
,buf
,NULL
,NULL
,XD_TIMEOUT
* 2)) {
872 xd_info
[drive
].heads
= buf
[0x04]; /* heads */
873 xd_info
[drive
].cylinders
= (buf
[0x02] << 8) | buf
[0x03]; /* cylinders */
874 xd_info
[drive
].sectors
= buf
[0x05]; /* sectors */
875 xd_info
[drive
].control
= 0; /* control byte */
878 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive
);
881 /* Omti support courtesy Dirk Melchers */
882 static void __init
xd_omti_init_controller (unsigned int address
)
886 case 0xC8000: break; /*initial: 0x320 */
887 case 0xD0000: xd_iobase
= 0x324; break;
888 case 0xD8000: xd_iobase
= 0x328; break;
889 case 0xE0000: xd_iobase
= 0x32C; break;
890 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address
);
894 xd_maxsectors
= 0x40;
896 outb(0,XD_RESET
); /* reset the controller */
899 static void __init
xd_omti_init_drive (u_char drive
)
901 /* gets infos from drive */
902 xd_override_init_drive(drive
);
904 /* set other parameters, Hardcoded, not that nice :-) */
905 xd_info
[drive
].control
= 2;
908 /* Xebec support (AK) */
909 static void __init
xd_xebec_init_controller (unsigned int address
)
911 /* iobase may be set manually in range 0x300 - 0x33C
912 irq may be set manually to 2(9),3,4,5,6,7
913 dma may be set manually to 1,2,3
914 (How to detect them ???)
915 BIOS address may be set manually in range 0x0 - 0xF8000
916 If you need non-standard settings use the xd=... command */
920 case 0xC8000: /* initially: xd_iobase==0x320 */
930 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address
);
934 xd_maxsectors
= 0x01;
935 outb(0,XD_RESET
); /* reset the controller */
937 msleep(XD_INIT_DISK_DELAY
);
940 static void __init
xd_xebec_init_drive (u_char drive
)
942 /* values from controller's BIOS - BIOS chip may be removed */
943 static u_short geometry_table
[][5] = {
944 {0x132,4,0x080,0x080,0x7},
945 {0x132,4,0x080,0x080,0x17},
946 {0x264,2,0x100,0x100,0x7},
947 {0x264,2,0x100,0x100,0x17},
948 {0x132,8,0x080,0x080,0x7},
949 {0x132,8,0x080,0x080,0x17},
950 {0x264,4,0x100,0x100,0x6},
951 {0x264,4,0x100,0x100,0x17},
952 {0x2BC,5,0x2BC,0x12C,0x6},
953 {0x3A5,4,0x3A5,0x3A5,0x7},
954 {0x26C,6,0x26C,0x26C,0x7},
955 {0x200,8,0x200,0x100,0x17},
956 {0x400,5,0x400,0x400,0x7},
957 {0x400,6,0x400,0x400,0x7},
958 {0x264,8,0x264,0x200,0x17},
959 {0x33E,7,0x33E,0x200,0x7}};
962 n
= inb(XD_JUMPER
) & 0x0F; /* BIOS's drive number: same geometry
963 is assumed for BOTH drives */
965 xd_manual_geo_set(drive
);
967 xd_info
[drive
].heads
= (u_char
)(geometry_table
[n
][1]); /* heads */
968 xd_info
[drive
].cylinders
= geometry_table
[n
][0]; /* cylinders */
969 xd_info
[drive
].sectors
= 17; /* sectors */
971 xd_info
[drive
].rwrite
= geometry_table
[n
][2]; /* reduced write */
972 xd_info
[drive
].precomp
= geometry_table
[n
][3] /* write precomp */
973 xd_info
[drive
].ecc
= 0x0B; /* ecc length */
976 xd_info
[drive
].control
= geometry_table
[n
][4]; /* control byte */
977 xd_setparam(CMD_XBSETPARAM
,drive
,xd_info
[drive
].heads
,xd_info
[drive
].cylinders
,geometry_table
[n
][2],geometry_table
[n
][3],0x0B);
978 xd_recalibrate(drive
);
981 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
982 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
983 static void __init
xd_override_init_drive (u_char drive
)
985 u_short min
[] = { 0,0,0 },max
[] = { 16,1024,64 },test
[] = { 0,0,0 };
989 xd_manual_geo_set(drive
);
991 for (i
= 0; i
< 3; i
++) {
992 while (min
[i
] != max
[i
] - 1) {
993 test
[i
] = (min
[i
] + max
[i
]) / 2;
994 xd_build(cmdblk
,CMD_SEEK
,drive
,(u_char
) test
[0],(u_short
) test
[1],(u_char
) test
[2],0,0);
995 if (!xd_command(cmdblk
,PIO_MODE
,NULL
,NULL
,NULL
,XD_TIMEOUT
* 2))
1002 xd_info
[drive
].heads
= (u_char
) min
[0] + 1;
1003 xd_info
[drive
].cylinders
= (u_short
) min
[1] + 1;
1004 xd_info
[drive
].sectors
= (u_char
) min
[2] + 1;
1006 xd_info
[drive
].control
= 0;
1009 /* xd_setup: initialise controller from command line parameters */
1010 static void __init
do_xd_setup (int *integers
)
1012 switch (integers
[0]) {
1013 case 4: if (integers
[4] < 0)
1015 else if (integers
[4] < 8)
1016 xd_dma
= integers
[4];
1017 case 3: if ((integers
[3] > 0) && (integers
[3] <= 0x3FC))
1018 xd_iobase
= integers
[3];
1019 case 2: if ((integers
[2] > 0) && (integers
[2] < 16))
1020 xd_irq
= integers
[2];
1021 case 1: xd_override
= 1;
1022 if ((integers
[1] >= 0) && (integers
[1] < (sizeof(xd_sigs
) / sizeof(xd_sigs
[0]))))
1023 xd_type
= integers
[1];
1025 default:printk("xd: too many parameters for xd\n");
1027 xd_maxsectors
= 0x01;
1030 /* xd_setparam: set the drive characteristics */
1031 static void __init
xd_setparam (u_char command
,u_char drive
,u_char heads
,u_short cylinders
,u_short rwrite
,u_short wprecomp
,u_char ecc
)
1035 xd_build(cmdblk
,command
,drive
,0,0,0,0,0);
1036 cmdblk
[6] = (u_char
) (cylinders
>> 8) & 0x03;
1037 cmdblk
[7] = (u_char
) (cylinders
& 0xFF);
1038 cmdblk
[8] = heads
& 0x1F;
1039 cmdblk
[9] = (u_char
) (rwrite
>> 8) & 0x03;
1040 cmdblk
[10] = (u_char
) (rwrite
& 0xFF);
1041 cmdblk
[11] = (u_char
) (wprecomp
>> 8) & 0x03;
1042 cmdblk
[12] = (u_char
) (wprecomp
& 0xFF);
1045 /* Some controllers require geometry info as data, not command */
1047 if (xd_command(cmdblk
,PIO_MODE
,NULL
,&cmdblk
[6],NULL
,XD_TIMEOUT
* 2))
1048 printk("xd: error setting characteristics for xd%c\n", 'a'+drive
);
1054 module_param_array(xd
, int, NULL
, 0);
1055 module_param_array(xd_geo
, int, NULL
, 0);
1056 module_param(nodma
, bool, 0);
1058 MODULE_LICENSE("GPL");
1060 void cleanup_module(void)
1063 unregister_blkdev(XT_DISK_MAJOR
, "xd");
1064 for (i
= 0; i
< xd_drives
; i
++) {
1065 del_gendisk(xd_gendisk
[i
]);
1066 put_disk(xd_gendisk
[i
]);
1068 blk_cleanup_queue(xd_queue
);
1069 release_region(xd_iobase
,4);
1071 free_irq(xd_irq
, NULL
);
1074 xd_dma_mem_free((unsigned long)xd_dma_buffer
, xd_maxsectors
* 0x200);
1079 static int __init
xd_setup (char *str
)
1082 get_options (str
, ARRAY_SIZE (ints
), ints
);
1087 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1088 (used only for WD drives) */
1089 static int __init
xd_manual_geo_init (char *str
)
1091 int i
, integers
[1 + 3*XD_MAXDRIVES
];
1093 get_options (str
, ARRAY_SIZE (integers
), integers
);
1094 if (integers
[0]%3 != 0) {
1095 printk("xd: incorrect number of parameters for xd_geo\n");
1098 for (i
= 0; (i
< integers
[0]) && (i
< 3*XD_MAXDRIVES
); i
++)
1099 xd_geo
[i
] = integers
[i
+1];
1103 __setup ("xd=", xd_setup
);
1104 __setup ("xd_geo=", xd_manual_geo_init
);
1108 module_init(xd_init
);
1109 MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR
);