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