Loading...
1/*
2 * This file contains the driver for an XT hard disk controller
3 * (at least the DTC 5150X) for Linux.
4 *
5 * Author: Pat Mackinlay, pat@it.com.au
6 * Date: 29/09/92
7 *
8 * Revised: 01/01/93, ...
9 *
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.
14 *
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.
20 *
21 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
22 *
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.
31 *
32 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
33 *
34 */
35
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/mutex.h>
50#include <linux/blkpg.h>
51#include <linux/delay.h>
52#include <linux/io.h>
53#include <linux/gfp.h>
54
55#include <asm/system.h>
56#include <asm/uaccess.h>
57#include <asm/dma.h>
58
59#include "xd.h"
60
61static DEFINE_MUTEX(xd_mutex);
62static void __init do_xd_setup (int *integers);
63#ifdef MODULE
64static int xd[5] = { -1,-1,-1,-1, };
65#endif
66
67#define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
68 "nodma" module option */
69#define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
70
71/* Above may need to be increased if a problem with the 2nd drive detection
72 (ST11M controller) or resetting a controller (WD) appears */
73
74static XD_INFO xd_info[XD_MAXDRIVES];
75
76/* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
77 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
78 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
79 command. Run DEBUG, and then you can examine your BIOS signature with:
80
81 d xxxx:0000
82
83 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
84 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
85 in the table are, in order:
86
87 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
88 signature ; this is the actual text of the signature
89 xd_?_init_controller ; this is the controller init routine used by your controller
90 xd_?_init_drive ; this is the drive init routine used by your controller
91
92 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
93 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
94 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
95 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>.
96
97 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
98 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
99
100#include <asm/page.h>
101#define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
102#define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
103static char *xd_dma_buffer;
104
105static XD_SIGNATURE xd_sigs[] __initdata = {
106 { 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
107 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
108 { 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 */
109 { 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 */
110 { 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 */
111 { 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 */
112 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
113 { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
114 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
115 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
116 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
117 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
118 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
119};
120
121static unsigned int xd_bases[] __initdata =
122{
123 0xC8000, 0xCA000, 0xCC000,
124 0xCE000, 0xD0000, 0xD2000,
125 0xD4000, 0xD6000, 0xD8000,
126 0xDA000, 0xDC000, 0xDE000,
127 0xE0000
128};
129
130static DEFINE_SPINLOCK(xd_lock);
131
132static struct gendisk *xd_gendisk[2];
133
134static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
135
136static const struct block_device_operations xd_fops = {
137 .owner = THIS_MODULE,
138 .ioctl = xd_ioctl,
139 .getgeo = xd_getgeo,
140};
141static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
142static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
143static u_char xd_override __initdata = 0, xd_type __initdata = 0;
144static u_short xd_iobase = 0x320;
145static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
146
147static volatile int xdc_busy;
148static struct timer_list xd_watchdog_int;
149
150static volatile u_char xd_error;
151static int nodma = XD_DONT_USE_DMA;
152
153static struct request_queue *xd_queue;
154
155/* xd_init: register the block device number and set up pointer tables */
156static int __init xd_init(void)
157{
158 u_char i,controller;
159 unsigned int address;
160 int err;
161
162#ifdef MODULE
163 {
164 u_char count = 0;
165 for (i = 4; i > 0; i--)
166 if (((xd[i] = xd[i-1]) >= 0) && !count)
167 count = i;
168 if ((xd[0] = count))
169 do_xd_setup(xd);
170 }
171#endif
172
173 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
174
175 err = -EBUSY;
176 if (register_blkdev(XT_DISK_MAJOR, "xd"))
177 goto out1;
178
179 err = -ENOMEM;
180 xd_queue = blk_init_queue(do_xd_request, &xd_lock);
181 if (!xd_queue)
182 goto out1a;
183
184 if (xd_detect(&controller,&address)) {
185
186 printk("Detected a%s controller (type %d) at address %06x\n",
187 xd_sigs[controller].name,controller,address);
188 if (!request_region(xd_iobase,4,"xd")) {
189 printk("xd: Ports at 0x%x are not available\n",
190 xd_iobase);
191 goto out2;
192 }
193 if (controller)
194 xd_sigs[controller].init_controller(address);
195 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
196
197 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
198 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
199 }
200
201 /*
202 * With the drive detected, xd_maxsectors should now be known.
203 * If xd_maxsectors is 0, nothing was detected and we fall through
204 * to return -ENODEV
205 */
206 if (!xd_dma_buffer && xd_maxsectors) {
207 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
208 if (!xd_dma_buffer) {
209 printk(KERN_ERR "xd: Out of memory.\n");
210 goto out3;
211 }
212 }
213
214 err = -ENODEV;
215 if (!xd_drives)
216 goto out3;
217
218 for (i = 0; i < xd_drives; i++) {
219 XD_INFO *p = &xd_info[i];
220 struct gendisk *disk = alloc_disk(64);
221 if (!disk)
222 goto Enomem;
223 p->unit = i;
224 disk->major = XT_DISK_MAJOR;
225 disk->first_minor = i<<6;
226 sprintf(disk->disk_name, "xd%c", i+'a');
227 disk->fops = &xd_fops;
228 disk->private_data = p;
229 disk->queue = xd_queue;
230 set_capacity(disk, p->heads * p->cylinders * p->sectors);
231 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
232 p->cylinders, p->heads, p->sectors);
233 xd_gendisk[i] = disk;
234 }
235
236 err = -EBUSY;
237 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
238 printk("xd: unable to get IRQ%d\n",xd_irq);
239 goto out4;
240 }
241
242 if (request_dma(xd_dma,"xd")) {
243 printk("xd: unable to get DMA%d\n",xd_dma);
244 goto out5;
245 }
246
247 /* xd_maxsectors depends on controller - so set after detection */
248 blk_queue_max_hw_sectors(xd_queue, xd_maxsectors);
249
250 for (i = 0; i < xd_drives; i++)
251 add_disk(xd_gendisk[i]);
252
253 return 0;
254
255out5:
256 free_irq(xd_irq, NULL);
257out4:
258 for (i = 0; i < xd_drives; i++)
259 put_disk(xd_gendisk[i]);
260out3:
261 if (xd_maxsectors)
262 release_region(xd_iobase,4);
263
264 if (xd_dma_buffer)
265 xd_dma_mem_free((unsigned long)xd_dma_buffer,
266 xd_maxsectors * 0x200);
267out2:
268 blk_cleanup_queue(xd_queue);
269out1a:
270 unregister_blkdev(XT_DISK_MAJOR, "xd");
271out1:
272 return err;
273Enomem:
274 err = -ENOMEM;
275 while (i--)
276 put_disk(xd_gendisk[i]);
277 goto out3;
278}
279
280/* xd_detect: scan the possible BIOS ROM locations for the signature strings */
281static u_char __init xd_detect (u_char *controller, unsigned int *address)
282{
283 int i, j;
284
285 if (xd_override)
286 {
287 *controller = xd_type;
288 *address = 0;
289 return(1);
290 }
291
292 for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
293 void __iomem *p = ioremap(xd_bases[i], 0x2000);
294 if (!p)
295 continue;
296 for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
297 const char *s = xd_sigs[j].string;
298 if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
299 *controller = j;
300 xd_type = j;
301 *address = xd_bases[i];
302 iounmap(p);
303 return 1;
304 }
305 }
306 iounmap(p);
307 }
308 return 0;
309}
310
311/* do_xd_request: handle an incoming request */
312static void do_xd_request (struct request_queue * q)
313{
314 struct request *req;
315
316 if (xdc_busy)
317 return;
318
319 req = blk_fetch_request(q);
320 while (req) {
321 unsigned block = blk_rq_pos(req);
322 unsigned count = blk_rq_cur_sectors(req);
323 XD_INFO *disk = req->rq_disk->private_data;
324 int res = -EIO;
325 int retry;
326
327 if (req->cmd_type != REQ_TYPE_FS)
328 goto done;
329 if (block + count > get_capacity(req->rq_disk))
330 goto done;
331 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
332 res = xd_readwrite(rq_data_dir(req), disk, req->buffer,
333 block, count);
334 done:
335 /* wrap up, 0 = success, -errno = fail */
336 if (!__blk_end_request_cur(req, res))
337 req = blk_fetch_request(q);
338 }
339}
340
341static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
342{
343 XD_INFO *p = bdev->bd_disk->private_data;
344
345 geo->heads = p->heads;
346 geo->sectors = p->sectors;
347 geo->cylinders = p->cylinders;
348 return 0;
349}
350
351/* xd_ioctl: handle device ioctl's */
352static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg)
353{
354 switch (cmd) {
355 case HDIO_SET_DMA:
356 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
357 if (xdc_busy) return -EBUSY;
358 nodma = !arg;
359 if (nodma && xd_dma_buffer) {
360 xd_dma_mem_free((unsigned long)xd_dma_buffer,
361 xd_maxsectors * 0x200);
362 xd_dma_buffer = NULL;
363 } else if (!nodma && !xd_dma_buffer) {
364 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
365 if (!xd_dma_buffer) {
366 nodma = XD_DONT_USE_DMA;
367 return -ENOMEM;
368 }
369 }
370 return 0;
371 case HDIO_GET_DMA:
372 return put_user(!nodma, (long __user *) arg);
373 case HDIO_GET_MULTCOUNT:
374 return put_user(xd_maxsectors, (long __user *) arg);
375 default:
376 return -EINVAL;
377 }
378}
379
380static int xd_ioctl(struct block_device *bdev, fmode_t mode,
381 unsigned int cmd, unsigned long param)
382{
383 int ret;
384
385 mutex_lock(&xd_mutex);
386 ret = xd_locked_ioctl(bdev, mode, cmd, param);
387 mutex_unlock(&xd_mutex);
388
389 return ret;
390}
391
392/* xd_readwrite: handle a read/write request */
393static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
394{
395 int drive = p->unit;
396 u_char cmdblk[6],sense[4];
397 u_short track,cylinder;
398 u_char head,sector,control,mode = PIO_MODE,temp;
399 char **real_buffer;
400 register int i;
401
402#ifdef DEBUG_READWRITE
403 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
404#endif /* DEBUG_READWRITE */
405
406 spin_unlock_irq(&xd_lock);
407
408 control = p->control;
409 if (!xd_dma_buffer)
410 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
411 while (count) {
412 temp = count < xd_maxsectors ? count : xd_maxsectors;
413
414 track = block / p->sectors;
415 head = track % p->heads;
416 cylinder = track / p->heads;
417 sector = block % p->sectors;
418
419#ifdef DEBUG_READWRITE
420 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
421#endif /* DEBUG_READWRITE */
422
423 if (xd_dma_buffer) {
424 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
425 real_buffer = &xd_dma_buffer;
426 for (i=0; i < (temp * 0x200); i++)
427 xd_dma_buffer[i] = buffer[i];
428 }
429 else
430 real_buffer = &buffer;
431
432 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
433
434 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
435 case 1:
436 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
437 xd_recalibrate(drive);
438 spin_lock_irq(&xd_lock);
439 return -EIO;
440 case 2:
441 if (sense[0] & 0x30) {
442 printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
443 switch ((sense[0] & 0x30) >> 4) {
444 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
445 break;
446 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
447 break;
448 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
449 break;
450 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
451 break;
452 }
453 }
454 if (sense[0] & 0x80)
455 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
456 /* reported drive number = (sense[1] & 0xE0) >> 5 */
457 else
458 printk(" - no valid disk address\n");
459 spin_lock_irq(&xd_lock);
460 return -EIO;
461 }
462 if (xd_dma_buffer)
463 for (i=0; i < (temp * 0x200); i++)
464 buffer[i] = xd_dma_buffer[i];
465
466 count -= temp, buffer += temp * 0x200, block += temp;
467 }
468 spin_lock_irq(&xd_lock);
469 return 0;
470}
471
472/* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
473static void xd_recalibrate (u_char drive)
474{
475 u_char cmdblk[6];
476
477 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
478 if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 8))
479 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
480}
481
482/* xd_interrupt_handler: interrupt service routine */
483static irqreturn_t xd_interrupt_handler(int irq, void *dev_id)
484{
485 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
486#ifdef DEBUG_OTHER
487 printk("xd_interrupt_handler: interrupt detected\n");
488#endif /* DEBUG_OTHER */
489 outb(0,XD_CONTROL); /* acknowledge interrupt */
490 wake_up(&xd_wait_int); /* and wake up sleeping processes */
491 return IRQ_HANDLED;
492 }
493 else
494 printk("xd: unexpected interrupt\n");
495 return IRQ_NONE;
496}
497
498/* xd_setup_dma: set up the DMA controller for a data transfer */
499static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
500{
501 unsigned long f;
502
503 if (nodma)
504 return (PIO_MODE);
505 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
506#ifdef DEBUG_OTHER
507 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
508#endif /* DEBUG_OTHER */
509 return (PIO_MODE);
510 }
511
512 f=claim_dma_lock();
513 disable_dma(xd_dma);
514 clear_dma_ff(xd_dma);
515 set_dma_mode(xd_dma,mode);
516 set_dma_addr(xd_dma, (unsigned long) buffer);
517 set_dma_count(xd_dma,count);
518
519 release_dma_lock(f);
520
521 return (DMA_MODE); /* use DMA and INT */
522}
523
524/* xd_build: put stuff into an array in a format suitable for the controller */
525static 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)
526{
527 cmdblk[0] = command;
528 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
529 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
530 cmdblk[3] = cylinder & 0xFF;
531 cmdblk[4] = count;
532 cmdblk[5] = control;
533
534 return (cmdblk);
535}
536
537static void xd_watchdog (unsigned long unused)
538{
539 xd_error = 1;
540 wake_up(&xd_wait_int);
541}
542
543/* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
544static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
545{
546 u_long expiry = jiffies + timeout;
547 int success;
548
549 xdc_busy = 1;
550 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
551 schedule_timeout_uninterruptible(1);
552 xdc_busy = 0;
553 return (success);
554}
555
556static inline u_int xd_wait_for_IRQ (void)
557{
558 unsigned long flags;
559 xd_watchdog_int.expires = jiffies + 8 * HZ;
560 add_timer(&xd_watchdog_int);
561
562 flags=claim_dma_lock();
563 enable_dma(xd_dma);
564 release_dma_lock(flags);
565
566 sleep_on(&xd_wait_int);
567 del_timer(&xd_watchdog_int);
568 xdc_busy = 0;
569
570 flags=claim_dma_lock();
571 disable_dma(xd_dma);
572 release_dma_lock(flags);
573
574 if (xd_error) {
575 printk("xd: missed IRQ - command aborted\n");
576 xd_error = 0;
577 return (1);
578 }
579 return (0);
580}
581
582/* xd_command: handle all data transfers necessary for a single command */
583static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
584{
585 u_char cmdblk[6],csb,complete = 0;
586
587#ifdef DEBUG_COMMAND
588 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
589#endif /* DEBUG_COMMAND */
590
591 outb(0,XD_SELECT);
592 outb(mode,XD_CONTROL);
593
594 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
595 return (1);
596
597 while (!complete) {
598 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
599 return (1);
600
601 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
602 case 0:
603 if (mode == DMA_MODE) {
604 if (xd_wait_for_IRQ())
605 return (1);
606 } else
607 outb(outdata ? *outdata++ : 0,XD_DATA);
608 break;
609 case STAT_INPUT:
610 if (mode == DMA_MODE) {
611 if (xd_wait_for_IRQ())
612 return (1);
613 } else
614 if (indata)
615 *indata++ = inb(XD_DATA);
616 else
617 inb(XD_DATA);
618 break;
619 case STAT_COMMAND:
620 outb(command ? *command++ : 0,XD_DATA);
621 break;
622 case STAT_COMMAND | STAT_INPUT:
623 complete = 1;
624 break;
625 }
626 }
627 csb = inb(XD_DATA);
628
629 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
630 return (1);
631
632 if (csb & CSB_ERROR) { /* read sense data if error */
633 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
634 if (xd_command(cmdblk,0,sense,NULL,NULL,XD_TIMEOUT))
635 printk("xd: warning! sense command failed!\n");
636 }
637
638#ifdef DEBUG_COMMAND
639 printk("xd_command: completed with csb = 0x%X\n",csb);
640#endif /* DEBUG_COMMAND */
641
642 return (csb & CSB_ERROR);
643}
644
645static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
646{
647 u_char cmdblk[6],i,count = 0;
648
649 for (i = 0; i < XD_MAXDRIVES; i++) {
650 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
651 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
652 msleep_interruptible(XD_INIT_DISK_DELAY);
653
654 init_drive(count);
655 count++;
656
657 msleep_interruptible(XD_INIT_DISK_DELAY);
658 }
659 }
660 return (count);
661}
662
663static void __init xd_manual_geo_set (u_char drive)
664{
665 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
666 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
667 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
668}
669
670static void __init xd_dtc_init_controller (unsigned int address)
671{
672 switch (address) {
673 case 0x00000:
674 case 0xC8000: break; /*initial: 0x320 */
675 case 0xCA000: xd_iobase = 0x324;
676 case 0xD0000: /*5150CX*/
677 case 0xD8000: break; /*5150CX & 5150XL*/
678 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
679 break;
680 }
681 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
682
683 outb(0,XD_RESET); /* reset the controller */
684}
685
686
687static void __init xd_dtc5150cx_init_drive (u_char drive)
688{
689 /* values from controller's BIOS - BIOS chip may be removed */
690 static u_short geometry_table[][4] = {
691 {0x200,8,0x200,0x100},
692 {0x267,2,0x267,0x267},
693 {0x264,4,0x264,0x80},
694 {0x132,4,0x132,0x0},
695 {0x132,2,0x80, 0x132},
696 {0x177,8,0x177,0x0},
697 {0x132,8,0x84, 0x0},
698 {}, /* not used */
699 {0x132,6,0x80, 0x100},
700 {0x200,6,0x100,0x100},
701 {0x264,2,0x264,0x80},
702 {0x280,4,0x280,0x100},
703 {0x2B9,3,0x2B9,0x2B9},
704 {0x2B9,5,0x2B9,0x2B9},
705 {0x280,6,0x280,0x100},
706 {0x132,4,0x132,0x0}};
707 u_char n;
708
709 n = inb(XD_JUMPER);
710 n = (drive ? n : (n >> 2)) & 0x33;
711 n = (n | (n >> 2)) & 0x0F;
712 if (xd_geo[3*drive])
713 xd_manual_geo_set(drive);
714 else
715 if (n != 7) {
716 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
717 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
718 xd_info[drive].sectors = 17; /* sectors */
719#if 0
720 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
721 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
722 xd_info[drive].ecc = 0x0B; /* ecc length */
723#endif /* 0 */
724 }
725 else {
726 printk("xd%c: undetermined drive geometry\n",'a'+drive);
727 return;
728 }
729 xd_info[drive].control = 5; /* control byte */
730 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
731 xd_recalibrate(drive);
732}
733
734static void __init xd_dtc_init_drive (u_char drive)
735{
736 u_char cmdblk[6],buf[64];
737
738 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
739 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
740 xd_info[drive].heads = buf[0x0A]; /* heads */
741 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
742 xd_info[drive].sectors = 17; /* sectors */
743 if (xd_geo[3*drive])
744 xd_manual_geo_set(drive);
745#if 0
746 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
747 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
748 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
749#endif /* 0 */
750 xd_info[drive].control = 0; /* control byte */
751
752 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]);
753 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
754 if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
755 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
756 }
757 else
758 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
759}
760
761static void __init xd_wd_init_controller (unsigned int address)
762{
763 switch (address) {
764 case 0x00000:
765 case 0xC8000: break; /*initial: 0x320 */
766 case 0xCA000: xd_iobase = 0x324; break;
767 case 0xCC000: xd_iobase = 0x328; break;
768 case 0xCE000: xd_iobase = 0x32C; break;
769 case 0xD0000: xd_iobase = 0x328; break; /* ? */
770 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
771 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
772 break;
773 }
774 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
775
776 outb(0,XD_RESET); /* reset the controller */
777
778 msleep(XD_INIT_DISK_DELAY);
779}
780
781static void __init xd_wd_init_drive (u_char drive)
782{
783 /* values from controller's BIOS - BIOS may be disabled */
784 static u_short geometry_table[][4] = {
785 {0x264,4,0x1C2,0x1C2}, /* common part */
786 {0x132,4,0x099,0x0},
787 {0x267,2,0x1C2,0x1C2},
788 {0x267,4,0x1C2,0x1C2},
789
790 {0x334,6,0x335,0x335}, /* 1004 series RLL */
791 {0x30E,4,0x30F,0x3DC},
792 {0x30E,2,0x30F,0x30F},
793 {0x267,4,0x268,0x268},
794
795 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
796 {0x3DB,7,0x3DC,0x3DC},
797 {0x264,4,0x265,0x265},
798 {0x267,4,0x268,0x268}};
799
800 u_char cmdblk[6],buf[0x200];
801 u_char n = 0,rll,jumper_state,use_jumper_geo;
802 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
803
804 jumper_state = ~(inb(0x322));
805 if (jumper_state & 0x40)
806 xd_irq = 9;
807 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
808 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
809 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
810 xd_info[drive].heads = buf[0x1AF]; /* heads */
811 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
812 xd_info[drive].sectors = 17; /* sectors */
813 if (xd_geo[3*drive])
814 xd_manual_geo_set(drive);
815#if 0
816 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
817 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
818 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
819#endif /* 0 */
820 xd_info[drive].control = buf[0x1B5]; /* control byte */
821 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
822 if (xd_geo[3*drive]) {
823 xd_manual_geo_set(drive);
824 xd_info[drive].control = rll ? 7 : 5;
825 }
826 else if (use_jumper_geo) {
827 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
828 xd_info[drive].cylinders = geometry_table[n][0];
829 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
830 xd_info[drive].control = rll ? 7 : 5;
831#if 0
832 xd_info[drive].rwrite = geometry_table[n][2];
833 xd_info[drive].wprecomp = geometry_table[n][3];
834 xd_info[drive].ecc = 0x0B;
835#endif /* 0 */
836 }
837 if (!wd_1002) {
838 if (use_jumper_geo)
839 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
840 geometry_table[n][2],geometry_table[n][3],0x0B);
841 else
842 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
843 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
844 }
845 /* 1002 based RLL controller requests converted addressing, but reports physical
846 (physical 26 sec., logical 17 sec.)
847 1004 based ???? */
848 if (rll & wd_1002) {
849 if ((xd_info[drive].cylinders *= 26,
850 xd_info[drive].cylinders /= 17) > 1023)
851 xd_info[drive].cylinders = 1023; /* 1024 ? */
852#if 0
853 xd_info[drive].rwrite *= 26;
854 xd_info[drive].rwrite /= 17;
855 xd_info[drive].wprecomp *= 26
856 xd_info[drive].wprecomp /= 17;
857#endif /* 0 */
858 }
859 }
860 else
861 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
862
863}
864
865static void __init xd_seagate_init_controller (unsigned int address)
866{
867 switch (address) {
868 case 0x00000:
869 case 0xC8000: break; /*initial: 0x320 */
870 case 0xD0000: xd_iobase = 0x324; break;
871 case 0xD8000: xd_iobase = 0x328; break;
872 case 0xE0000: xd_iobase = 0x32C; break;
873 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
874 break;
875 }
876 xd_maxsectors = 0x40;
877
878 outb(0,XD_RESET); /* reset the controller */
879}
880
881static void __init xd_seagate_init_drive (u_char drive)
882{
883 u_char cmdblk[6],buf[0x200];
884
885 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
886 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
887 xd_info[drive].heads = buf[0x04]; /* heads */
888 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
889 xd_info[drive].sectors = buf[0x05]; /* sectors */
890 xd_info[drive].control = 0; /* control byte */
891 }
892 else
893 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
894}
895
896/* Omti support courtesy Dirk Melchers */
897static void __init xd_omti_init_controller (unsigned int address)
898{
899 switch (address) {
900 case 0x00000:
901 case 0xC8000: break; /*initial: 0x320 */
902 case 0xD0000: xd_iobase = 0x324; break;
903 case 0xD8000: xd_iobase = 0x328; break;
904 case 0xE0000: xd_iobase = 0x32C; break;
905 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
906 break;
907 }
908
909 xd_maxsectors = 0x40;
910
911 outb(0,XD_RESET); /* reset the controller */
912}
913
914static void __init xd_omti_init_drive (u_char drive)
915{
916 /* gets infos from drive */
917 xd_override_init_drive(drive);
918
919 /* set other parameters, Hardcoded, not that nice :-) */
920 xd_info[drive].control = 2;
921}
922
923/* Xebec support (AK) */
924static void __init xd_xebec_init_controller (unsigned int address)
925{
926/* iobase may be set manually in range 0x300 - 0x33C
927 irq may be set manually to 2(9),3,4,5,6,7
928 dma may be set manually to 1,2,3
929 (How to detect them ???)
930BIOS address may be set manually in range 0x0 - 0xF8000
931If you need non-standard settings use the xd=... command */
932
933 switch (address) {
934 case 0x00000:
935 case 0xC8000: /* initially: xd_iobase==0x320 */
936 case 0xD0000:
937 case 0xD2000:
938 case 0xD4000:
939 case 0xD6000:
940 case 0xD8000:
941 case 0xDA000:
942 case 0xDC000:
943 case 0xDE000:
944 case 0xE0000: break;
945 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
946 break;
947 }
948
949 xd_maxsectors = 0x01;
950 outb(0,XD_RESET); /* reset the controller */
951
952 msleep(XD_INIT_DISK_DELAY);
953}
954
955static void __init xd_xebec_init_drive (u_char drive)
956{
957 /* values from controller's BIOS - BIOS chip may be removed */
958 static u_short geometry_table[][5] = {
959 {0x132,4,0x080,0x080,0x7},
960 {0x132,4,0x080,0x080,0x17},
961 {0x264,2,0x100,0x100,0x7},
962 {0x264,2,0x100,0x100,0x17},
963 {0x132,8,0x080,0x080,0x7},
964 {0x132,8,0x080,0x080,0x17},
965 {0x264,4,0x100,0x100,0x6},
966 {0x264,4,0x100,0x100,0x17},
967 {0x2BC,5,0x2BC,0x12C,0x6},
968 {0x3A5,4,0x3A5,0x3A5,0x7},
969 {0x26C,6,0x26C,0x26C,0x7},
970 {0x200,8,0x200,0x100,0x17},
971 {0x400,5,0x400,0x400,0x7},
972 {0x400,6,0x400,0x400,0x7},
973 {0x264,8,0x264,0x200,0x17},
974 {0x33E,7,0x33E,0x200,0x7}};
975 u_char n;
976
977 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
978 is assumed for BOTH drives */
979 if (xd_geo[3*drive])
980 xd_manual_geo_set(drive);
981 else {
982 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
983 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
984 xd_info[drive].sectors = 17; /* sectors */
985#if 0
986 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
987 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
988 xd_info[drive].ecc = 0x0B; /* ecc length */
989#endif /* 0 */
990 }
991 xd_info[drive].control = geometry_table[n][4]; /* control byte */
992 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
993 xd_recalibrate(drive);
994}
995
996/* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
997 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
998static void __init xd_override_init_drive (u_char drive)
999{
1000 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
1001 u_char cmdblk[6],i;
1002
1003 if (xd_geo[3*drive])
1004 xd_manual_geo_set(drive);
1005 else {
1006 for (i = 0; i < 3; i++) {
1007 while (min[i] != max[i] - 1) {
1008 test[i] = (min[i] + max[i]) / 2;
1009 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
1010 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
1011 min[i] = test[i];
1012 else
1013 max[i] = test[i];
1014 }
1015 test[i] = min[i];
1016 }
1017 xd_info[drive].heads = (u_char) min[0] + 1;
1018 xd_info[drive].cylinders = (u_short) min[1] + 1;
1019 xd_info[drive].sectors = (u_char) min[2] + 1;
1020 }
1021 xd_info[drive].control = 0;
1022}
1023
1024/* xd_setup: initialise controller from command line parameters */
1025static void __init do_xd_setup (int *integers)
1026{
1027 switch (integers[0]) {
1028 case 4: if (integers[4] < 0)
1029 nodma = 1;
1030 else if (integers[4] < 8)
1031 xd_dma = integers[4];
1032 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1033 xd_iobase = integers[3];
1034 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1035 xd_irq = integers[2];
1036 case 1: xd_override = 1;
1037 if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
1038 xd_type = integers[1];
1039 case 0: break;
1040 default:printk("xd: too many parameters for xd\n");
1041 }
1042 xd_maxsectors = 0x01;
1043}
1044
1045/* xd_setparam: set the drive characteristics */
1046static 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)
1047{
1048 u_char cmdblk[14];
1049
1050 xd_build(cmdblk,command,drive,0,0,0,0,0);
1051 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1052 cmdblk[7] = (u_char) (cylinders & 0xFF);
1053 cmdblk[8] = heads & 0x1F;
1054 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1055 cmdblk[10] = (u_char) (rwrite & 0xFF);
1056 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1057 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1058 cmdblk[13] = ecc;
1059
1060 /* Some controllers require geometry info as data, not command */
1061
1062 if (xd_command(cmdblk,PIO_MODE,NULL,&cmdblk[6],NULL,XD_TIMEOUT * 2))
1063 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1064}
1065
1066
1067#ifdef MODULE
1068
1069module_param_array(xd, int, NULL, 0);
1070module_param_array(xd_geo, int, NULL, 0);
1071module_param(nodma, bool, 0);
1072
1073MODULE_LICENSE("GPL");
1074
1075void cleanup_module(void)
1076{
1077 int i;
1078 unregister_blkdev(XT_DISK_MAJOR, "xd");
1079 for (i = 0; i < xd_drives; i++) {
1080 del_gendisk(xd_gendisk[i]);
1081 put_disk(xd_gendisk[i]);
1082 }
1083 blk_cleanup_queue(xd_queue);
1084 release_region(xd_iobase,4);
1085 if (xd_drives) {
1086 free_irq(xd_irq, NULL);
1087 free_dma(xd_dma);
1088 if (xd_dma_buffer)
1089 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1090 }
1091}
1092#else
1093
1094static int __init xd_setup (char *str)
1095{
1096 int ints[5];
1097 get_options (str, ARRAY_SIZE (ints), ints);
1098 do_xd_setup (ints);
1099 return 1;
1100}
1101
1102/* xd_manual_geo_init: initialise drive geometry from command line parameters
1103 (used only for WD drives) */
1104static int __init xd_manual_geo_init (char *str)
1105{
1106 int i, integers[1 + 3*XD_MAXDRIVES];
1107
1108 get_options (str, ARRAY_SIZE (integers), integers);
1109 if (integers[0]%3 != 0) {
1110 printk("xd: incorrect number of parameters for xd_geo\n");
1111 return 1;
1112 }
1113 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1114 xd_geo[i] = integers[i+1];
1115 return 1;
1116}
1117
1118__setup ("xd=", xd_setup);
1119__setup ("xd_geo=", xd_manual_geo_init);
1120
1121#endif /* MODULE */
1122
1123module_init(xd_init);
1124MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);
1/*
2 * This file contains the driver for an XT hard disk controller
3 * (at least the DTC 5150X) for Linux.
4 *
5 * Author: Pat Mackinlay, pat@it.com.au
6 * Date: 29/09/92
7 *
8 * Revised: 01/01/93, ...
9 *
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.
14 *
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.
20 *
21 * Modularized: 04/10/96 by Todd Fries, tfries@umr.edu
22 *
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.
31 *
32 * Bugfix: 15/02/01, Paul G. - inform queue layer of tiny xd_maxsect.
33 *
34 */
35
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/mutex.h>
50#include <linux/blkpg.h>
51#include <linux/delay.h>
52#include <linux/io.h>
53#include <linux/gfp.h>
54
55#include <asm/uaccess.h>
56#include <asm/dma.h>
57
58#include "xd.h"
59
60static DEFINE_MUTEX(xd_mutex);
61static void __init do_xd_setup (int *integers);
62#ifdef MODULE
63static int xd[5] = { -1,-1,-1,-1, };
64#endif
65
66#define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
67 "nodma" module option */
68#define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
69
70/* Above may need to be increased if a problem with the 2nd drive detection
71 (ST11M controller) or resetting a controller (WD) appears */
72
73static XD_INFO xd_info[XD_MAXDRIVES];
74
75/* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
76 signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
77 few bytes of your controller's on-board ROM BIOS. To find out what yours is, use something like MS-DOS's DEBUG
78 command. Run DEBUG, and then you can examine your BIOS signature with:
79
80 d xxxx:0000
81
82 where xxxx is the segment of your controller (like C800 or D000 or something). On the ASCII dump at the right, you should
83 be able to see a string mentioning the manufacturer's copyright etc. Add this string into the table below. The parameters
84 in the table are, in order:
85
86 offset ; this is the offset (in bytes) from the start of your ROM where the signature starts
87 signature ; this is the actual text of the signature
88 xd_?_init_controller ; this is the controller init routine used by your controller
89 xd_?_init_drive ; this is the drive init routine used by your controller
90
91 The controllers directly supported at the moment are: DTC 5150x, WD 1004A27X, ST11M/R and override. If your controller is
92 made by the same manufacturer as one of these, try using the same init routines as they do. If that doesn't work, your
93 best bet is to use the "override" routines. These routines use a "portable" method of getting the disk's geometry, and
94 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>.
95
96 NOTE: You can now specify your XT controller's parameters from the command line in the form xd=TYPE,IRQ,IO,DMA. The driver
97 should be able to detect your drive's geometry from this info. (eg: xd=0,5,0x320,3 is the "standard"). */
98
99#include <asm/page.h>
100#define xd_dma_mem_alloc(size) __get_dma_pages(GFP_KERNEL,get_order(size))
101#define xd_dma_mem_free(addr, size) free_pages(addr, get_order(size))
102static char *xd_dma_buffer;
103
104static XD_SIGNATURE xd_sigs[] __initdata = {
105 { 0x0000,"Override geometry handler",NULL,xd_override_init_drive,"n unknown" }, /* Pat Mackinlay, pat@it.com.au */
106 { 0x0008,"[BXD06 (C) DTC 17-MAY-1985]",xd_dtc_init_controller,xd_dtc5150cx_init_drive," DTC 5150CX" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
107 { 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 */
108 { 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 */
109 { 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 */
110 { 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 */
111 { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
112 { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
113 { 0x0010,"ST11 BIOS v1.7",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11R" }, /* Alan Hourihane, alanh@fairlite.demon.co.uk */
114 { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
115 { 0x0006,"COPYRIGHT XEBEC (C) 1984",xd_xebec_init_controller,xd_xebec_init_drive," XEBEC" }, /* Andrzej Krzysztofowicz, ankry@mif.pg.gda.pl */
116 { 0x0008,"(C) Copyright 1984 Western Digital Corp", xd_wd_init_controller, xd_wd_init_drive," Western Dig. 1002s-wx2" },
117 { 0x0008,"(C) Copyright 1986 Western Digital Corporation", xd_wd_init_controller, xd_wd_init_drive," 1986 Western Digital" }, /* jfree@sovereign.org */
118};
119
120static unsigned int xd_bases[] __initdata =
121{
122 0xC8000, 0xCA000, 0xCC000,
123 0xCE000, 0xD0000, 0xD2000,
124 0xD4000, 0xD6000, 0xD8000,
125 0xDA000, 0xDC000, 0xDE000,
126 0xE0000
127};
128
129static DEFINE_SPINLOCK(xd_lock);
130
131static struct gendisk *xd_gendisk[2];
132
133static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
134
135static const struct block_device_operations xd_fops = {
136 .owner = THIS_MODULE,
137 .ioctl = xd_ioctl,
138 .getgeo = xd_getgeo,
139};
140static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
141static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
142static u_char xd_override __initdata = 0, xd_type __initdata = 0;
143static u_short xd_iobase = 0x320;
144static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
145
146static volatile int xdc_busy;
147static struct timer_list xd_watchdog_int;
148
149static volatile u_char xd_error;
150static bool nodma = XD_DONT_USE_DMA;
151
152static struct request_queue *xd_queue;
153
154/* xd_init: register the block device number and set up pointer tables */
155static int __init xd_init(void)
156{
157 u_char i,controller;
158 unsigned int address;
159 int err;
160
161#ifdef MODULE
162 {
163 u_char count = 0;
164 for (i = 4; i > 0; i--)
165 if (((xd[i] = xd[i-1]) >= 0) && !count)
166 count = i;
167 if ((xd[0] = count))
168 do_xd_setup(xd);
169 }
170#endif
171
172 init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
173
174 err = -EBUSY;
175 if (register_blkdev(XT_DISK_MAJOR, "xd"))
176 goto out1;
177
178 err = -ENOMEM;
179 xd_queue = blk_init_queue(do_xd_request, &xd_lock);
180 if (!xd_queue)
181 goto out1a;
182
183 if (xd_detect(&controller,&address)) {
184
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;
191 }
192 if (controller)
193 xd_sigs[controller].init_controller(address);
194 xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
195
196 printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
197 xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
198 }
199
200 /*
201 * With the drive detected, xd_maxsectors should now be known.
202 * If xd_maxsectors is 0, nothing was detected and we fall through
203 * to return -ENODEV
204 */
205 if (!xd_dma_buffer && xd_maxsectors) {
206 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
207 if (!xd_dma_buffer) {
208 printk(KERN_ERR "xd: Out of memory.\n");
209 goto out3;
210 }
211 }
212
213 err = -ENODEV;
214 if (!xd_drives)
215 goto out3;
216
217 for (i = 0; i < xd_drives; i++) {
218 XD_INFO *p = &xd_info[i];
219 struct gendisk *disk = alloc_disk(64);
220 if (!disk)
221 goto Enomem;
222 p->unit = i;
223 disk->major = XT_DISK_MAJOR;
224 disk->first_minor = i<<6;
225 sprintf(disk->disk_name, "xd%c", i+'a');
226 disk->fops = &xd_fops;
227 disk->private_data = p;
228 disk->queue = xd_queue;
229 set_capacity(disk, p->heads * p->cylinders * p->sectors);
230 printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
231 p->cylinders, p->heads, p->sectors);
232 xd_gendisk[i] = disk;
233 }
234
235 err = -EBUSY;
236 if (request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
237 printk("xd: unable to get IRQ%d\n",xd_irq);
238 goto out4;
239 }
240
241 if (request_dma(xd_dma,"xd")) {
242 printk("xd: unable to get DMA%d\n",xd_dma);
243 goto out5;
244 }
245
246 /* xd_maxsectors depends on controller - so set after detection */
247 blk_queue_max_hw_sectors(xd_queue, xd_maxsectors);
248
249 for (i = 0; i < xd_drives; i++)
250 add_disk(xd_gendisk[i]);
251
252 return 0;
253
254out5:
255 free_irq(xd_irq, NULL);
256out4:
257 for (i = 0; i < xd_drives; i++)
258 put_disk(xd_gendisk[i]);
259out3:
260 if (xd_maxsectors)
261 release_region(xd_iobase,4);
262
263 if (xd_dma_buffer)
264 xd_dma_mem_free((unsigned long)xd_dma_buffer,
265 xd_maxsectors * 0x200);
266out2:
267 blk_cleanup_queue(xd_queue);
268out1a:
269 unregister_blkdev(XT_DISK_MAJOR, "xd");
270out1:
271 return err;
272Enomem:
273 err = -ENOMEM;
274 while (i--)
275 put_disk(xd_gendisk[i]);
276 goto out3;
277}
278
279/* xd_detect: scan the possible BIOS ROM locations for the signature strings */
280static u_char __init xd_detect (u_char *controller, unsigned int *address)
281{
282 int i, j;
283
284 if (xd_override)
285 {
286 *controller = xd_type;
287 *address = 0;
288 return(1);
289 }
290
291 for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
292 void __iomem *p = ioremap(xd_bases[i], 0x2000);
293 if (!p)
294 continue;
295 for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
296 const char *s = xd_sigs[j].string;
297 if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
298 *controller = j;
299 xd_type = j;
300 *address = xd_bases[i];
301 iounmap(p);
302 return 1;
303 }
304 }
305 iounmap(p);
306 }
307 return 0;
308}
309
310/* do_xd_request: handle an incoming request */
311static void do_xd_request (struct request_queue * q)
312{
313 struct request *req;
314
315 if (xdc_busy)
316 return;
317
318 req = blk_fetch_request(q);
319 while (req) {
320 unsigned block = blk_rq_pos(req);
321 unsigned count = blk_rq_cur_sectors(req);
322 XD_INFO *disk = req->rq_disk->private_data;
323 int res = -EIO;
324 int retry;
325
326 if (req->cmd_type != REQ_TYPE_FS)
327 goto done;
328 if (block + count > get_capacity(req->rq_disk))
329 goto done;
330 for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
331 res = xd_readwrite(rq_data_dir(req), disk, req->buffer,
332 block, count);
333 done:
334 /* wrap up, 0 = success, -errno = fail */
335 if (!__blk_end_request_cur(req, res))
336 req = blk_fetch_request(q);
337 }
338}
339
340static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
341{
342 XD_INFO *p = bdev->bd_disk->private_data;
343
344 geo->heads = p->heads;
345 geo->sectors = p->sectors;
346 geo->cylinders = p->cylinders;
347 return 0;
348}
349
350/* xd_ioctl: handle device ioctl's */
351static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg)
352{
353 switch (cmd) {
354 case HDIO_SET_DMA:
355 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
356 if (xdc_busy) return -EBUSY;
357 nodma = !arg;
358 if (nodma && xd_dma_buffer) {
359 xd_dma_mem_free((unsigned long)xd_dma_buffer,
360 xd_maxsectors * 0x200);
361 xd_dma_buffer = NULL;
362 } else if (!nodma && !xd_dma_buffer) {
363 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
364 if (!xd_dma_buffer) {
365 nodma = XD_DONT_USE_DMA;
366 return -ENOMEM;
367 }
368 }
369 return 0;
370 case HDIO_GET_DMA:
371 return put_user(!nodma, (long __user *) arg);
372 case HDIO_GET_MULTCOUNT:
373 return put_user(xd_maxsectors, (long __user *) arg);
374 default:
375 return -EINVAL;
376 }
377}
378
379static int xd_ioctl(struct block_device *bdev, fmode_t mode,
380 unsigned int cmd, unsigned long param)
381{
382 int ret;
383
384 mutex_lock(&xd_mutex);
385 ret = xd_locked_ioctl(bdev, mode, cmd, param);
386 mutex_unlock(&xd_mutex);
387
388 return ret;
389}
390
391/* xd_readwrite: handle a read/write request */
392static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
393{
394 int drive = p->unit;
395 u_char cmdblk[6],sense[4];
396 u_short track,cylinder;
397 u_char head,sector,control,mode = PIO_MODE,temp;
398 char **real_buffer;
399 register int i;
400
401#ifdef DEBUG_READWRITE
402 printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
403#endif /* DEBUG_READWRITE */
404
405 spin_unlock_irq(&xd_lock);
406
407 control = p->control;
408 if (!xd_dma_buffer)
409 xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
410 while (count) {
411 temp = count < xd_maxsectors ? count : xd_maxsectors;
412
413 track = block / p->sectors;
414 head = track % p->heads;
415 cylinder = track / p->heads;
416 sector = block % p->sectors;
417
418#ifdef DEBUG_READWRITE
419 printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
420#endif /* DEBUG_READWRITE */
421
422 if (xd_dma_buffer) {
423 mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
424 real_buffer = &xd_dma_buffer;
425 for (i=0; i < (temp * 0x200); i++)
426 xd_dma_buffer[i] = buffer[i];
427 }
428 else
429 real_buffer = &buffer;
430
431 xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
432
433 switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
434 case 1:
435 printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
436 xd_recalibrate(drive);
437 spin_lock_irq(&xd_lock);
438 return -EIO;
439 case 2:
440 if (sense[0] & 0x30) {
441 printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
442 switch ((sense[0] & 0x30) >> 4) {
443 case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
444 break;
445 case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
446 break;
447 case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
448 break;
449 case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
450 break;
451 }
452 }
453 if (sense[0] & 0x80)
454 printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
455 /* reported drive number = (sense[1] & 0xE0) >> 5 */
456 else
457 printk(" - no valid disk address\n");
458 spin_lock_irq(&xd_lock);
459 return -EIO;
460 }
461 if (xd_dma_buffer)
462 for (i=0; i < (temp * 0x200); i++)
463 buffer[i] = xd_dma_buffer[i];
464
465 count -= temp, buffer += temp * 0x200, block += temp;
466 }
467 spin_lock_irq(&xd_lock);
468 return 0;
469}
470
471/* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
472static void xd_recalibrate (u_char drive)
473{
474 u_char cmdblk[6];
475
476 xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
477 if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 8))
478 printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
479}
480
481/* xd_interrupt_handler: interrupt service routine */
482static irqreturn_t xd_interrupt_handler(int irq, void *dev_id)
483{
484 if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
485#ifdef DEBUG_OTHER
486 printk("xd_interrupt_handler: interrupt detected\n");
487#endif /* DEBUG_OTHER */
488 outb(0,XD_CONTROL); /* acknowledge interrupt */
489 wake_up(&xd_wait_int); /* and wake up sleeping processes */
490 return IRQ_HANDLED;
491 }
492 else
493 printk("xd: unexpected interrupt\n");
494 return IRQ_NONE;
495}
496
497/* xd_setup_dma: set up the DMA controller for a data transfer */
498static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
499{
500 unsigned long f;
501
502 if (nodma)
503 return (PIO_MODE);
504 if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
505#ifdef DEBUG_OTHER
506 printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
507#endif /* DEBUG_OTHER */
508 return (PIO_MODE);
509 }
510
511 f=claim_dma_lock();
512 disable_dma(xd_dma);
513 clear_dma_ff(xd_dma);
514 set_dma_mode(xd_dma,mode);
515 set_dma_addr(xd_dma, (unsigned long) buffer);
516 set_dma_count(xd_dma,count);
517
518 release_dma_lock(f);
519
520 return (DMA_MODE); /* use DMA and INT */
521}
522
523/* xd_build: put stuff into an array in a format suitable for the controller */
524static 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)
525{
526 cmdblk[0] = command;
527 cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
528 cmdblk[2] = ((cylinder & 0x300) >> 2) | (sector & 0x3F);
529 cmdblk[3] = cylinder & 0xFF;
530 cmdblk[4] = count;
531 cmdblk[5] = control;
532
533 return (cmdblk);
534}
535
536static void xd_watchdog (unsigned long unused)
537{
538 xd_error = 1;
539 wake_up(&xd_wait_int);
540}
541
542/* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
543static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
544{
545 u_long expiry = jiffies + timeout;
546 int success;
547
548 xdc_busy = 1;
549 while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
550 schedule_timeout_uninterruptible(1);
551 xdc_busy = 0;
552 return (success);
553}
554
555static inline u_int xd_wait_for_IRQ (void)
556{
557 unsigned long flags;
558 xd_watchdog_int.expires = jiffies + 8 * HZ;
559 add_timer(&xd_watchdog_int);
560
561 flags=claim_dma_lock();
562 enable_dma(xd_dma);
563 release_dma_lock(flags);
564
565 sleep_on(&xd_wait_int);
566 del_timer(&xd_watchdog_int);
567 xdc_busy = 0;
568
569 flags=claim_dma_lock();
570 disable_dma(xd_dma);
571 release_dma_lock(flags);
572
573 if (xd_error) {
574 printk("xd: missed IRQ - command aborted\n");
575 xd_error = 0;
576 return (1);
577 }
578 return (0);
579}
580
581/* xd_command: handle all data transfers necessary for a single command */
582static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
583{
584 u_char cmdblk[6],csb,complete = 0;
585
586#ifdef DEBUG_COMMAND
587 printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
588#endif /* DEBUG_COMMAND */
589
590 outb(0,XD_SELECT);
591 outb(mode,XD_CONTROL);
592
593 if (xd_waitport(XD_STATUS,STAT_SELECT,STAT_SELECT,timeout))
594 return (1);
595
596 while (!complete) {
597 if (xd_waitport(XD_STATUS,STAT_READY,STAT_READY,timeout))
598 return (1);
599
600 switch (inb(XD_STATUS) & (STAT_COMMAND | STAT_INPUT)) {
601 case 0:
602 if (mode == DMA_MODE) {
603 if (xd_wait_for_IRQ())
604 return (1);
605 } else
606 outb(outdata ? *outdata++ : 0,XD_DATA);
607 break;
608 case STAT_INPUT:
609 if (mode == DMA_MODE) {
610 if (xd_wait_for_IRQ())
611 return (1);
612 } else
613 if (indata)
614 *indata++ = inb(XD_DATA);
615 else
616 inb(XD_DATA);
617 break;
618 case STAT_COMMAND:
619 outb(command ? *command++ : 0,XD_DATA);
620 break;
621 case STAT_COMMAND | STAT_INPUT:
622 complete = 1;
623 break;
624 }
625 }
626 csb = inb(XD_DATA);
627
628 if (xd_waitport(XD_STATUS,0,STAT_SELECT,timeout)) /* wait until deselected */
629 return (1);
630
631 if (csb & CSB_ERROR) { /* read sense data if error */
632 xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
633 if (xd_command(cmdblk,0,sense,NULL,NULL,XD_TIMEOUT))
634 printk("xd: warning! sense command failed!\n");
635 }
636
637#ifdef DEBUG_COMMAND
638 printk("xd_command: completed with csb = 0x%X\n",csb);
639#endif /* DEBUG_COMMAND */
640
641 return (csb & CSB_ERROR);
642}
643
644static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
645{
646 u_char cmdblk[6],i,count = 0;
647
648 for (i = 0; i < XD_MAXDRIVES; i++) {
649 xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
650 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
651 msleep_interruptible(XD_INIT_DISK_DELAY);
652
653 init_drive(count);
654 count++;
655
656 msleep_interruptible(XD_INIT_DISK_DELAY);
657 }
658 }
659 return (count);
660}
661
662static void __init xd_manual_geo_set (u_char drive)
663{
664 xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
665 xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
666 xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
667}
668
669static void __init xd_dtc_init_controller (unsigned int address)
670{
671 switch (address) {
672 case 0x00000:
673 case 0xC8000: break; /*initial: 0x320 */
674 case 0xCA000: xd_iobase = 0x324;
675 case 0xD0000: /*5150CX*/
676 case 0xD8000: break; /*5150CX & 5150XL*/
677 default: printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
678 break;
679 }
680 xd_maxsectors = 0x01; /* my card seems to have trouble doing multi-block transfers? */
681
682 outb(0,XD_RESET); /* reset the controller */
683}
684
685
686static void __init xd_dtc5150cx_init_drive (u_char drive)
687{
688 /* values from controller's BIOS - BIOS chip may be removed */
689 static u_short geometry_table[][4] = {
690 {0x200,8,0x200,0x100},
691 {0x267,2,0x267,0x267},
692 {0x264,4,0x264,0x80},
693 {0x132,4,0x132,0x0},
694 {0x132,2,0x80, 0x132},
695 {0x177,8,0x177,0x0},
696 {0x132,8,0x84, 0x0},
697 {}, /* not used */
698 {0x132,6,0x80, 0x100},
699 {0x200,6,0x100,0x100},
700 {0x264,2,0x264,0x80},
701 {0x280,4,0x280,0x100},
702 {0x2B9,3,0x2B9,0x2B9},
703 {0x2B9,5,0x2B9,0x2B9},
704 {0x280,6,0x280,0x100},
705 {0x132,4,0x132,0x0}};
706 u_char n;
707
708 n = inb(XD_JUMPER);
709 n = (drive ? n : (n >> 2)) & 0x33;
710 n = (n | (n >> 2)) & 0x0F;
711 if (xd_geo[3*drive])
712 xd_manual_geo_set(drive);
713 else
714 if (n != 7) {
715 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
716 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
717 xd_info[drive].sectors = 17; /* sectors */
718#if 0
719 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
720 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
721 xd_info[drive].ecc = 0x0B; /* ecc length */
722#endif /* 0 */
723 }
724 else {
725 printk("xd%c: undetermined drive geometry\n",'a'+drive);
726 return;
727 }
728 xd_info[drive].control = 5; /* control byte */
729 xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
730 xd_recalibrate(drive);
731}
732
733static void __init xd_dtc_init_drive (u_char drive)
734{
735 u_char cmdblk[6],buf[64];
736
737 xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
738 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
739 xd_info[drive].heads = buf[0x0A]; /* heads */
740 xd_info[drive].cylinders = ((u_short *) (buf))[0x04]; /* cylinders */
741 xd_info[drive].sectors = 17; /* sectors */
742 if (xd_geo[3*drive])
743 xd_manual_geo_set(drive);
744#if 0
745 xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05]; /* reduced write */
746 xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06]; /* write precomp */
747 xd_info[drive].ecc = buf[0x0F]; /* ecc length */
748#endif /* 0 */
749 xd_info[drive].control = 0; /* control byte */
750
751 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]);
752 xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
753 if (xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
754 printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
755 }
756 else
757 printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
758}
759
760static void __init xd_wd_init_controller (unsigned int address)
761{
762 switch (address) {
763 case 0x00000:
764 case 0xC8000: break; /*initial: 0x320 */
765 case 0xCA000: xd_iobase = 0x324; break;
766 case 0xCC000: xd_iobase = 0x328; break;
767 case 0xCE000: xd_iobase = 0x32C; break;
768 case 0xD0000: xd_iobase = 0x328; break; /* ? */
769 case 0xD8000: xd_iobase = 0x32C; break; /* ? */
770 default: printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
771 break;
772 }
773 xd_maxsectors = 0x01; /* this one doesn't wrap properly either... */
774
775 outb(0,XD_RESET); /* reset the controller */
776
777 msleep(XD_INIT_DISK_DELAY);
778}
779
780static void __init xd_wd_init_drive (u_char drive)
781{
782 /* values from controller's BIOS - BIOS may be disabled */
783 static u_short geometry_table[][4] = {
784 {0x264,4,0x1C2,0x1C2}, /* common part */
785 {0x132,4,0x099,0x0},
786 {0x267,2,0x1C2,0x1C2},
787 {0x267,4,0x1C2,0x1C2},
788
789 {0x334,6,0x335,0x335}, /* 1004 series RLL */
790 {0x30E,4,0x30F,0x3DC},
791 {0x30E,2,0x30F,0x30F},
792 {0x267,4,0x268,0x268},
793
794 {0x3D5,5,0x3D6,0x3D6}, /* 1002 series RLL */
795 {0x3DB,7,0x3DC,0x3DC},
796 {0x264,4,0x265,0x265},
797 {0x267,4,0x268,0x268}};
798
799 u_char cmdblk[6],buf[0x200];
800 u_char n = 0,rll,jumper_state,use_jumper_geo;
801 u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
802
803 jumper_state = ~(inb(0x322));
804 if (jumper_state & 0x40)
805 xd_irq = 9;
806 rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;
807 xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
808 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
809 xd_info[drive].heads = buf[0x1AF]; /* heads */
810 xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6]; /* cylinders */
811 xd_info[drive].sectors = 17; /* sectors */
812 if (xd_geo[3*drive])
813 xd_manual_geo_set(drive);
814#if 0
815 xd_info[drive].rwrite = ((u_short *) (buf))[0xD8]; /* reduced write */
816 xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA]; /* write precomp */
817 xd_info[drive].ecc = buf[0x1B4]; /* ecc length */
818#endif /* 0 */
819 xd_info[drive].control = buf[0x1B5]; /* control byte */
820 use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);
821 if (xd_geo[3*drive]) {
822 xd_manual_geo_set(drive);
823 xd_info[drive].control = rll ? 7 : 5;
824 }
825 else if (use_jumper_geo) {
826 n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
827 xd_info[drive].cylinders = geometry_table[n][0];
828 xd_info[drive].heads = (u_char)(geometry_table[n][1]);
829 xd_info[drive].control = rll ? 7 : 5;
830#if 0
831 xd_info[drive].rwrite = geometry_table[n][2];
832 xd_info[drive].wprecomp = geometry_table[n][3];
833 xd_info[drive].ecc = 0x0B;
834#endif /* 0 */
835 }
836 if (!wd_1002) {
837 if (use_jumper_geo)
838 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
839 geometry_table[n][2],geometry_table[n][3],0x0B);
840 else
841 xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
842 ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
843 }
844 /* 1002 based RLL controller requests converted addressing, but reports physical
845 (physical 26 sec., logical 17 sec.)
846 1004 based ???? */
847 if (rll & wd_1002) {
848 if ((xd_info[drive].cylinders *= 26,
849 xd_info[drive].cylinders /= 17) > 1023)
850 xd_info[drive].cylinders = 1023; /* 1024 ? */
851#if 0
852 xd_info[drive].rwrite *= 26;
853 xd_info[drive].rwrite /= 17;
854 xd_info[drive].wprecomp *= 26
855 xd_info[drive].wprecomp /= 17;
856#endif /* 0 */
857 }
858 }
859 else
860 printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);
861
862}
863
864static void __init xd_seagate_init_controller (unsigned int address)
865{
866 switch (address) {
867 case 0x00000:
868 case 0xC8000: break; /*initial: 0x320 */
869 case 0xD0000: xd_iobase = 0x324; break;
870 case 0xD8000: xd_iobase = 0x328; break;
871 case 0xE0000: xd_iobase = 0x32C; break;
872 default: printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
873 break;
874 }
875 xd_maxsectors = 0x40;
876
877 outb(0,XD_RESET); /* reset the controller */
878}
879
880static void __init xd_seagate_init_drive (u_char drive)
881{
882 u_char cmdblk[6],buf[0x200];
883
884 xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
885 if (!xd_command(cmdblk,PIO_MODE,buf,NULL,NULL,XD_TIMEOUT * 2)) {
886 xd_info[drive].heads = buf[0x04]; /* heads */
887 xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03]; /* cylinders */
888 xd_info[drive].sectors = buf[0x05]; /* sectors */
889 xd_info[drive].control = 0; /* control byte */
890 }
891 else
892 printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
893}
894
895/* Omti support courtesy Dirk Melchers */
896static void __init xd_omti_init_controller (unsigned int address)
897{
898 switch (address) {
899 case 0x00000:
900 case 0xC8000: break; /*initial: 0x320 */
901 case 0xD0000: xd_iobase = 0x324; break;
902 case 0xD8000: xd_iobase = 0x328; break;
903 case 0xE0000: xd_iobase = 0x32C; break;
904 default: printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
905 break;
906 }
907
908 xd_maxsectors = 0x40;
909
910 outb(0,XD_RESET); /* reset the controller */
911}
912
913static void __init xd_omti_init_drive (u_char drive)
914{
915 /* gets infos from drive */
916 xd_override_init_drive(drive);
917
918 /* set other parameters, Hardcoded, not that nice :-) */
919 xd_info[drive].control = 2;
920}
921
922/* Xebec support (AK) */
923static void __init xd_xebec_init_controller (unsigned int address)
924{
925/* iobase may be set manually in range 0x300 - 0x33C
926 irq may be set manually to 2(9),3,4,5,6,7
927 dma may be set manually to 1,2,3
928 (How to detect them ???)
929BIOS address may be set manually in range 0x0 - 0xF8000
930If you need non-standard settings use the xd=... command */
931
932 switch (address) {
933 case 0x00000:
934 case 0xC8000: /* initially: xd_iobase==0x320 */
935 case 0xD0000:
936 case 0xD2000:
937 case 0xD4000:
938 case 0xD6000:
939 case 0xD8000:
940 case 0xDA000:
941 case 0xDC000:
942 case 0xDE000:
943 case 0xE0000: break;
944 default: printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
945 break;
946 }
947
948 xd_maxsectors = 0x01;
949 outb(0,XD_RESET); /* reset the controller */
950
951 msleep(XD_INIT_DISK_DELAY);
952}
953
954static void __init xd_xebec_init_drive (u_char drive)
955{
956 /* values from controller's BIOS - BIOS chip may be removed */
957 static u_short geometry_table[][5] = {
958 {0x132,4,0x080,0x080,0x7},
959 {0x132,4,0x080,0x080,0x17},
960 {0x264,2,0x100,0x100,0x7},
961 {0x264,2,0x100,0x100,0x17},
962 {0x132,8,0x080,0x080,0x7},
963 {0x132,8,0x080,0x080,0x17},
964 {0x264,4,0x100,0x100,0x6},
965 {0x264,4,0x100,0x100,0x17},
966 {0x2BC,5,0x2BC,0x12C,0x6},
967 {0x3A5,4,0x3A5,0x3A5,0x7},
968 {0x26C,6,0x26C,0x26C,0x7},
969 {0x200,8,0x200,0x100,0x17},
970 {0x400,5,0x400,0x400,0x7},
971 {0x400,6,0x400,0x400,0x7},
972 {0x264,8,0x264,0x200,0x17},
973 {0x33E,7,0x33E,0x200,0x7}};
974 u_char n;
975
976 n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry
977 is assumed for BOTH drives */
978 if (xd_geo[3*drive])
979 xd_manual_geo_set(drive);
980 else {
981 xd_info[drive].heads = (u_char)(geometry_table[n][1]); /* heads */
982 xd_info[drive].cylinders = geometry_table[n][0]; /* cylinders */
983 xd_info[drive].sectors = 17; /* sectors */
984#if 0
985 xd_info[drive].rwrite = geometry_table[n][2]; /* reduced write */
986 xd_info[drive].precomp = geometry_table[n][3] /* write precomp */
987 xd_info[drive].ecc = 0x0B; /* ecc length */
988#endif /* 0 */
989 }
990 xd_info[drive].control = geometry_table[n][4]; /* control byte */
991 xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);
992 xd_recalibrate(drive);
993}
994
995/* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
996 etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
997static void __init xd_override_init_drive (u_char drive)
998{
999 u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
1000 u_char cmdblk[6],i;
1001
1002 if (xd_geo[3*drive])
1003 xd_manual_geo_set(drive);
1004 else {
1005 for (i = 0; i < 3; i++) {
1006 while (min[i] != max[i] - 1) {
1007 test[i] = (min[i] + max[i]) / 2;
1008 xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
1009 if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT * 2))
1010 min[i] = test[i];
1011 else
1012 max[i] = test[i];
1013 }
1014 test[i] = min[i];
1015 }
1016 xd_info[drive].heads = (u_char) min[0] + 1;
1017 xd_info[drive].cylinders = (u_short) min[1] + 1;
1018 xd_info[drive].sectors = (u_char) min[2] + 1;
1019 }
1020 xd_info[drive].control = 0;
1021}
1022
1023/* xd_setup: initialise controller from command line parameters */
1024static void __init do_xd_setup (int *integers)
1025{
1026 switch (integers[0]) {
1027 case 4: if (integers[4] < 0)
1028 nodma = 1;
1029 else if (integers[4] < 8)
1030 xd_dma = integers[4];
1031 case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))
1032 xd_iobase = integers[3];
1033 case 2: if ((integers[2] > 0) && (integers[2] < 16))
1034 xd_irq = integers[2];
1035 case 1: xd_override = 1;
1036 if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
1037 xd_type = integers[1];
1038 case 0: break;
1039 default:printk("xd: too many parameters for xd\n");
1040 }
1041 xd_maxsectors = 0x01;
1042}
1043
1044/* xd_setparam: set the drive characteristics */
1045static 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)
1046{
1047 u_char cmdblk[14];
1048
1049 xd_build(cmdblk,command,drive,0,0,0,0,0);
1050 cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
1051 cmdblk[7] = (u_char) (cylinders & 0xFF);
1052 cmdblk[8] = heads & 0x1F;
1053 cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
1054 cmdblk[10] = (u_char) (rwrite & 0xFF);
1055 cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
1056 cmdblk[12] = (u_char) (wprecomp & 0xFF);
1057 cmdblk[13] = ecc;
1058
1059 /* Some controllers require geometry info as data, not command */
1060
1061 if (xd_command(cmdblk,PIO_MODE,NULL,&cmdblk[6],NULL,XD_TIMEOUT * 2))
1062 printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
1063}
1064
1065
1066#ifdef MODULE
1067
1068module_param_array(xd, int, NULL, 0);
1069module_param_array(xd_geo, int, NULL, 0);
1070module_param(nodma, bool, 0);
1071
1072MODULE_LICENSE("GPL");
1073
1074void cleanup_module(void)
1075{
1076 int i;
1077 unregister_blkdev(XT_DISK_MAJOR, "xd");
1078 for (i = 0; i < xd_drives; i++) {
1079 del_gendisk(xd_gendisk[i]);
1080 put_disk(xd_gendisk[i]);
1081 }
1082 blk_cleanup_queue(xd_queue);
1083 release_region(xd_iobase,4);
1084 if (xd_drives) {
1085 free_irq(xd_irq, NULL);
1086 free_dma(xd_dma);
1087 if (xd_dma_buffer)
1088 xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
1089 }
1090}
1091#else
1092
1093static int __init xd_setup (char *str)
1094{
1095 int ints[5];
1096 get_options (str, ARRAY_SIZE (ints), ints);
1097 do_xd_setup (ints);
1098 return 1;
1099}
1100
1101/* xd_manual_geo_init: initialise drive geometry from command line parameters
1102 (used only for WD drives) */
1103static int __init xd_manual_geo_init (char *str)
1104{
1105 int i, integers[1 + 3*XD_MAXDRIVES];
1106
1107 get_options (str, ARRAY_SIZE (integers), integers);
1108 if (integers[0]%3 != 0) {
1109 printk("xd: incorrect number of parameters for xd_geo\n");
1110 return 1;
1111 }
1112 for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)
1113 xd_geo[i] = integers[i+1];
1114 return 1;
1115}
1116
1117__setup ("xd=", xd_setup);
1118__setup ("xd_geo=", xd_manual_geo_init);
1119
1120#endif /* MODULE */
1121
1122module_init(xd_init);
1123MODULE_ALIAS_BLOCKDEV_MAJOR(XT_DISK_MAJOR);