[IPV4]: Make struct sockaddr_in::sin_port __be16
[linux-2.6/mini2440.git] / drivers / block / xd.c
blobe828e4cbd3e1122a0ca3abb48e7ed2de51a6bf81
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/blkdev.h>
49 #include <linux/blkpg.h>
50 #include <linux/delay.h>
52 #include <asm/system.h>
53 #include <asm/io.h>
54 #include <asm/uaccess.h>
55 #include <asm/dma.h>
57 #include "xd.h"
59 static void __init do_xd_setup (int *integers);
60 #ifdef MODULE
61 static int xd[5] = { -1,-1,-1,-1, };
62 #endif
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:
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;
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 DEFINE_SPINLOCK(xd_lock);
129 static struct gendisk *xd_gendisk[2];
131 static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
133 static struct block_device_operations xd_fops = {
134 .owner = THIS_MODULE,
135 .ioctl = xd_ioctl,
136 .getgeo = xd_getgeo,
138 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
139 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
140 static u_char xd_override __initdata = 0, xd_type __initdata = 0;
141 static u_short xd_iobase = 0x320;
142 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
144 static volatile int xdc_busy;
145 static struct timer_list xd_watchdog_int;
147 static volatile u_char xd_error;
148 static int nodma = XD_DONT_USE_DMA;
150 static struct request_queue *xd_queue;
152 /* xd_init: register the block device number and set up pointer tables */
153 static int __init xd_init(void)
155 u_char i,controller;
156 unsigned int address;
157 int err;
159 #ifdef MODULE
161 u_char count = 0;
162 for (i = 4; i > 0; i--)
163 if (((xd[i] = xd[i-1]) >= 0) && !count)
164 count = i;
165 if ((xd[0] = count))
166 do_xd_setup(xd);
168 #endif
170 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
172 if (!xd_dma_buffer)
173 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
174 if (!xd_dma_buffer) {
175 printk(KERN_ERR "xd: Out of memory.\n");
176 return -ENOMEM;
179 err = -EBUSY;
180 if (register_blkdev(XT_DISK_MAJOR, "xd"))
181 goto out1;
183 err = -ENOMEM;
184 xd_queue = blk_init_queue(do_xd_request, &xd_lock);
185 if (!xd_queue)
186 goto out1a;
188 if (xd_detect(&controller,&address)) {
190 printk("Detected a%s controller (type %d) at address %06x\n",
191 xd_sigs[controller].name,controller,address);
192 if (!request_region(xd_iobase,4,"xd")) {
193 printk("xd: Ports at 0x%x are not available\n",
194 xd_iobase);
195 goto out2;
197 if (controller)
198 xd_sigs[controller].init_controller(address);
199 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
201 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
202 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
205 err = -ENODEV;
206 if (!xd_drives)
207 goto out3;
209 for (i = 0; i < xd_drives; i++) {
210 XD_INFO *p = &xd_info[i];
211 struct gendisk *disk = alloc_disk(64);
212 if (!disk)
213 goto Enomem;
214 p->unit = i;
215 disk->major = XT_DISK_MAJOR;
216 disk->first_minor = i<<6;
217 sprintf(disk->disk_name, "xd%c", i+'a');
218 disk->fops = &xd_fops;
219 disk->private_data = p;
220 disk->queue = xd_queue;
221 set_capacity(disk, p->heads * p->cylinders * p->sectors);
222 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
223 p->cylinders, p->heads, p->sectors);
224 xd_gendisk[i] = disk;
227 err = -EBUSY;
228 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
229 printk("xd: unable to get IRQ%d\n",xd_irq);
230 goto out4;
233 if (request_dma(xd_dma,"xd")) {
234 printk("xd: unable to get DMA%d\n",xd_dma);
235 goto out5;
238 /* xd_maxsectors depends on controller - so set after detection */
239 blk_queue_max_sectors(xd_queue, xd_maxsectors);
241 for (i = 0; i < xd_drives; i++)
242 add_disk(xd_gendisk[i]);
244 return 0;
246 out5:
247 free_irq(xd_irq, NULL);
248 out4:
249 for (i = 0; i < xd_drives; i++)
250 put_disk(xd_gendisk[i]);
251 out3:
252 release_region(xd_iobase,4);
253 out2:
254 blk_cleanup_queue(xd_queue);
255 out1a:
256 unregister_blkdev(XT_DISK_MAJOR, "xd");
257 out1:
258 if (xd_dma_buffer)
259 xd_dma_mem_free((unsigned long)xd_dma_buffer,
260 xd_maxsectors * 0x200);
261 return err;
262 Enomem:
263 err = -ENOMEM;
264 while (i--)
265 put_disk(xd_gendisk[i]);
266 goto out3;
269 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
270 static u_char __init xd_detect (u_char *controller, unsigned int *address)
272 int i, j;
274 if (xd_override)
276 *controller = xd_type;
277 *address = 0;
278 return(1);
281 for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
282 void __iomem *p = ioremap(xd_bases[i], 0x2000);
283 if (!p)
284 continue;
285 for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
286 const char *s = xd_sigs[j].string;
287 if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
288 *controller = j;
289 xd_type = j;
290 *address = xd_bases[i];
291 iounmap(p);
292 return 1;
295 iounmap(p);
297 return 0;
300 /* do_xd_request: handle an incoming request */
301 static void do_xd_request (request_queue_t * q)
303 struct request *req;
305 if (xdc_busy)
306 return;
308 while ((req = elv_next_request(q)) != NULL) {
309 unsigned block = req->sector;
310 unsigned count = req->nr_sectors;
311 int rw = rq_data_dir(req);
312 XD_INFO *disk = req->rq_disk->private_data;
313 int res = 0;
314 int retry;
316 if (!(req->flags & REQ_CMD)) {
317 end_request(req, 0);
318 continue;
320 if (block + count > get_capacity(req->rq_disk)) {
321 end_request(req, 0);
322 continue;
324 if (rw != READ && rw != WRITE) {
325 printk("do_xd_request: unknown request\n");
326 end_request(req, 0);
327 continue;
329 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
330 res = xd_readwrite(rw, disk, req->buffer, block, count);
331 end_request(req, res); /* wrap up, 0 = fail, 1 = success */
335 static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
337 XD_INFO *p = bdev->bd_disk->private_data;
339 geo->heads = p->heads;
340 geo->sectors = p->sectors;
341 geo->cylinders = p->cylinders;
342 return 0;
345 /* xd_ioctl: handle device ioctl's */
346 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
348 switch (cmd) {
349 case HDIO_SET_DMA:
350 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
351 if (xdc_busy) return -EBUSY;
352 nodma = !arg;
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;
361 return -ENOMEM;
364 return 0;
365 case HDIO_GET_DMA:
366 return put_user(!nodma, (long __user *) arg);
367 case HDIO_GET_MULTCOUNT:
368 return put_user(xd_maxsectors, (long __user *) arg);
369 default:
370 return -EINVAL;
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)
377 int drive = p->unit;
378 u_char cmdblk[6],sense[4];
379 u_short track,cylinder;
380 u_char head,sector,control,mode = PIO_MODE,temp;
381 char **real_buffer;
382 register int i;
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;
391 if (!xd_dma_buffer)
392 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
393 while (count) {
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 */
405 if (xd_dma_buffer) {
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];
411 else
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)) {
417 case 1:
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);
421 return (0);
422 case 2:
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);
427 break;
428 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
429 break;
430 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
431 break;
432 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
433 break;
436 if (sense[0] & 0x80)
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 */
439 else
440 printk(" - no valid disk address\n");
441 spin_lock_irq(&xd_lock);
442 return (0);
444 if (xd_dma_buffer)
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);
451 return (1);
454 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
455 static void xd_recalibrate (u_char drive)
457 u_char cmdblk[6];
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 */
469 #ifdef DEBUG_OTHER
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 */
474 return IRQ_HANDLED;
476 else
477 printk("xd: unexpected interrupt\n");
478 return IRQ_NONE;
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)
484 unsigned long f;
486 if (nodma)
487 return (PIO_MODE);
488 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
489 #ifdef DEBUG_OTHER
490 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
491 #endif /* DEBUG_OTHER */
492 return (PIO_MODE);
495 f=claim_dma_lock();
496 disable_dma(xd_dma);
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);
502 release_dma_lock(f);
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)
510 cmdblk[0] = command;
511 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
512 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
513 cmdblk[3] = cylinder & 0xFF;
514 cmdblk[4] = count;
515 cmdblk[5] = control;
517 return (cmdblk);
520 static void xd_watchdog (unsigned long unused)
522 xd_error = 1;
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;
530 int success;
532 xdc_busy = 1;
533 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
534 schedule_timeout_uninterruptible(1);
535 xdc_busy = 0;
536 return (success);
539 static inline u_int xd_wait_for_IRQ (void)
541 unsigned long flags;
542 xd_watchdog_int.expires = jiffies + 8 * HZ;
543 add_timer(&xd_watchdog_int);
545 flags=claim_dma_lock();
546 enable_dma(xd_dma);
547 release_dma_lock(flags);
549 sleep_on(&xd_wait_int);
550 del_timer(&xd_watchdog_int);
551 xdc_busy = 0;
553 flags=claim_dma_lock();
554 disable_dma(xd_dma);
555 release_dma_lock(flags);
557 if (xd_error) {
558 printk("xd: missed IRQ - command aborted\n");
559 xd_error = 0;
560 return (1);
562 return (0);
565 /* xd_command: handle all data transfers necessary for a single command */
566 static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
568 u_char cmdblk[6],csb,complete = 0;
570 #ifdef DEBUG_COMMAND
571 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
572 #endif /* DEBUG_COMMAND */
574 outb(0,XD_SELECT);
575 outb(mode,XD_CONTROL);
577 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
578 return (1);
580 while (!complete) {
581 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
582 return (1);
584 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
585 case 0:
586 if (mode == DMA_MODE) {
587 if (xd_wait_for_IRQ())
588 return (1);
589 } else
590 outb(outdata ? *outdata++ : 0,XD_DATA);
591 break;
592 case STAT_INPUT:
593 if (mode == DMA_MODE) {
594 if (xd_wait_for_IRQ())
595 return (1);
596 } else
597 if (indata)
598 *indata++ = inb(XD_DATA);
599 else
600 inb(XD_DATA);
601 break;
602 case STAT_COMMAND:
603 outb(command ? *command++ : 0,XD_DATA);
604 break;
605 case STAT_COMMAND | STAT_INPUT:
606 complete = 1;
607 break;
610 csb = inb(XD_DATA);
612 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
613 return (1);
615 if (csb & CSB_ERROR) { /* read sense data if error */
616 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
617 if (xd_command(cmdblk,0,sense,NULL,NULL,XD_TIMEOUT))
618 printk("xd: warning! sense command failed!\n");
621 #ifdef DEBUG_COMMAND
622 printk("xd_command: completed with csb = 0x%X\n",csb);
623 #endif /* DEBUG_COMMAND */
625 return (csb & CSB_ERROR);
628 static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
630 u_char cmdblk[6],i,count = 0;
632 for (i = 0; i < XD_MAXDRIVES; i++) {
633 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
634 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
635 msleep_interruptible(XD_INIT_DISK_DELAY);
637 init_drive(count);
638 count++;
640 msleep_interruptible(XD_INIT_DISK_DELAY);
643 return (count);
646 static void __init xd_manual_geo_set (u_char drive)
648 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
649 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
650 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
653 static void __init xd_dtc_init_controller (unsigned int address)
655 switch (address) {
656 case 0x00000:
657 case 0xC8000: break; /*initial: 0x320 */
658 case 0xCA000: xd_iobase = 0x324;
659 case 0xD0000: /*5150CX*/
660 case 0xD8000: break; /*5150CX & 5150XL*/
661 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
662 break;
664 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
666 outb(0,XD_RESET); /* reset the controller */
670 static void __init xd_dtc5150cx_init_drive (u_char drive)
672 /* values from controller's BIOS - BIOS chip may be removed */
673 static u_short geometry_table[][4] = {
674 {0x200,8,0x200,0x100},
675 {0x267,2,0x267,0x267},
676 {0x264,4,0x264,0x80},
677 {0x132,4,0x132,0x0},
678 {0x132,2,0x80, 0x132},
679 {0x177,8,0x177,0x0},
680 {0x132,8,0x84, 0x0},
681 {}, /* not used */
682 {0x132,6,0x80, 0x100},
683 {0x200,6,0x100,0x100},
684 {0x264,2,0x264,0x80},
685 {0x280,4,0x280,0x100},
686 {0x2B9,3,0x2B9,0x2B9},
687 {0x2B9,5,0x2B9,0x2B9},
688 {0x280,6,0x280,0x100},
689 {0x132,4,0x132,0x0}};
690 u_char n;
692 n = inb(XD_JUMPER);
693 n = (drive ? n : (n >> 2)) & 0x33;
694 n = (n | (n >> 2)) & 0x0F;
695 if (xd_geo[3*drive])
696 xd_manual_geo_set(drive);
697 else
698 if (n != 7) {
699 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
700 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
701 xd_info[drive].sectors = 17; /* sectors */
702 #if 0
703 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
704 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
705 xd_info[drive].ecc = 0x0B; /* ecc length */
706 #endif /* 0 */
708 else {
709 printk("xd%c: undetermined drive geometry\n",'a'+drive);
710 return;
712 xd_info[drive].control = 5; /* control byte */
713 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
714 xd_recalibrate(drive);
717 static void __init xd_dtc_init_drive (u_char drive)
719 u_char cmdblk[6],buf[64];
721 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
722 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
723 xd_info[drive].heads = buf[0x0A]; /* heads */
724 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
725 xd_info[drive].sectors = 17; /* sectors */
726 if (xd_geo[3*drive])
727 xd_manual_geo_set(drive);
728 #if 0
729 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
730 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
731 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
732 #endif /* 0 */
733 xd_info[drive].control = 0; /* control byte */
735 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]);
736 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
737 if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
738 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
740 else
741 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
744 static void __init xd_wd_init_controller (unsigned int address)
746 switch (address) {
747 case 0x00000:
748 case 0xC8000: break; /*initial: 0x320 */
749 case 0xCA000: xd_iobase = 0x324; break;
750 case 0xCC000: xd_iobase = 0x328; break;
751 case 0xCE000: xd_iobase = 0x32C; break;
752 case 0xD0000: xd_iobase = 0x328; break; /* ? */
753 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
754 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
755 break;
757 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
759 outb(0,XD_RESET); /* reset the controller */
761 msleep(XD_INIT_DISK_DELAY);
764 static void __init xd_wd_init_drive (u_char drive)
766 /* values from controller's BIOS - BIOS may be disabled */
767 static u_short geometry_table[][4] = {
768 {0x264,4,0x1C2,0x1C2}, /* common part */
769 {0x132,4,0x099,0x0},
770 {0x267,2,0x1C2,0x1C2},
771 {0x267,4,0x1C2,0x1C2},
773 {0x334,6,0x335,0x335}, /* 1004 series RLL */
774 {0x30E,4,0x30F,0x3DC},
775 {0x30E,2,0x30F,0x30F},
776 {0x267,4,0x268,0x268},
778 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
779 {0x3DB,7,0x3DC,0x3DC},
780 {0x264,4,0x265,0x265},
781 {0x267,4,0x268,0x268}};
783 u_char cmdblk[6],buf[0x200];
784 u_char n = 0,rll,jumper_state,use_jumper_geo;
785 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
787 jumper_state = ~(inb(0x322));
788 if (jumper_state & 0x40)
789 xd_irq = 9;
790 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
791 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
792 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
793 xd_info[drive].heads = buf[0x1AF]; /* heads */
794 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
795 xd_info[drive].sectors = 17; /* sectors */
796 if (xd_geo[3*drive])
797 xd_manual_geo_set(drive);
798 #if 0
799 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
800 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
801 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
802 #endif /* 0 */
803 xd_info[drive].control = buf[0x1B5]; /* control byte */
804 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
805 if (xd_geo[3*drive]) {
806 xd_manual_geo_set(drive);
807 xd_info[drive].control = rll ? 7 : 5;
809 else if (use_jumper_geo) {
810 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
811 xd_info[drive].cylinders = geometry_table[n][0];
812 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
813 xd_info[drive].control = rll ? 7 : 5;
814 #if 0
815 xd_info[drive].rwrite = geometry_table[n][2];
816 xd_info[drive].wprecomp = geometry_table[n][3];
817 xd_info[drive].ecc = 0x0B;
818 #endif /* 0 */
820 if (!wd_1002) {
821 if (use_jumper_geo)
822 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
823 geometry_table[n][2],geometry_table[n][3],0x0B);
824 else
825 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
826 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
828 /* 1002 based RLL controller requests converted addressing, but reports physical
829 (physical 26 sec., logical 17 sec.)
830 1004 based ???? */
831 if (rll & wd_1002) {
832 if ((xd_info[drive].cylinders *= 26,
833 xd_info[drive].cylinders /= 17) > 1023)
834 xd_info[drive].cylinders = 1023; /* 1024 ? */
835 #if 0
836 xd_info[drive].rwrite *= 26;
837 xd_info[drive].rwrite /= 17;
838 xd_info[drive].wprecomp *= 26
839 xd_info[drive].wprecomp /= 17;
840 #endif /* 0 */
843 else
844 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
848 static void __init xd_seagate_init_controller (unsigned int address)
850 switch (address) {
851 case 0x00000:
852 case 0xC8000: break; /*initial: 0x320 */
853 case 0xD0000: xd_iobase = 0x324; break;
854 case 0xD8000: xd_iobase = 0x328; break;
855 case 0xE0000: xd_iobase = 0x32C; break;
856 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
857 break;
859 xd_maxsectors = 0x40;
861 outb(0,XD_RESET); /* reset the controller */
864 static void __init xd_seagate_init_drive (u_char drive)
866 u_char cmdblk[6],buf[0x200];
868 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
869 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
870 xd_info[drive].heads = buf[0x04]; /* heads */
871 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
872 xd_info[drive].sectors = buf[0x05]; /* sectors */
873 xd_info[drive].control = 0; /* control byte */
875 else
876 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
879 /* Omti support courtesy Dirk Melchers */
880 static void __init xd_omti_init_controller (unsigned int address)
882 switch (address) {
883 case 0x00000:
884 case 0xC8000: break; /*initial: 0x320 */
885 case 0xD0000: xd_iobase = 0x324; break;
886 case 0xD8000: xd_iobase = 0x328; break;
887 case 0xE0000: xd_iobase = 0x32C; break;
888 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
889 break;
892 xd_maxsectors = 0x40;
894 outb(0,XD_RESET); /* reset the controller */
897 static void __init xd_omti_init_drive (u_char drive)
899 /* gets infos from drive */
900 xd_override_init_drive(drive);
902 /* set other parameters, Hardcoded, not that nice :-) */
903 xd_info[drive].control = 2;
906 /* Xebec support (AK) */
907 static void __init xd_xebec_init_controller (unsigned int address)
909 /* iobase may be set manually in range 0x300 - 0x33C
910 irq may be set manually to 2(9),3,4,5,6,7
911 dma may be set manually to 1,2,3
912 (How to detect them ???)
913 BIOS address may be set manually in range 0x0 - 0xF8000
914 If you need non-standard settings use the xd=... command */
916 switch (address) {
917 case 0x00000:
918 case 0xC8000: /* initially: xd_iobase==0x320 */
919 case 0xD0000:
920 case 0xD2000:
921 case 0xD4000:
922 case 0xD6000:
923 case 0xD8000:
924 case 0xDA000:
925 case 0xDC000:
926 case 0xDE000:
927 case 0xE0000: break;
928 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
929 break;
932 xd_maxsectors = 0x01;
933 outb(0,XD_RESET); /* reset the controller */
935 msleep(XD_INIT_DISK_DELAY);
938 static void __init xd_xebec_init_drive (u_char drive)
940 /* values from controller's BIOS - BIOS chip may be removed */
941 static u_short geometry_table[][5] = {
942 {0x132,4,0x080,0x080,0x7},
943 {0x132,4,0x080,0x080,0x17},
944 {0x264,2,0x100,0x100,0x7},
945 {0x264,2,0x100,0x100,0x17},
946 {0x132,8,0x080,0x080,0x7},
947 {0x132,8,0x080,0x080,0x17},
948 {0x264,4,0x100,0x100,0x6},
949 {0x264,4,0x100,0x100,0x17},
950 {0x2BC,5,0x2BC,0x12C,0x6},
951 {0x3A5,4,0x3A5,0x3A5,0x7},
952 {0x26C,6,0x26C,0x26C,0x7},
953 {0x200,8,0x200,0x100,0x17},
954 {0x400,5,0x400,0x400,0x7},
955 {0x400,6,0x400,0x400,0x7},
956 {0x264,8,0x264,0x200,0x17},
957 {0x33E,7,0x33E,0x200,0x7}};
958 u_char n;
960 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
961 is assumed for BOTH drives */
962 if (xd_geo[3*drive])
963 xd_manual_geo_set(drive);
964 else {
965 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
966 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
967 xd_info[drive].sectors = 17; /* sectors */
968 #if 0
969 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
970 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
971 xd_info[drive].ecc = 0x0B; /* ecc length */
972 #endif /* 0 */
974 xd_info[drive].control = geometry_table[n][4]; /* control byte */
975 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
976 xd_recalibrate(drive);
979 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
980 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
981 static void __init xd_override_init_drive (u_char drive)
983 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
984 u_char cmdblk[6],i;
986 if (xd_geo[3*drive])
987 xd_manual_geo_set(drive);
988 else {
989 for (i = 0; i < 3; i++) {
990 while (min[i] != max[i] - 1) {
991 test[i] = (min[i] + max[i]) / 2;
992 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
993 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
994 min[i] = test[i];
995 else
996 max[i] = test[i];
998 test[i] = min[i];
1000 xd_info[drive].heads = (u_char) min[0] + 1;
1001 xd_info[drive].cylinders = (u_short) min[1] + 1;
1002 xd_info[drive].sectors = (u_char) min[2] + 1;
1004 xd_info[drive].control = 0;
1007 /* xd_setup: initialise controller from command line parameters */
1008 static void __init do_xd_setup (int *integers)
1010 switch (integers[0]) {
1011 case 4: if (integers[4] < 0)
1012 nodma = 1;
1013 else if (integers[4] < 8)
1014 xd_dma = integers[4];
1015 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1016 xd_iobase = integers[3];
1017 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1018 xd_irq = integers[2];
1019 case 1: xd_override = 1;
1020 if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
1021 xd_type = integers[1];
1022 case 0: break;
1023 default:printk("xd: too many parameters for xd\n");
1025 xd_maxsectors = 0x01;
1028 /* xd_setparam: set the drive characteristics */
1029 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)
1031 u_char cmdblk[14];
1033 xd_build(cmdblk,command,drive,0,0,0,0,0);
1034 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1035 cmdblk[7] = (u_char) (cylinders & 0xFF);
1036 cmdblk[8] = heads & 0x1F;
1037 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1038 cmdblk[10] = (u_char) (rwrite & 0xFF);
1039 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1040 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1041 cmdblk[13] = ecc;
1043 /* Some controllers require geometry info as data, not command */
1045 if (xd_command(cmdblk,PIO_MODE,NULL,&cmdblk[6],NULL,XD_TIMEOUT * 2))
1046 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1050 #ifdef MODULE
1052 module_param_array(xd, int, NULL, 0);
1053 module_param_array(xd_geo, int, NULL, 0);
1054 module_param(nodma, bool, 0);
1056 MODULE_LICENSE("GPL");
1058 void cleanup_module(void)
1060 int i;
1061 unregister_blkdev(XT_DISK_MAJOR, "xd");
1062 for (i = 0; i < xd_drives; i++) {
1063 del_gendisk(xd_gendisk[i]);
1064 put_disk(xd_gendisk[i]);
1066 blk_cleanup_queue(xd_queue);
1067 release_region(xd_iobase,4);
1068 if (xd_drives) {
1069 free_irq(xd_irq, NULL);
1070 free_dma(xd_dma);
1071 if (xd_dma_buffer)
1072 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1075 #else
1077 static int __init xd_setup (char *str)
1079 int ints[5];
1080 get_options (str, ARRAY_SIZE (ints), ints);
1081 do_xd_setup (ints);
1082 return 1;
1085 /* xd_manual_geo_init: initialise drive geometry from command line parameters
1086 (used only for WD drives) */
1087 static int __init xd_manual_geo_init (char *str)
1089 int i, integers[1 + 3*XD_MAXDRIVES];
1091 get_options (str, ARRAY_SIZE (integers), integers);
1092 if (integers[0]%3 != 0) {
1093 printk("xd: incorrect number of parameters for xd_geo\n");
1094 return 1;
1096 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1097 xd_geo[i] = integers[i+1];
1098 return 1;
1101 __setup ("xd=", xd_setup);
1102 __setup ("xd_geo=", xd_manual_geo_init);
1104 #endif /* MODULE */
1106 module_init(xd_init);
1107 MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);