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