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