Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / drivers / block / xd.c
blob227518517812d1ca7d6feb152b7a3af76f25b2ac
1 /*
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
6 * Date: 29/09/92
7 *
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
13 * Wim Van Dorst.
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,
19 * he says.
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)
26 * in form:
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>
39 #include <linux/mm.h>
40 #include <linux/fs.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/devfs_fs_kernel.h>
50 #include <asm/system.h>
51 #include <asm/io.h>
52 #include <asm/uaccess.h>
53 #include <asm/dma.h>
55 #define MAJOR_NR XT_DISK_MAJOR
56 #include <linux/blk.h>
57 #include <linux/blkpg.h>
59 #include "xd.h"
61 static void __init do_xd_setup (int *integers);
62 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*HZ/1000) /* 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 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:
78 d xxxx:0000
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"). */
97 #include <asm/page.h>
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 = 0;
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,
124 0xE0000
127 static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
129 static struct gendisk *xd_gendisk[2];
131 static struct block_device_operations xd_fops = {
132 .owner = THIS_MODULE,
133 .ioctl = xd_ioctl,
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 static devfs_handle_t devfs_handle = NULL;
151 /* xd_init: register the block device number and set up pointer tables */
152 static int __init xd_init(void)
154 u_char i,controller;
155 u_char count = 0;
156 unsigned int address;
157 int err;
159 #ifdef MODULE
160 for (i = 4; i > 0; i--)
161 if(((xd[i] = xd[i-1]) >= 0) && !count)
162 count = i;
163 if((xd[0] = count))
164 do_xd_setup(xd);
165 #endif
167 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
169 if (!xd_dma_buffer)
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");
173 return -ENOMEM;
176 err = -EBUSY;
177 if (register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
178 printk("xd: Unable to get major number %d\n",MAJOR_NR);
179 goto out1;
181 devfs_handle = devfs_mk_dir (NULL, "xd", NULL);
182 blk_init_queue(&xd_queue, do_xd_request, &xd_lock);
183 if (xd_detect(&controller,&address)) {
185 printk("Detected a%s controller (type %d) at address %06x\n",
186 xd_sigs[controller].name,controller,address);
187 if (!request_region(xd_iobase,4,"xd")) {
188 printk("xd: Ports at 0x%x are not available\n",
189 xd_iobase);
190 goto out2;
192 if (controller)
193 xd_sigs[controller].init_controller(address);
194 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
196 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
197 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
200 err = -ENODEV;
201 if (!xd_drives)
202 goto out3;
204 for (i = 0; i < xd_drives; i++) {
205 XD_INFO *p = &xd_info[i];
206 struct gendisk *disk = alloc_disk(64);
207 if (!disk)
208 goto Enomem;
209 p->unit = i;
210 disk->major = MAJOR_NR;
211 disk->first_minor = i<<6;
212 sprintf(disk->disk_name, "xd%c", i+'a');
213 disk->fops = &xd_fops;
214 disk->private_data = p;
215 disk->queue = &xd_queue;
216 set_capacity(disk, p->heads * p->cylinders * p->sectors);
217 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
218 p->cylinders, p->heads, p->sectors);
219 xd_gendisk[i] = disk;
222 err = -EBUSY;
223 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
224 printk("xd: unable to get IRQ%d\n",xd_irq);
225 goto out4;
228 if (request_dma(xd_dma,"xd")) {
229 printk("xd: unable to get DMA%d\n",xd_dma);
230 goto out5;
233 /* xd_maxsectors depends on controller - so set after detection */
234 blk_queue_max_sectors(&xd_queue, xd_maxsectors);
236 for (i = 0; i < xd_drives; i++)
237 add_disk(xd_gendisk[i]);
239 return 0;
241 out5:
242 free_irq(xd_irq, NULL);
243 out4:
244 for (i = 0; i < xd_drives; i++)
245 put_disk(xd_gendisk[i]);
246 out3:
247 release_region(xd_iobase,4);
248 out2:
249 blk_cleanup_queue(&xd_queue);
250 unregister_blkdev(MAJOR_NR, "xd");
251 out1:
252 if (xd_dma_buffer)
253 xd_dma_mem_free((unsigned long)xd_dma_buffer,
254 xd_maxsectors * 0x200);
255 return err;
256 Enomem:
257 err = -ENOMEM;
258 while (i--)
259 put_disk(xd_gendisk[i]);
260 goto out3;
263 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
264 static u_char __init xd_detect (u_char *controller, unsigned int *address)
266 u_char i,j,found = 0;
268 if (xd_override)
270 *controller = xd_type;
271 *address = 0;
272 return(1);
275 for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
276 for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
277 if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
278 *controller = j;
279 xd_type = j;
280 *address = xd_bases[i];
281 found++;
283 return (found);
286 /* do_xd_request: handle an incoming request */
287 static void do_xd_request (request_queue_t * q)
289 if (xdc_busy)
290 return;
292 while (!blk_queue_empty(q)) {
293 struct request *req = elv_next_request(q);
294 unsigned block = req->sector;
295 unsigned count = req->nr_sectors;
296 int rw = rq_data_dir(req);
297 XD_INFO *disk = req->rq_disk->private_data;
298 int res = 0;
299 int retry;
301 if (!(req->flags & REQ_CMD)) {
302 end_request(req, 0);
303 continue;
305 if (block + count > get_capacity(req->rq_disk)) {
306 end_request(req, 0);
307 continue;
309 if (rw != READ && rw != WRITE) {
310 printk("do_xd_request: unknown request\n");
311 end_request(req, 0);
312 continue;
314 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
315 res = xd_readwrite(rw, disk, req->buffer, block, count);
316 end_request(req, res); /* wrap up, 0 = fail, 1 = success */
320 /* xd_ioctl: handle device ioctl's */
321 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
323 XD_INFO *p = inode->i_bdev->bd_disk->private_data;
325 switch (cmd) {
326 case HDIO_GETGEO:
328 struct hd_geometry g;
329 struct hd_geometry *geometry = (struct hd_geometry *) arg;
330 g.heads = p->heads;
331 g.sectors = p->sectors;
332 g.cylinders = p->cylinders;
333 g.start = get_start_sect(inode->i_bdev);
334 return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
336 case HDIO_SET_DMA:
337 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
338 if (xdc_busy) return -EBUSY;
339 nodma = !arg;
340 if (nodma && xd_dma_buffer) {
341 xd_dma_mem_free((unsigned long)xd_dma_buffer,
342 xd_maxsectors * 0x200);
343 xd_dma_buffer = 0;
344 } else if (!nodma && !xd_dma_buffer) {
345 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
346 if (!xd_dma_buffer) {
347 nodma = XD_DONT_USE_DMA;
348 return -ENOMEM;
351 return 0;
352 case HDIO_GET_DMA:
353 return put_user(!nodma, (long *) arg);
354 case HDIO_GET_MULTCOUNT:
355 return put_user(xd_maxsectors, (long *) arg);
356 default:
357 return -EINVAL;
361 /* xd_readwrite: handle a read/write request */
362 static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
364 int drive = p->unit;
365 u_char cmdblk[6],sense[4];
366 u_short track,cylinder;
367 u_char head,sector,control,mode = PIO_MODE,temp;
368 char **real_buffer;
369 register int i;
371 #ifdef DEBUG_READWRITE
372 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
373 #endif /* DEBUG_READWRITE */
375 spin_unlock_irq(&xd_lock);
377 control = p->control;
378 if (!xd_dma_buffer)
379 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
380 while (count) {
381 temp = count < xd_maxsectors ? count : xd_maxsectors;
383 track = block / p->sectors;
384 head = track % p->heads;
385 cylinder = track / p->heads;
386 sector = block % p->sectors;
388 #ifdef DEBUG_READWRITE
389 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
390 #endif /* DEBUG_READWRITE */
392 if (xd_dma_buffer) {
393 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
394 real_buffer = &xd_dma_buffer;
395 for (i=0; i < (temp * 0x200); i++)
396 xd_dma_buffer[i] = buffer[i];
398 else
399 real_buffer = &buffer;
401 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
403 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
404 case 1:
405 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
406 xd_recalibrate(drive);
407 spin_lock_irq(&xd_lock);
408 return (0);
409 case 2:
410 if (sense[0] & 0x30) {
411 printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
412 switch ((sense[0] & 0x30) >> 4) {
413 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
414 break;
415 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
416 break;
417 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
418 break;
419 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
420 break;
423 if (sense[0] & 0x80)
424 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
425 /* reported drive number = (sense[1] & 0xE0) >> 5 */
426 else
427 printk(" - no valid disk address\n");
428 spin_lock_irq(&xd_lock);
429 return (0);
431 if (xd_dma_buffer)
432 for (i=0; i < (temp * 0x200); i++)
433 buffer[i] = xd_dma_buffer[i];
435 count -= temp, buffer += temp * 0x200, block += temp;
437 spin_lock_irq(&xd_lock);
438 return (1);
441 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
442 static void xd_recalibrate (u_char drive)
444 u_char cmdblk[6];
446 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
447 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
448 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
451 /* xd_interrupt_handler: interrupt service routine */
452 static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs)
454 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
455 #ifdef DEBUG_OTHER
456 printk("xd_interrupt_handler: interrupt detected\n");
457 #endif /* DEBUG_OTHER */
458 outb(0,XD_CONTROL); /* acknowledge interrupt */
459 wake_up(&xd_wait_int); /* and wake up sleeping processes */
461 else
462 printk("xd: unexpected interrupt\n");
465 /* xd_setup_dma: set up the DMA controller for a data transfer */
466 static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
468 unsigned long f;
470 if (nodma)
471 return (PIO_MODE);
472 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
473 #ifdef DEBUG_OTHER
474 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
475 #endif /* DEBUG_OTHER */
476 return (PIO_MODE);
479 f=claim_dma_lock();
480 disable_dma(xd_dma);
481 clear_dma_ff(xd_dma);
482 set_dma_mode(xd_dma,mode);
483 set_dma_addr(xd_dma, (unsigned long) buffer);
484 set_dma_count(xd_dma,count);
486 release_dma_lock(f);
488 return (DMA_MODE); /* use DMA and INT */
491 /* xd_build: put stuff into an array in a format suitable for the controller */
492 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)
494 cmdblk[0] = command;
495 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
496 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
497 cmdblk[3] = cylinder & 0xFF;
498 cmdblk[4] = count;
499 cmdblk[5] = control;
501 return (cmdblk);
504 static void xd_watchdog (unsigned long unused)
506 xd_error = 1;
507 wake_up(&xd_wait_int);
510 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
511 static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
513 u_long expiry = jiffies + timeout;
514 int success;
516 xdc_busy = 1;
517 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
518 set_current_state(TASK_UNINTERRUPTIBLE);
519 schedule_timeout(1);
521 xdc_busy = 0;
522 return (success);
525 static inline u_int xd_wait_for_IRQ (void)
527 unsigned long flags;
528 xd_watchdog_int.expires = jiffies + 8 * HZ;
529 add_timer(&xd_watchdog_int);
531 flags=claim_dma_lock();
532 enable_dma(xd_dma);
533 release_dma_lock(flags);
535 sleep_on(&xd_wait_int);
536 del_timer(&xd_watchdog_int);
537 xdc_busy = 0;
539 flags=claim_dma_lock();
540 disable_dma(xd_dma);
541 release_dma_lock(flags);
543 if (xd_error) {
544 printk("xd: missed IRQ - command aborted\n");
545 xd_error = 0;
546 return (1);
548 return (0);
551 /* xd_command: handle all data transfers necessary for a single command */
552 static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
554 u_char cmdblk[6],csb,complete = 0;
556 #ifdef DEBUG_COMMAND
557 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
558 #endif /* DEBUG_COMMAND */
560 outb(0,XD_SELECT);
561 outb(mode,XD_CONTROL);
563 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
564 return (1);
566 while (!complete) {
567 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
568 return (1);
570 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
571 case 0:
572 if (mode == DMA_MODE) {
573 if (xd_wait_for_IRQ())
574 return (1);
575 } else
576 outb(outdata ? *outdata++ : 0,XD_DATA);
577 break;
578 case STAT_INPUT:
579 if (mode == DMA_MODE) {
580 if (xd_wait_for_IRQ())
581 return (1);
582 } else
583 if (indata)
584 *indata++ = inb(XD_DATA);
585 else
586 inb(XD_DATA);
587 break;
588 case STAT_COMMAND:
589 outb(command ? *command++ : 0,XD_DATA);
590 break;
591 case STAT_COMMAND | STAT_INPUT:
592 complete = 1;
593 break;
596 csb = inb(XD_DATA);
598 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
599 return (1);
601 if (csb & CSB_ERROR) { /* read sense data if error */
602 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
603 if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
604 printk("xd: warning! sense command failed!\n");
607 #ifdef DEBUG_COMMAND
608 printk("xd_command: completed with csb = 0x%X\n",csb);
609 #endif /* DEBUG_COMMAND */
611 return (csb & CSB_ERROR);
614 static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
616 u_char cmdblk[6],i,count = 0;
618 for (i = 0; i < XD_MAXDRIVES; i++) {
619 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
620 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
621 set_current_state(TASK_INTERRUPTIBLE);
622 schedule_timeout(XD_INIT_DISK_DELAY);
624 init_drive(count);
625 count++;
627 set_current_state(TASK_INTERRUPTIBLE);
628 schedule_timeout(XD_INIT_DISK_DELAY);
631 return (count);
634 static void __init xd_manual_geo_set (u_char drive)
636 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
637 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
638 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
641 static void __init xd_dtc_init_controller (unsigned int address)
643 switch (address) {
644 case 0x00000:
645 case 0xC8000: break; /*initial: 0x320 */
646 case 0xCA000: xd_iobase = 0x324;
647 case 0xD0000: /*5150CX*/
648 case 0xD8000: break; /*5150CX & 5150XL*/
649 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
650 break;
652 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
654 outb(0,XD_RESET); /* reset the controller */
658 static void __init xd_dtc5150cx_init_drive (u_char drive)
660 /* values from controller's BIOS - BIOS chip may be removed */
661 static u_short geometry_table[][4] = {
662 {0x200,8,0x200,0x100},
663 {0x267,2,0x267,0x267},
664 {0x264,4,0x264,0x80},
665 {0x132,4,0x132,0x0},
666 {0x132,2,0x80, 0x132},
667 {0x177,8,0x177,0x0},
668 {0x132,8,0x84, 0x0},
669 {}, /* not used */
670 {0x132,6,0x80, 0x100},
671 {0x200,6,0x100,0x100},
672 {0x264,2,0x264,0x80},
673 {0x280,4,0x280,0x100},
674 {0x2B9,3,0x2B9,0x2B9},
675 {0x2B9,5,0x2B9,0x2B9},
676 {0x280,6,0x280,0x100},
677 {0x132,4,0x132,0x0}};
678 u_char n;
680 n = inb(XD_JUMPER);
681 n = (drive ? n : (n >> 2)) & 0x33;
682 n = (n | (n >> 2)) & 0x0F;
683 if (xd_geo[3*drive])
684 xd_manual_geo_set(drive);
685 else
686 if (n != 7) {
687 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
688 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
689 xd_info[drive].sectors = 17; /* sectors */
690 #if 0
691 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
692 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
693 xd_info[drive].ecc = 0x0B; /* ecc length */
694 #endif /* 0 */
696 else {
697 printk("xd%c: undetermined drive geometry\n",'a'+drive);
698 return;
700 xd_info[drive].control = 5; /* control byte */
701 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
702 xd_recalibrate(drive);
705 static void __init xd_dtc_init_drive (u_char drive)
707 u_char cmdblk[6],buf[64];
709 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
710 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
711 xd_info[drive].heads = buf[0x0A]; /* heads */
712 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
713 xd_info[drive].sectors = 17; /* sectors */
714 if (xd_geo[3*drive])
715 xd_manual_geo_set(drive);
716 #if 0
717 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
718 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
719 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
720 #endif /* 0 */
721 xd_info[drive].control = 0; /* control byte */
723 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]);
724 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
725 if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
726 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
728 else
729 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
732 static void __init xd_wd_init_controller (unsigned int address)
734 switch (address) {
735 case 0x00000:
736 case 0xC8000: break; /*initial: 0x320 */
737 case 0xCA000: xd_iobase = 0x324; break;
738 case 0xCC000: xd_iobase = 0x328; break;
739 case 0xCE000: xd_iobase = 0x32C; break;
740 case 0xD0000: xd_iobase = 0x328; break; /* ? */
741 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
742 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
743 break;
745 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
747 outb(0,XD_RESET); /* reset the controller */
749 set_current_state(TASK_UNINTERRUPTIBLE);
750 schedule_timeout(XD_INIT_DISK_DELAY);
753 static void __init xd_wd_init_drive (u_char drive)
755 /* values from controller's BIOS - BIOS may be disabled */
756 static u_short geometry_table[][4] = {
757 {0x264,4,0x1C2,0x1C2}, /* common part */
758 {0x132,4,0x099,0x0},
759 {0x267,2,0x1C2,0x1C2},
760 {0x267,4,0x1C2,0x1C2},
762 {0x334,6,0x335,0x335}, /* 1004 series RLL */
763 {0x30E,4,0x30F,0x3DC},
764 {0x30E,2,0x30F,0x30F},
765 {0x267,4,0x268,0x268},
767 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
768 {0x3DB,7,0x3DC,0x3DC},
769 {0x264,4,0x265,0x265},
770 {0x267,4,0x268,0x268}};
772 u_char cmdblk[6],buf[0x200];
773 u_char n = 0,rll,jumper_state,use_jumper_geo;
774 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
776 jumper_state = ~(inb(0x322));
777 if (jumper_state & 0x40)
778 xd_irq = 9;
779 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
780 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
781 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
782 xd_info[drive].heads = buf[0x1AF]; /* heads */
783 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
784 xd_info[drive].sectors = 17; /* sectors */
785 if (xd_geo[3*drive])
786 xd_manual_geo_set(drive);
787 #if 0
788 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
789 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
790 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
791 #endif /* 0 */
792 xd_info[drive].control = buf[0x1B5]; /* control byte */
793 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
794 if (xd_geo[3*drive]) {
795 xd_manual_geo_set(drive);
796 xd_info[drive].control = rll ? 7 : 5;
798 else if (use_jumper_geo) {
799 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
800 xd_info[drive].cylinders = geometry_table[n][0];
801 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
802 xd_info[drive].control = rll ? 7 : 5;
803 #if 0
804 xd_info[drive].rwrite = geometry_table[n][2];
805 xd_info[drive].wprecomp = geometry_table[n][3];
806 xd_info[drive].ecc = 0x0B;
807 #endif /* 0 */
809 if (!wd_1002) {
810 if (use_jumper_geo)
811 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
812 geometry_table[n][2],geometry_table[n][3],0x0B);
813 else
814 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
815 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
817 /* 1002 based RLL controller requests converted addressing, but reports physical
818 (physical 26 sec., logical 17 sec.)
819 1004 based ???? */
820 if (rll & wd_1002) {
821 if ((xd_info[drive].cylinders *= 26,
822 xd_info[drive].cylinders /= 17) > 1023)
823 xd_info[drive].cylinders = 1023; /* 1024 ? */
824 #if 0
825 xd_info[drive].rwrite *= 26;
826 xd_info[drive].rwrite /= 17;
827 xd_info[drive].wprecomp *= 26
828 xd_info[drive].wprecomp /= 17;
829 #endif /* 0 */
832 else
833 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
837 static void __init xd_seagate_init_controller (unsigned int address)
839 switch (address) {
840 case 0x00000:
841 case 0xC8000: break; /*initial: 0x320 */
842 case 0xD0000: xd_iobase = 0x324; break;
843 case 0xD8000: xd_iobase = 0x328; break;
844 case 0xE0000: xd_iobase = 0x32C; break;
845 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
846 break;
848 xd_maxsectors = 0x40;
850 outb(0,XD_RESET); /* reset the controller */
853 static void __init xd_seagate_init_drive (u_char drive)
855 u_char cmdblk[6],buf[0x200];
857 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
858 if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
859 xd_info[drive].heads = buf[0x04]; /* heads */
860 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
861 xd_info[drive].sectors = buf[0x05]; /* sectors */
862 xd_info[drive].control = 0; /* control byte */
864 else
865 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
868 /* Omti support courtesy Dirk Melchers */
869 static void __init xd_omti_init_controller (unsigned int address)
871 switch (address) {
872 case 0x00000:
873 case 0xC8000: break; /*initial: 0x320 */
874 case 0xD0000: xd_iobase = 0x324; break;
875 case 0xD8000: xd_iobase = 0x328; break;
876 case 0xE0000: xd_iobase = 0x32C; break;
877 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
878 break;
881 xd_maxsectors = 0x40;
883 outb(0,XD_RESET); /* reset the controller */
886 static void __init xd_omti_init_drive (u_char drive)
888 /* gets infos from drive */
889 xd_override_init_drive(drive);
891 /* set other parameters, Hardcoded, not that nice :-) */
892 xd_info[drive].control = 2;
895 /* Xebec support (AK) */
896 static void __init xd_xebec_init_controller (unsigned int address)
898 /* iobase may be set manually in range 0x300 - 0x33C
899 irq may be set manually to 2(9),3,4,5,6,7
900 dma may be set manually to 1,2,3
901 (How to detect them ???)
902 BIOS address may be set manually in range 0x0 - 0xF8000
903 If you need non-standard settings use the xd=... command */
905 switch (address) {
906 case 0x00000:
907 case 0xC8000: /* initially: xd_iobase==0x320 */
908 case 0xD0000:
909 case 0xD2000:
910 case 0xD4000:
911 case 0xD6000:
912 case 0xD8000:
913 case 0xDA000:
914 case 0xDC000:
915 case 0xDE000:
916 case 0xE0000: break;
917 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
918 break;
921 xd_maxsectors = 0x01;
922 outb(0,XD_RESET); /* reset the controller */
924 set_current_state(TASK_UNINTERRUPTIBLE);
925 schedule_timeout(XD_INIT_DISK_DELAY);
928 static void __init xd_xebec_init_drive (u_char drive)
930 /* values from controller's BIOS - BIOS chip may be removed */
931 static u_short geometry_table[][5] = {
932 {0x132,4,0x080,0x080,0x7},
933 {0x132,4,0x080,0x080,0x17},
934 {0x264,2,0x100,0x100,0x7},
935 {0x264,2,0x100,0x100,0x17},
936 {0x132,8,0x080,0x080,0x7},
937 {0x132,8,0x080,0x080,0x17},
938 {0x264,4,0x100,0x100,0x6},
939 {0x264,4,0x100,0x100,0x17},
940 {0x2BC,5,0x2BC,0x12C,0x6},
941 {0x3A5,4,0x3A5,0x3A5,0x7},
942 {0x26C,6,0x26C,0x26C,0x7},
943 {0x200,8,0x200,0x100,0x17},
944 {0x400,5,0x400,0x400,0x7},
945 {0x400,6,0x400,0x400,0x7},
946 {0x264,8,0x264,0x200,0x17},
947 {0x33E,7,0x33E,0x200,0x7}};
948 u_char n;
950 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
951 is assumed for BOTH drives */
952 if (xd_geo[3*drive])
953 xd_manual_geo_set(drive);
954 else {
955 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
956 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
957 xd_info[drive].sectors = 17; /* sectors */
958 #if 0
959 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
960 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
961 xd_info[drive].ecc = 0x0B; /* ecc length */
962 #endif /* 0 */
964 xd_info[drive].control = geometry_table[n][4]; /* control byte */
965 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
966 xd_recalibrate(drive);
969 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
970 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
971 static void __init xd_override_init_drive (u_char drive)
973 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
974 u_char cmdblk[6],i;
976 if (xd_geo[3*drive])
977 xd_manual_geo_set(drive);
978 else {
979 for (i = 0; i < 3; i++) {
980 while (min[i] != max[i] - 1) {
981 test[i] = (min[i] + max[i]) / 2;
982 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
983 if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
984 min[i] = test[i];
985 else
986 max[i] = test[i];
988 test[i] = min[i];
990 xd_info[drive].heads = (u_char) min[0] + 1;
991 xd_info[drive].cylinders = (u_short) min[1] + 1;
992 xd_info[drive].sectors = (u_char) min[2] + 1;
994 xd_info[drive].control = 0;
997 /* xd_setup: initialise controller from command line parameters */
998 static void __init do_xd_setup (int *integers)
1000 switch (integers[0]) {
1001 case 4: if (integers[4] < 0)
1002 nodma = 1;
1003 else if (integers[4] < 8)
1004 xd_dma = integers[4];
1005 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1006 xd_iobase = integers[3];
1007 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1008 xd_irq = integers[2];
1009 case 1: xd_override = 1;
1010 if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
1011 xd_type = integers[1];
1012 case 0: break;
1013 default:printk("xd: too many parameters for xd\n");
1015 xd_maxsectors = 0x01;
1018 /* xd_setparam: set the drive characteristics */
1019 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)
1021 u_char cmdblk[14];
1023 xd_build(cmdblk,command,drive,0,0,0,0,0);
1024 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1025 cmdblk[7] = (u_char) (cylinders & 0xFF);
1026 cmdblk[8] = heads & 0x1F;
1027 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1028 cmdblk[10] = (u_char) (rwrite & 0xFF);
1029 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1030 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1031 cmdblk[13] = ecc;
1033 /* Some controllers require geometry info as data, not command */
1035 if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
1036 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1040 #ifdef MODULE
1042 MODULE_PARM(xd, "1-4i");
1043 MODULE_PARM(xd_geo, "3-6i");
1044 MODULE_PARM(nodma, "i");
1046 MODULE_LICENSE("GPL");
1048 void cleanup_module(void)
1050 int i;
1051 unregister_blkdev(MAJOR_NR, "xd");
1052 for (i = 0; i < xd_drives; i++) {
1053 del_gendisk(xd_gendisk[i]);
1054 put_disk(xd_gendisk[i]);
1056 blk_cleanup_queue(&xd_queue);
1057 release_region(xd_iobase,4);
1058 devfs_unregister (devfs_handle);
1059 if (xd_drives) {
1060 free_irq(xd_irq, NULL);
1061 free_dma(xd_dma);
1062 if (xd_dma_buffer)
1063 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1066 #else
1068 static int __init xd_setup (char *str)
1070 int ints[5];
1071 get_options (str, ARRAY_SIZE (ints), ints);
1072 do_xd_setup (ints);
1073 return 1;
1076 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1077 (used only for WD drives) */
1078 static int __init xd_manual_geo_init (char *str)
1080 int i, integers[1 + 3*XD_MAXDRIVES];
1082 get_options (str, ARRAY_SIZE (integers), integers);
1083 if (integers[0]%3 != 0) {
1084 printk("xd: incorrect number of parameters for xd_geo\n");
1085 return 1;
1087 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1088 xd_geo[i] = integers[i+1];
1089 return 1;
1092 __setup ("xd=", xd_setup);
1093 __setup ("xd_geo=", xd_manual_geo_init);
1095 #endif /* MODULE */
1097 module_init(xd_init)