1 /* $Id$ 2 * 1993/03/31 3 * linux/kernel/aha1740.c 4 * 5 * Based loosely on aha1542.c which is 6 * Copyright (C) 1992 Tommy Thorn and 7 * Modified by Eric Youngdale 8 * 9 * This file is aha1740.c, written and 10 * Copyright (C) 1992,1993 Brad McLean 11 * brad@saturn.gaylord.com or brad@bradpc.gaylord.com. 12 * 13 * Modifications to makecode and queuecommand 14 * for proper handling of multiple devices courteously 15 * provided by Michael Weller, March, 1993 16 * 17 * Multiple adapter support, extended translation detection, 18 * update to current scsi subsystem changes, proc fs support, 19 * working (!) module support based on patches from Andreas Arens, 20 * by Andreas Degert <ad@papyrus.hamburg.com>, 2/1997 21 * 22 * aha1740_makecode may still need even more work 23 * if it doesn't work for your devices, take a look. 24 * 25 * Reworked for new_eh and new locking by Alan Cox <alan@lxorguk.ukuu.org.uk> 26 * 27 * Converted to EISA and generic DMA APIs by Marc Zyngier 28 * <maz@wild-wind.fr.eu.org>, 4/2003. 29 * 30 * Shared interrupt support added by Rask Ingemann Lambertsen 31 * <rask@sygehus.dk>, 10/2003 32 * 33 * For the avoidance of doubt the "preferred form" of this code is one which 34 * is in an open non patent encumbered format. Where cryptographic key signing 35 * forms part of the process of creating an executable the information 36 * including keys needed to generate an equivalently functional executable 37 * are deemed to be part of the source code. 38 */ 39 40 #include <linux/blkdev.h> 41 #include <linux/interrupt.h> 42 #include <linux/module.h> 43 #include <linux/kernel.h> 44 #include <linux/types.h> 45 #include <linux/string.h> 46 #include <linux/ioport.h> 47 #include <linux/proc_fs.h> 48 #include <linux/stat.h> 49 #include <linux/init.h> 50 #include <linux/device.h> 51 #include <linux/eisa.h> 52 #include <linux/dma-mapping.h> 53 #include <linux/gfp.h> 54 55 #include <asm/dma.h> 56 #include <asm/io.h> 57 58 #include "scsi.h" 59 #include <scsi/scsi_host.h> 60 #include "aha1740.h" 61 62 /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH 63 IT WORK, THEN: 64 #define DEBUG 65 */ 66 #ifdef DEBUG 67 #define DEB(x) x 68 #else 69 #define DEB(x) 70 #endif 71 72 struct aha1740_hostdata { 73 struct eisa_device *edev; 74 unsigned int translation; 75 unsigned int last_ecb_used; 76 dma_addr_t ecb_dma_addr; 77 struct ecb ecb[AHA1740_ECBS]; 78 }; 79 80 struct aha1740_sg { 81 struct aha1740_chain sg_chain[AHA1740_SCATTER]; 82 dma_addr_t sg_dma_addr; 83 dma_addr_t buf_dma_addr; 84 }; 85 86 #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata) 87 88 static inline struct ecb *ecb_dma_to_cpu (struct Scsi_Host *host, 89 dma_addr_t dma) 90 { 91 struct aha1740_hostdata *hdata = HOSTDATA (host); 92 dma_addr_t offset; 93 94 offset = dma - hdata->ecb_dma_addr; 95 96 return (struct ecb *)(((char *) hdata->ecb) + (unsigned int) offset); 97 } 98 99 static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu) 100 { 101 struct aha1740_hostdata *hdata = HOSTDATA (host); 102 dma_addr_t offset; 103 104 offset = (char *) cpu - (char *) hdata->ecb; 105 106 return hdata->ecb_dma_addr + offset; 107 } 108 109 static int aha1740_show_info(struct seq_file *m, struct Scsi_Host *shpnt) 110 { 111 struct aha1740_hostdata *host = HOSTDATA(shpnt); 112 seq_printf(m, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n" 113 "Extended translation %sabled.\n", 114 shpnt->io_port, shpnt->irq, host->edev->slot, 115 host->translation ? "en" : "dis"); 116 return 0; 117 } 118 119 static int aha1740_makecode(unchar *sense, unchar *status) 120 { 121 struct statusword 122 { 123 ushort don:1, /* Command Done - No Error */ 124 du:1, /* Data underrun */ 125 :1, qf:1, /* Queue full */ 126 sc:1, /* Specification Check */ 127 dor:1, /* Data overrun */ 128 ch:1, /* Chaining Halted */ 129 intr:1, /* Interrupt issued */ 130 asa:1, /* Additional Status Available */ 131 sns:1, /* Sense information Stored */ 132 :1, ini:1, /* Initialization Required */ 133 me:1, /* Major error or exception */ 134 :1, eca:1, /* Extended Contingent alliance */ 135 :1; 136 } status_word; 137 int retval = DID_OK; 138 139 status_word = * (struct statusword *) status; 140 #ifdef DEBUG 141 printk("makecode from %x,%x,%x,%x %x,%x,%x,%x", 142 status[0], status[1], status[2], status[3], 143 sense[0], sense[1], sense[2], sense[3]); 144 #endif 145 if (!status_word.don) { /* Anything abnormal was detected */ 146 if ( (status[1]&0x18) || status_word.sc ) { 147 /*Additional info available*/ 148 /* Use the supplied info for further diagnostics */ 149 switch ( status[2] ) { 150 case 0x12: 151 if ( status_word.dor ) 152 retval=DID_ERROR; /* It's an Overrun */ 153 /* If not overrun, assume underrun and 154 * ignore it! */ 155 case 0x00: /* No info, assume no error, should 156 * not occur */ 157 break; 158 case 0x11: 159 case 0x21: 160 retval=DID_TIME_OUT; 161 break; 162 case 0x0a: 163 retval=DID_BAD_TARGET; 164 break; 165 case 0x04: 166 case 0x05: 167 retval=DID_ABORT; 168 /* Either by this driver or the 169 * AHA1740 itself */ 170 break; 171 default: 172 retval=DID_ERROR; /* No further 173 * diagnostics 174 * possible */ 175 } 176 } else { 177 /* Michael suggests, and Brad concurs: */ 178 if ( status_word.qf ) { 179 retval = DID_TIME_OUT; /* forces a redo */ 180 /* I think this specific one should 181 * not happen -Brad */ 182 printk("aha1740.c: WARNING: AHA1740 queue overflow!\n"); 183 } else 184 if ( status[0]&0x60 ) { 185 /* Didn't find a better error */ 186 retval = DID_ERROR; 187 } 188 /* In any other case return DID_OK so for example 189 CONDITION_CHECKS make it through to the appropriate 190 device driver */ 191 } 192 } 193 /* Under all circumstances supply the target status -Michael */ 194 return status[3] | retval << 16; 195 } 196 197 static int aha1740_test_port(unsigned int base) 198 { 199 if ( inb(PORTADR(base)) & PORTADDR_ENH ) 200 return 1; /* Okay, we're all set */ 201 202 printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n"); 203 return 0; 204 } 205 206 /* A "high" level interrupt handler */ 207 static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) 208 { 209 struct Scsi_Host *host = (struct Scsi_Host *) dev_id; 210 void (*my_done)(struct scsi_cmnd *); 211 int errstatus, adapstat; 212 int number_serviced; 213 struct ecb *ecbptr; 214 struct scsi_cmnd *SCtmp; 215 unsigned int base; 216 unsigned long flags; 217 int handled = 0; 218 struct aha1740_sg *sgptr; 219 struct eisa_device *edev; 220 221 if (!host) 222 panic("aha1740.c: Irq from unknown host!\n"); 223 spin_lock_irqsave(host->host_lock, flags); 224 base = host->io_port; 225 number_serviced = 0; 226 edev = HOSTDATA(host)->edev; 227 228 while(inb(G2STAT(base)) & G2STAT_INTPEND) { 229 handled = 1; 230 DEB(printk("aha1740_intr top of loop.\n")); 231 adapstat = inb(G2INTST(base)); 232 ecbptr = ecb_dma_to_cpu (host, inl(MBOXIN0(base))); 233 outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */ 234 235 switch ( adapstat & G2INTST_MASK ) { 236 case G2INTST_CCBRETRY: 237 case G2INTST_CCBERROR: 238 case G2INTST_CCBGOOD: 239 /* Host Ready -> Mailbox in complete */ 240 outb(G2CNTRL_HRDY,G2CNTRL(base)); 241 if (!ecbptr) { 242 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n", 243 inb(G2STAT(base)),adapstat, 244 inb(G2INTST(base)), number_serviced++); 245 continue; 246 } 247 SCtmp = ecbptr->SCpnt; 248 if (!SCtmp) { 249 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n", 250 inb(G2STAT(base)),adapstat, 251 inb(G2INTST(base)), number_serviced++); 252 continue; 253 } 254 sgptr = (struct aha1740_sg *) SCtmp->host_scribble; 255 scsi_dma_unmap(SCtmp); 256 257 /* Free the sg block */ 258 dma_free_coherent (&edev->dev, 259 sizeof (struct aha1740_sg), 260 SCtmp->host_scribble, 261 sgptr->sg_dma_addr); 262 263 /* Fetch the sense data, and tuck it away, in 264 the required slot. The Adaptec 265 automatically fetches it, and there is no 266 guarantee that we will still have it in the 267 cdb when we come back */ 268 if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR ) { 269 memcpy(SCtmp->sense_buffer, ecbptr->sense, 270 SCSI_SENSE_BUFFERSIZE); 271 errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status); 272 } else 273 errstatus = 0; 274 DEB(if (errstatus) 275 printk("aha1740_intr_handle: returning %6x\n", 276 errstatus)); 277 SCtmp->result = errstatus; 278 my_done = ecbptr->done; 279 memset(ecbptr,0,sizeof(struct ecb)); 280 if ( my_done ) 281 my_done(SCtmp); 282 break; 283 284 case G2INTST_HARDFAIL: 285 printk(KERN_ALERT "aha1740 hardware failure!\n"); 286 panic("aha1740.c"); /* Goodbye */ 287 288 case G2INTST_ASNEVENT: 289 printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n", 290 adapstat, 291 inb(MBOXIN0(base)), 292 inb(MBOXIN1(base)), 293 inb(MBOXIN2(base)), 294 inb(MBOXIN3(base))); /* Say What? */ 295 /* Host Ready -> Mailbox in complete */ 296 outb(G2CNTRL_HRDY,G2CNTRL(base)); 297 break; 298 299 case G2INTST_CMDGOOD: 300 /* set immediate command success flag here: */ 301 break; 302 303 case G2INTST_CMDERROR: 304 /* Set immediate command failure flag here: */ 305 break; 306 } 307 number_serviced++; 308 } 309 310 spin_unlock_irqrestore(host->host_lock, flags); 311 return IRQ_RETVAL(handled); 312 } 313 314 static int aha1740_queuecommand_lck(struct scsi_cmnd * SCpnt, 315 void (*done)(struct scsi_cmnd *)) 316 { 317 unchar direction; 318 unchar *cmd = (unchar *) SCpnt->cmnd; 319 unchar target = scmd_id(SCpnt); 320 struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host); 321 unsigned long flags; 322 dma_addr_t sg_dma; 323 struct aha1740_sg *sgptr; 324 int ecbno, nseg; 325 DEB(int i); 326 327 if(*cmd == REQUEST_SENSE) { 328 SCpnt->result = 0; 329 done(SCpnt); 330 return 0; 331 } 332 333 #ifdef DEBUG 334 if (*cmd == READ_10 || *cmd == WRITE_10) 335 i = xscsi2int(cmd+2); 336 else if (*cmd == READ_6 || *cmd == WRITE_6) 337 i = scsi2int(cmd+2); 338 else 339 i = -1; 340 printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ", 341 target, *cmd, i, bufflen); 342 printk("scsi cmd:"); 343 for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]); 344 printk("\n"); 345 #endif 346 347 /* locate an available ecb */ 348 spin_lock_irqsave(SCpnt->device->host->host_lock, flags); 349 ecbno = host->last_ecb_used + 1; /* An optimization */ 350 if (ecbno >= AHA1740_ECBS) 351 ecbno = 0; 352 do { 353 if (!host->ecb[ecbno].cmdw) 354 break; 355 ecbno++; 356 if (ecbno >= AHA1740_ECBS) 357 ecbno = 0; 358 } while (ecbno != host->last_ecb_used); 359 360 if (host->ecb[ecbno].cmdw) 361 panic("Unable to find empty ecb for aha1740.\n"); 362 363 host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command 364 doubles as reserved flag */ 365 366 host->last_ecb_used = ecbno; 367 spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); 368 369 #ifdef DEBUG 370 printk("Sending command (%d %x)...", ecbno, done); 371 #endif 372 373 host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command 374 * Descriptor Block 375 * Length */ 376 377 direction = 0; 378 if (*cmd == READ_10 || *cmd == READ_6) 379 direction = 1; 380 else if (*cmd == WRITE_10 || *cmd == WRITE_6) 381 direction = 0; 382 383 memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len); 384 385 SCpnt->host_scribble = dma_alloc_coherent (&host->edev->dev, 386 sizeof (struct aha1740_sg), 387 &sg_dma, GFP_ATOMIC); 388 if(SCpnt->host_scribble == NULL) { 389 printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n"); 390 return 1; 391 } 392 sgptr = (struct aha1740_sg *) SCpnt->host_scribble; 393 sgptr->sg_dma_addr = sg_dma; 394 395 nseg = scsi_dma_map(SCpnt); 396 BUG_ON(nseg < 0); 397 if (nseg) { 398 struct scatterlist *sg; 399 struct aha1740_chain * cptr; 400 int i; 401 DEB(unsigned char * ptr); 402 403 host->ecb[ecbno].sg = 1; /* SCSI Initiator Command 404 * w/scatter-gather*/ 405 cptr = sgptr->sg_chain; 406 scsi_for_each_sg(SCpnt, sg, nseg, i) { 407 cptr[i].datalen = sg_dma_len (sg); 408 cptr[i].dataptr = sg_dma_address (sg); 409 } 410 host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain); 411 host->ecb[ecbno].dataptr = sg_dma; 412 #ifdef DEBUG 413 printk("cptr %x: ",cptr); 414 ptr = (unsigned char *) cptr; 415 for(i=0;i<24;i++) printk("%02x ", ptr[i]); 416 #endif 417 } else { 418 host->ecb[ecbno].datalen = 0; 419 host->ecb[ecbno].dataptr = 0; 420 } 421 host->ecb[ecbno].lun = SCpnt->device->lun; 422 host->ecb[ecbno].ses = 1; /* Suppress underrun errors */ 423 host->ecb[ecbno].dir = direction; 424 host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */ 425 host->ecb[ecbno].senselen = 12; 426 host->ecb[ecbno].senseptr = ecb_cpu_to_dma (SCpnt->device->host, 427 host->ecb[ecbno].sense); 428 host->ecb[ecbno].statusptr = ecb_cpu_to_dma (SCpnt->device->host, 429 host->ecb[ecbno].status); 430 host->ecb[ecbno].done = done; 431 host->ecb[ecbno].SCpnt = SCpnt; 432 #ifdef DEBUG 433 { 434 int i; 435 printk("aha1740_command: sending.. "); 436 for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++) 437 printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]); 438 } 439 printk("\n"); 440 #endif 441 if (done) { 442 /* The Adaptec Spec says the card is so fast that the loops 443 will only be executed once in the code below. Even if this 444 was true with the fastest processors when the spec was 445 written, it doesn't seem to be true with today's fast 446 processors. We print a warning if the code is executed more 447 often than LOOPCNT_WARN. If this happens, it should be 448 investigated. If the count reaches LOOPCNT_MAX, we assume 449 something is broken; since there is no way to return an 450 error (the return value is ignored by the mid-level scsi 451 layer) we have to panic (and maybe that's the best thing we 452 can do then anyhow). */ 453 454 #define LOOPCNT_WARN 10 /* excessive mbxout wait -> syslog-msg */ 455 #define LOOPCNT_MAX 1000000 /* mbxout deadlock -> panic() after ~ 2 sec. */ 456 int loopcnt; 457 unsigned int base = SCpnt->device->host->io_port; 458 DEB(printk("aha1740[%d] critical section\n",ecbno)); 459 460 spin_lock_irqsave(SCpnt->device->host->host_lock, flags); 461 for (loopcnt = 0; ; loopcnt++) { 462 if (inb(G2STAT(base)) & G2STAT_MBXOUT) break; 463 if (loopcnt == LOOPCNT_WARN) { 464 printk("aha1740[%d]_mbxout wait!\n",ecbno); 465 } 466 if (loopcnt == LOOPCNT_MAX) 467 panic("aha1740.c: mbxout busy!\n"); 468 } 469 outl (ecb_cpu_to_dma (SCpnt->device->host, host->ecb + ecbno), 470 MBOXOUT0(base)); 471 for (loopcnt = 0; ; loopcnt++) { 472 if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break; 473 if (loopcnt == LOOPCNT_WARN) { 474 printk("aha1740[%d]_attn wait!\n",ecbno); 475 } 476 if (loopcnt == LOOPCNT_MAX) 477 panic("aha1740.c: attn wait failed!\n"); 478 } 479 outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */ 480 spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); 481 DEB(printk("aha1740[%d] request queued.\n",ecbno)); 482 } else 483 printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n"); 484 return 0; 485 } 486 487 static DEF_SCSI_QCMD(aha1740_queuecommand) 488 489 /* Query the board for its irq_level and irq_type. Nothing else matters 490 in enhanced mode on an EISA bus. */ 491 492 static void aha1740_getconfig(unsigned int base, unsigned int *irq_level, 493 unsigned int *irq_type, 494 unsigned int *translation) 495 { 496 static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 }; 497 498 *irq_level = intab[inb(INTDEF(base)) & 0x7]; 499 *irq_type = (inb(INTDEF(base)) & 0x8) >> 3; 500 *translation = inb(RESV1(base)) & 0x1; 501 outb(inb(INTDEF(base)) | 0x10, INTDEF(base)); 502 } 503 504 static int aha1740_biosparam(struct scsi_device *sdev, 505 struct block_device *dev, 506 sector_t capacity, int* ip) 507 { 508 int size = capacity; 509 int extended = HOSTDATA(sdev->host)->translation; 510 511 DEB(printk("aha1740_biosparam\n")); 512 if (extended && (ip[2] > 1024)) { 513 ip[0] = 255; 514 ip[1] = 63; 515 ip[2] = size / (255 * 63); 516 } else { 517 ip[0] = 64; 518 ip[1] = 32; 519 ip[2] = size >> 11; 520 } 521 return 0; 522 } 523 524 static int aha1740_eh_abort_handler (struct scsi_cmnd *dummy) 525 { 526 /* 527 * From Alan Cox : 528 * The AHA1740 has firmware handled abort/reset handling. The "head in 529 * sand" kernel code is correct for once 8) 530 * 531 * So we define a dummy handler just to keep the kernel SCSI code as 532 * quiet as possible... 533 */ 534 535 return SUCCESS; 536 } 537 538 static struct scsi_host_template aha1740_template = { 539 .module = THIS_MODULE, 540 .proc_name = "aha1740", 541 .show_info = aha1740_show_info, 542 .name = "Adaptec 174x (EISA)", 543 .queuecommand = aha1740_queuecommand, 544 .bios_param = aha1740_biosparam, 545 .can_queue = AHA1740_ECBS, 546 .this_id = 7, 547 .sg_tablesize = AHA1740_SCATTER, 548 .eh_abort_handler = aha1740_eh_abort_handler, 549 }; 550 551 static int aha1740_probe (struct device *dev) 552 { 553 int slotbase, rc; 554 unsigned int irq_level, irq_type, translation; 555 struct Scsi_Host *shpnt; 556 struct aha1740_hostdata *host; 557 struct eisa_device *edev = to_eisa_device (dev); 558 559 DEB(printk("aha1740_probe: \n")); 560 561 slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET; 562 if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */ 563 return -EBUSY; 564 if (!aha1740_test_port(slotbase)) 565 goto err_release_region; 566 aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation); 567 if ((inb(G2STAT(slotbase)) & 568 (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) { 569 /* If the card isn't ready, hard reset it */ 570 outb(G2CNTRL_HRST, G2CNTRL(slotbase)); 571 outb(0, G2CNTRL(slotbase)); 572 } 573 printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n", 574 edev->slot, slotbase, irq_level, irq_type ? "edge" : "level"); 575 printk(KERN_INFO "aha174x: Extended translation %sabled.\n", 576 translation ? "en" : "dis"); 577 shpnt = scsi_host_alloc(&aha1740_template, 578 sizeof(struct aha1740_hostdata)); 579 if(shpnt == NULL) 580 goto err_release_region; 581 582 shpnt->base = 0; 583 shpnt->io_port = slotbase; 584 shpnt->n_io_port = SLOTSIZE; 585 shpnt->irq = irq_level; 586 shpnt->dma_channel = 0xff; 587 host = HOSTDATA(shpnt); 588 host->edev = edev; 589 host->translation = translation; 590 host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb, 591 sizeof (host->ecb), 592 DMA_BIDIRECTIONAL); 593 if (!host->ecb_dma_addr) { 594 printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n"); 595 goto err_host_put; 596 } 597 598 DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level)); 599 if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED, 600 "aha1740",shpnt)) { 601 printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n", 602 irq_level); 603 goto err_unmap; 604 } 605 606 eisa_set_drvdata (edev, shpnt); 607 608 rc = scsi_add_host (shpnt, dev); 609 if (rc) 610 goto err_irq; 611 612 scsi_scan_host (shpnt); 613 return 0; 614 615 err_irq: 616 free_irq(irq_level, shpnt); 617 err_unmap: 618 dma_unmap_single (&edev->dev, host->ecb_dma_addr, 619 sizeof (host->ecb), DMA_BIDIRECTIONAL); 620 err_host_put: 621 scsi_host_put (shpnt); 622 err_release_region: 623 release_region(slotbase, SLOTSIZE); 624 625 return -ENODEV; 626 } 627 628 static int aha1740_remove (struct device *dev) 629 { 630 struct Scsi_Host *shpnt = dev_get_drvdata(dev); 631 struct aha1740_hostdata *host = HOSTDATA (shpnt); 632 633 scsi_remove_host(shpnt); 634 635 free_irq (shpnt->irq, shpnt); 636 dma_unmap_single (dev, host->ecb_dma_addr, 637 sizeof (host->ecb), DMA_BIDIRECTIONAL); 638 release_region (shpnt->io_port, SLOTSIZE); 639 640 scsi_host_put (shpnt); 641 642 return 0; 643 } 644 645 static struct eisa_device_id aha1740_ids[] = { 646 { "ADP0000" }, /* 1740 */ 647 { "ADP0001" }, /* 1740A */ 648 { "ADP0002" }, /* 1742A */ 649 { "ADP0400" }, /* 1744 */ 650 { "" } 651 }; 652 MODULE_DEVICE_TABLE(eisa, aha1740_ids); 653 654 static struct eisa_driver aha1740_driver = { 655 .id_table = aha1740_ids, 656 .driver = { 657 .name = "aha1740", 658 .probe = aha1740_probe, 659 .remove = aha1740_remove, 660 }, 661 }; 662 663 static __init int aha1740_init (void) 664 { 665 return eisa_driver_register (&aha1740_driver); 666 } 667 668 static __exit void aha1740_exit (void) 669 { 670 eisa_driver_unregister (&aha1740_driver); 671 } 672 673 module_init (aha1740_init); 674 module_exit (aha1740_exit); 675 676 MODULE_LICENSE("GPL"); 677