1171 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for Adaptec AHA-1542 SCSI host adapters4 *5 * Copyright (C) 1992 Tommy Thorn6 * Copyright (C) 1993, 1994, 1995 Eric Youngdale7 * Copyright (C) 2015 Ondrej Zary8 */9 10#include <linux/module.h>11#include <linux/interrupt.h>12#include <linux/kernel.h>13#include <linux/types.h>14#include <linux/string.h>15#include <linux/delay.h>16#include <linux/init.h>17#include <linux/spinlock.h>18#include <linux/isa.h>19#include <linux/pnp.h>20#include <linux/slab.h>21#include <linux/io.h>22#include <asm/dma.h>23#include <scsi/scsi_cmnd.h>24#include <scsi/scsi_device.h>25#include <scsi/scsi_host.h>26#include "aha1542.h"27 28#define MAXBOARDS 429 30static bool isapnp = 1;31module_param(isapnp, bool, 0);32MODULE_PARM_DESC(isapnp, "enable PnP support (default=1)");33 34static int io[MAXBOARDS] = { 0x330, 0x334, 0, 0 };35module_param_hw_array(io, int, ioport, NULL, 0);36MODULE_PARM_DESC(io, "base IO address of controller (0x130,0x134,0x230,0x234,0x330,0x334, default=0x330,0x334)");37 38/* time AHA spends on the AT-bus during data transfer */39static int bus_on[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 11us */40module_param_array(bus_on, int, NULL, 0);41MODULE_PARM_DESC(bus_on, "bus on time [us] (2-15, default=-1 [HW default: 11])");42 43/* time AHA spends off the bus (not to monopolize it) during data transfer */44static int bus_off[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 4us */45module_param_array(bus_off, int, NULL, 0);46MODULE_PARM_DESC(bus_off, "bus off time [us] (1-64, default=-1 [HW default: 4])");47 48/* default is jumper selected (J1 on 1542A), factory default = 5 MB/s */49static int dma_speed[MAXBOARDS] = { -1, -1, -1, -1 };50module_param_array(dma_speed, int, NULL, 0);51MODULE_PARM_DESC(dma_speed, "DMA speed [MB/s] (5,6,7,8,10, default=-1 [by jumper])");52 53#define BIOS_TRANSLATION_6432 1 /* Default case these days */54#define BIOS_TRANSLATION_25563 2 /* Big disk case */55 56struct aha1542_hostdata {57 /* This will effectively start both of them at the first mailbox */58 int bios_translation; /* Mapping bios uses - for compatibility */59 int aha1542_last_mbi_used;60 int aha1542_last_mbo_used;61 struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];62 struct mailbox *mb;63 dma_addr_t mb_handle;64 struct ccb *ccb;65 dma_addr_t ccb_handle;66};67 68#define AHA1542_MAX_SECTORS 1669 70struct aha1542_cmd {71 /* bounce buffer */72 void *data_buffer;73 dma_addr_t data_buffer_handle;74};75 76static inline void aha1542_intr_reset(u16 base)77{78 outb(IRST, CONTROL(base));79}80 81static inline bool wait_mask(u16 port, u8 mask, u8 allof, u8 noneof, int timeout)82{83 bool delayed = true;84 85 if (timeout == 0) {86 timeout = 3000000;87 delayed = false;88 }89 90 while (1) {91 u8 bits = inb(port) & mask;92 if ((bits & allof) == allof && ((bits & noneof) == 0))93 break;94 if (delayed)95 mdelay(1);96 if (--timeout == 0)97 return false;98 }99 100 return true;101}102 103static int aha1542_outb(unsigned int base, u8 val)104{105 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))106 return 1;107 outb(val, DATA(base));108 109 return 0;110}111 112static int aha1542_out(unsigned int base, u8 *buf, int len)113{114 while (len--) {115 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))116 return 1;117 outb(*buf++, DATA(base));118 }119 if (!wait_mask(INTRFLAGS(base), INTRMASK, HACC, 0, 0))120 return 1;121 122 return 0;123}124 125/*126 * Only used at boot time, so we do not need to worry about latency as much127 * here128 */129 130static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout)131{132 while (len--) {133 if (!wait_mask(STATUS(base), DF, DF, 0, timeout))134 return 1;135 *buf++ = inb(DATA(base));136 }137 return 0;138}139 140static int makecode(unsigned hosterr, unsigned scsierr)141{142 switch (hosterr) {143 case 0x0:144 case 0xa: /* Linked command complete without error and linked normally */145 case 0xb: /* Linked command complete without error, interrupt generated */146 hosterr = 0;147 break;148 149 case 0x11: /* Selection time out-The initiator selection or target150 * reselection was not complete within the SCSI Time out period151 */152 hosterr = DID_TIME_OUT;153 break;154 155 case 0x12: /* Data overrun/underrun-The target attempted to transfer more data156 * than was allocated by the Data Length field or the sum of the157 * Scatter / Gather Data Length fields.158 */159 160 case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */161 162 case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was163 * invalid. This usually indicates a software failure.164 */165 166 case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.167 * This usually indicates a software failure.168 */169 170 case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set171 * of linked CCB's does not specify the same logical unit number as172 * the first.173 */174 case 0x18: /* Invalid Target Direction received from Host-The direction of a175 * Target Mode CCB was invalid.176 */177 178 case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was179 * received to service data transfer between the same target LUN180 * and initiator SCSI ID in the same direction.181 */182 183 case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero184 * length segment or invalid segment list boundaries was received.185 * A CCB parameter was invalid.186 */187#ifdef DEBUG188 printk("Aha1542: %x %x\n", hosterr, scsierr);189#endif190 hosterr = DID_ERROR; /* Couldn't find any better */191 break;192 193 case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus194 * phase sequence was requested by the target. The host adapter195 * will generate a SCSI Reset Condition, notifying the host with196 * a SCRD interrupt197 */198 hosterr = DID_RESET;199 break;200 default:201 printk(KERN_ERR "aha1542: makecode: unknown hoststatus %x\n", hosterr);202 break;203 }204 return scsierr | (hosterr << 16);205}206 207static int aha1542_test_port(struct Scsi_Host *sh)208{209 int i;210 211 /* Quick and dirty test for presence of the card. */212 if (inb(STATUS(sh->io_port)) == 0xff)213 return 0;214 215 /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */216 217 /* In case some other card was probing here, reset interrupts */218 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */219 220 outb(SRST | IRST /*|SCRST */ , CONTROL(sh->io_port));221 222 mdelay(20); /* Wait a little bit for things to settle down. */223 224 /* Expect INIT and IDLE, any of the others are bad */225 if (!wait_mask(STATUS(sh->io_port), STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0))226 return 0;227 228 /* Shouldn't have generated any interrupts during reset */229 if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)230 return 0;231 232 /*233 * Perform a host adapter inquiry instead so we do not need to set234 * up the mailboxes ahead of time235 */236 237 aha1542_outb(sh->io_port, CMD_INQUIRY);238 239 for (i = 0; i < 4; i++) {240 if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0))241 return 0;242 (void)inb(DATA(sh->io_port));243 }244 245 /* Reading port should reset DF */246 if (inb(STATUS(sh->io_port)) & DF)247 return 0;248 249 /* When HACC, command is completed, and we're though testing */250 if (!wait_mask(INTRFLAGS(sh->io_port), HACC, HACC, 0, 0))251 return 0;252 253 /* Clear interrupts */254 outb(IRST, CONTROL(sh->io_port));255 256 return 1;257}258 259static void aha1542_free_cmd(struct scsi_cmnd *cmd)260{261 struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);262 263 if (cmd->sc_data_direction == DMA_FROM_DEVICE) {264 struct request *rq = scsi_cmd_to_rq(cmd);265 void *buf = acmd->data_buffer;266 struct req_iterator iter;267 struct bio_vec bv;268 269 rq_for_each_segment(bv, rq, iter) {270 memcpy_to_bvec(&bv, buf);271 buf += bv.bv_len;272 }273 }274 275 scsi_dma_unmap(cmd);276}277 278static irqreturn_t aha1542_interrupt(int irq, void *dev_id)279{280 struct Scsi_Host *sh = dev_id;281 struct aha1542_hostdata *aha1542 = shost_priv(sh);282 int errstatus, mbi, mbo, mbistatus;283 int number_serviced;284 unsigned long flags;285 struct scsi_cmnd *tmp_cmd;286 int flag;287 struct mailbox *mb = aha1542->mb;288 struct ccb *ccb = aha1542->ccb;289 290#ifdef DEBUG291 {292 flag = inb(INTRFLAGS(sh->io_port));293 shost_printk(KERN_DEBUG, sh, "aha1542_intr_handle: ");294 if (!(flag & ANYINTR))295 printk("no interrupt?");296 if (flag & MBIF)297 printk("MBIF ");298 if (flag & MBOA)299 printk("MBOF ");300 if (flag & HACC)301 printk("HACC ");302 if (flag & SCRD)303 printk("SCRD ");304 printk("status %02x\n", inb(STATUS(sh->io_port)));305 }306#endif307 number_serviced = 0;308 309 spin_lock_irqsave(sh->host_lock, flags);310 while (1) {311 flag = inb(INTRFLAGS(sh->io_port));312 313 /*314 * Check for unusual interrupts. If any of these happen, we should315 * probably do something special, but for now just printing a message316 * is sufficient. A SCSI reset detected is something that we really317 * need to deal with in some way.318 */319 if (flag & ~MBIF) {320 if (flag & MBOA)321 printk("MBOF ");322 if (flag & HACC)323 printk("HACC ");324 if (flag & SCRD)325 printk("SCRD ");326 }327 aha1542_intr_reset(sh->io_port);328 329 mbi = aha1542->aha1542_last_mbi_used + 1;330 if (mbi >= 2 * AHA1542_MAILBOXES)331 mbi = AHA1542_MAILBOXES;332 333 do {334 if (mb[mbi].status != 0)335 break;336 mbi++;337 if (mbi >= 2 * AHA1542_MAILBOXES)338 mbi = AHA1542_MAILBOXES;339 } while (mbi != aha1542->aha1542_last_mbi_used);340 341 if (mb[mbi].status == 0) {342 spin_unlock_irqrestore(sh->host_lock, flags);343 /* Hmm, no mail. Must have read it the last time around */344 if (!number_serviced)345 shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n");346 return IRQ_HANDLED;347 }348 349 mbo = (scsi2int(mb[mbi].ccbptr) - (unsigned long)aha1542->ccb_handle) / sizeof(struct ccb);350 mbistatus = mb[mbi].status;351 mb[mbi].status = 0;352 aha1542->aha1542_last_mbi_used = mbi;353 354#ifdef DEBUG355 if (ccb[mbo].tarstat | ccb[mbo].hastat)356 shost_printk(KERN_DEBUG, sh, "aha1542_command: returning %x (status %d)\n",357 ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);358#endif359 360 if (mbistatus == 3)361 continue; /* Aborted command not found */362 363#ifdef DEBUG364 shost_printk(KERN_DEBUG, sh, "...done %d %d\n", mbo, mbi);365#endif366 367 tmp_cmd = aha1542->int_cmds[mbo];368 369 if (!tmp_cmd) {370 spin_unlock_irqrestore(sh->host_lock, flags);371 shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n");372 shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat,373 ccb[mbo].hastat, ccb[mbo].idlun, mbo);374 return IRQ_HANDLED;375 }376 aha1542_free_cmd(tmp_cmd);377 /*378 * Fetch the sense data, and tuck it away, in the required slot. The379 * Adaptec automatically fetches it, and there is no guarantee that380 * we will still have it in the cdb when we come back381 */382 if (ccb[mbo].tarstat == 2)383 memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],384 SCSI_SENSE_BUFFERSIZE);385 386 387 /* is there mail :-) */388 389 /* more error checking left out here */390 if (mbistatus != 1)391 /* This is surely wrong, but I don't know what's right */392 errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);393 else394 errstatus = 0;395 396#ifdef DEBUG397 if (errstatus)398 shost_printk(KERN_DEBUG, sh, "(aha1542 error:%x %x %x) ", errstatus,399 ccb[mbo].hastat, ccb[mbo].tarstat);400 if (ccb[mbo].tarstat == 2)401 print_hex_dump_bytes("sense: ", DUMP_PREFIX_NONE, &ccb[mbo].cdb[ccb[mbo].cdblen], 12);402 if (errstatus)403 printk("aha1542_intr_handle: returning %6x\n", errstatus);404#endif405 tmp_cmd->result = errstatus;406 aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as407 * far as queuecommand is concerned408 */409 scsi_done(tmp_cmd);410 number_serviced++;411 }412}413 414static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)415{416 struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);417 struct aha1542_hostdata *aha1542 = shost_priv(sh);418 u8 direction;419 u8 target = cmd->device->id;420 u8 lun = cmd->device->lun;421 unsigned long flags;422 int bufflen = scsi_bufflen(cmd);423 int mbo;424 struct mailbox *mb = aha1542->mb;425 struct ccb *ccb = aha1542->ccb;426 427 if (*cmd->cmnd == REQUEST_SENSE) {428 /* Don't do the command - we have the sense data already */429 cmd->result = 0;430 scsi_done(cmd);431 return 0;432 }433#ifdef DEBUG434 {435 int i = -1;436 if (*cmd->cmnd == READ_10 || *cmd->cmnd == WRITE_10)437 i = xscsi2int(cmd->cmnd + 2);438 else if (*cmd->cmnd == READ_6 || *cmd->cmnd == WRITE_6)439 i = scsi2int(cmd->cmnd + 2);440 shost_printk(KERN_DEBUG, sh, "aha1542_queuecommand: dev %d cmd %02x pos %d len %d",441 target, *cmd->cmnd, i, bufflen);442 print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);443 }444#endif445 446 if (cmd->sc_data_direction == DMA_TO_DEVICE) {447 struct request *rq = scsi_cmd_to_rq(cmd);448 void *buf = acmd->data_buffer;449 struct req_iterator iter;450 struct bio_vec bv;451 452 rq_for_each_segment(bv, rq, iter) {453 memcpy_from_bvec(buf, &bv);454 buf += bv.bv_len;455 }456 }457 458 /*459 * Use the outgoing mailboxes in a round-robin fashion, because this460 * is how the host adapter will scan for them461 */462 463 spin_lock_irqsave(sh->host_lock, flags);464 mbo = aha1542->aha1542_last_mbo_used + 1;465 if (mbo >= AHA1542_MAILBOXES)466 mbo = 0;467 468 do {469 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)470 break;471 mbo++;472 if (mbo >= AHA1542_MAILBOXES)473 mbo = 0;474 } while (mbo != aha1542->aha1542_last_mbo_used);475 476 if (mb[mbo].status || aha1542->int_cmds[mbo])477 panic("Unable to find empty mailbox for aha1542.\n");478 479 aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from480 * screwing with this cdb.481 */482 483 aha1542->aha1542_last_mbo_used = mbo;484 485#ifdef DEBUG486 shost_printk(KERN_DEBUG, sh, "Sending command (%d)...", mbo);487#endif488 489 /* This gets trashed for some reason */490 any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));491 492 memset(&ccb[mbo], 0, sizeof(struct ccb));493 494 ccb[mbo].cdblen = cmd->cmd_len;495 496 direction = 0;497 if (*cmd->cmnd == READ_10 || *cmd->cmnd == READ_6)498 direction = 8;499 else if (*cmd->cmnd == WRITE_10 || *cmd->cmnd == WRITE_6)500 direction = 16;501 502 memcpy(ccb[mbo].cdb, cmd->cmnd, ccb[mbo].cdblen);503 ccb[mbo].op = 0; /* SCSI Initiator Command */504 any2scsi(ccb[mbo].datalen, bufflen);505 if (bufflen)506 any2scsi(ccb[mbo].dataptr, acmd->data_buffer_handle);507 else508 any2scsi(ccb[mbo].dataptr, 0);509 ccb[mbo].idlun = (target & 7) << 5 | direction | (lun & 7); /*SCSI Target Id */510 ccb[mbo].rsalen = 16;511 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;512 ccb[mbo].commlinkid = 0;513 514#ifdef DEBUG515 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10);516 printk("aha1542_queuecommand: now waiting for interrupt ");517#endif518 mb[mbo].status = 1;519 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);520 spin_unlock_irqrestore(sh->host_lock, flags);521 522 return 0;523}524 525/* Initialize mailboxes */526static void setup_mailboxes(struct Scsi_Host *sh)527{528 struct aha1542_hostdata *aha1542 = shost_priv(sh);529 u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};530 int i;531 532 for (i = 0; i < AHA1542_MAILBOXES; i++) {533 aha1542->mb[i].status = 0;534 any2scsi(aha1542->mb[i].ccbptr,535 aha1542->ccb_handle + i * sizeof(struct ccb));536 aha1542->mb[AHA1542_MAILBOXES + i].status = 0;537 }538 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */539 any2scsi(mb_cmd + 2, aha1542->mb_handle);540 if (aha1542_out(sh->io_port, mb_cmd, 5))541 shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n");542 aha1542_intr_reset(sh->io_port);543}544 545static int aha1542_getconfig(struct Scsi_Host *sh)546{547 u8 inquiry_result[3];548 int i;549 i = inb(STATUS(sh->io_port));550 if (i & DF) {551 i = inb(DATA(sh->io_port));552 }553 aha1542_outb(sh->io_port, CMD_RETCONF);554 aha1542_in(sh->io_port, inquiry_result, 3, 0);555 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))556 shost_printk(KERN_ERR, sh, "error querying board settings\n");557 aha1542_intr_reset(sh->io_port);558 switch (inquiry_result[0]) {559 case 0x80:560 sh->dma_channel = 7;561 break;562 case 0x40:563 sh->dma_channel = 6;564 break;565 case 0x20:566 sh->dma_channel = 5;567 break;568 case 0x01:569 sh->dma_channel = 0;570 break;571 case 0:572 /*573 * This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.574 * Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this.575 */576 sh->dma_channel = 0xFF;577 break;578 default:579 shost_printk(KERN_ERR, sh, "Unable to determine DMA channel.\n");580 return -1;581 }582 switch (inquiry_result[1]) {583 case 0x40:584 sh->irq = 15;585 break;586 case 0x20:587 sh->irq = 14;588 break;589 case 0x8:590 sh->irq = 12;591 break;592 case 0x4:593 sh->irq = 11;594 break;595 case 0x2:596 sh->irq = 10;597 break;598 case 0x1:599 sh->irq = 9;600 break;601 default:602 shost_printk(KERN_ERR, sh, "Unable to determine IRQ level.\n");603 return -1;604 }605 sh->this_id = inquiry_result[2] & 7;606 return 0;607}608 609/*610 * This function should only be called for 1542C boards - we can detect611 * the special firmware settings and unlock the board612 */613 614static int aha1542_mbenable(struct Scsi_Host *sh)615{616 static u8 mbenable_cmd[3];617 static u8 mbenable_result[2];618 int retval;619 620 retval = BIOS_TRANSLATION_6432;621 622 aha1542_outb(sh->io_port, CMD_EXTBIOS);623 if (aha1542_in(sh->io_port, mbenable_result, 2, 100))624 return retval;625 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 100))626 goto fail;627 aha1542_intr_reset(sh->io_port);628 629 if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {630 mbenable_cmd[0] = CMD_MBENABLE;631 mbenable_cmd[1] = 0;632 mbenable_cmd[2] = mbenable_result[1];633 634 if ((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03))635 retval = BIOS_TRANSLATION_25563;636 637 if (aha1542_out(sh->io_port, mbenable_cmd, 3))638 goto fail;639 }640 while (0) {641fail:642 shost_printk(KERN_ERR, sh, "Mailbox init failed\n");643 }644 aha1542_intr_reset(sh->io_port);645 return retval;646}647 648/* Query the board to find out if it is a 1542 or a 1740, or whatever. */649static int aha1542_query(struct Scsi_Host *sh)650{651 struct aha1542_hostdata *aha1542 = shost_priv(sh);652 u8 inquiry_result[4];653 int i;654 i = inb(STATUS(sh->io_port));655 if (i & DF) {656 i = inb(DATA(sh->io_port));657 }658 aha1542_outb(sh->io_port, CMD_INQUIRY);659 aha1542_in(sh->io_port, inquiry_result, 4, 0);660 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))661 shost_printk(KERN_ERR, sh, "error querying card type\n");662 aha1542_intr_reset(sh->io_port);663 664 aha1542->bios_translation = BIOS_TRANSLATION_6432; /* Default case */665 666 /*667 * For an AHA1740 series board, we ignore the board since there is a668 * hardware bug which can lead to wrong blocks being returned if the board669 * is operating in the 1542 emulation mode. Since there is an extended mode670 * driver, we simply ignore the board and let the 1740 driver pick it up.671 */672 673 if (inquiry_result[0] == 0x43) {674 shost_printk(KERN_INFO, sh, "Emulation mode not supported for AHA-1740 hardware, use aha1740 driver instead.\n");675 return 1;676 }677 678 /*679 * Always call this - boards that do not support extended bios translation680 * will ignore the command, and we will set the proper default681 */682 683 aha1542->bios_translation = aha1542_mbenable(sh);684 685 return 0;686}687 688static u8 dma_speed_hw(int dma_speed)689{690 switch (dma_speed) {691 case 5:692 return 0x00;693 case 6:694 return 0x04;695 case 7:696 return 0x01;697 case 8:698 return 0x02;699 case 10:700 return 0x03;701 }702 703 return 0xff; /* invalid */704}705 706/* Set the Bus on/off-times as not to ruin floppy performance */707static void aha1542_set_bus_times(struct Scsi_Host *sh, int bus_on, int bus_off, int dma_speed)708{709 if (bus_on > 0) {710 u8 oncmd[] = { CMD_BUSON_TIME, clamp(bus_on, 2, 15) };711 712 aha1542_intr_reset(sh->io_port);713 if (aha1542_out(sh->io_port, oncmd, 2))714 goto fail;715 }716 717 if (bus_off > 0) {718 u8 offcmd[] = { CMD_BUSOFF_TIME, clamp(bus_off, 1, 64) };719 720 aha1542_intr_reset(sh->io_port);721 if (aha1542_out(sh->io_port, offcmd, 2))722 goto fail;723 }724 725 if (dma_speed_hw(dma_speed) != 0xff) {726 u8 dmacmd[] = { CMD_DMASPEED, dma_speed_hw(dma_speed) };727 728 aha1542_intr_reset(sh->io_port);729 if (aha1542_out(sh->io_port, dmacmd, 2))730 goto fail;731 }732 aha1542_intr_reset(sh->io_port);733 return;734fail:735 shost_printk(KERN_ERR, sh, "setting bus on/off-time failed\n");736 aha1542_intr_reset(sh->io_port);737}738 739/* return non-zero on detection */740static struct Scsi_Host *aha1542_hw_init(const struct scsi_host_template *tpnt,741 struct device *pdev, int indx)742{743 unsigned int base_io = io[indx];744 struct Scsi_Host *sh;745 struct aha1542_hostdata *aha1542;746 char dma_info[] = "no DMA";747 748 if (base_io == 0)749 return NULL;750 751 if (!request_region(base_io, AHA1542_REGION_SIZE, "aha1542"))752 return NULL;753 754 sh = scsi_host_alloc(tpnt, sizeof(struct aha1542_hostdata));755 if (!sh)756 goto release;757 aha1542 = shost_priv(sh);758 759 sh->unique_id = base_io;760 sh->io_port = base_io;761 sh->n_io_port = AHA1542_REGION_SIZE;762 aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1;763 aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1;764 765 if (!aha1542_test_port(sh))766 goto unregister;767 768 aha1542_set_bus_times(sh, bus_on[indx], bus_off[indx], dma_speed[indx]);769 if (aha1542_query(sh))770 goto unregister;771 if (aha1542_getconfig(sh) == -1)772 goto unregister;773 774 if (sh->dma_channel != 0xFF)775 snprintf(dma_info, sizeof(dma_info), "DMA %d", sh->dma_channel);776 shost_printk(KERN_INFO, sh, "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d, %s\n",777 sh->this_id, base_io, sh->irq, dma_info);778 if (aha1542->bios_translation == BIOS_TRANSLATION_25563)779 shost_printk(KERN_INFO, sh, "Using extended bios translation\n");780 781 if (dma_set_mask_and_coherent(pdev, DMA_BIT_MASK(24)) < 0)782 goto unregister;783 784 aha1542->mb = dma_alloc_coherent(pdev,785 AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),786 &aha1542->mb_handle, GFP_KERNEL);787 if (!aha1542->mb)788 goto unregister;789 790 aha1542->ccb = dma_alloc_coherent(pdev,791 AHA1542_MAILBOXES * sizeof(struct ccb),792 &aha1542->ccb_handle, GFP_KERNEL);793 if (!aha1542->ccb)794 goto free_mb;795 796 setup_mailboxes(sh);797 798 if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {799 shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");800 goto free_ccb;801 }802 if (sh->dma_channel != 0xFF) {803 if (request_dma(sh->dma_channel, "aha1542")) {804 shost_printk(KERN_ERR, sh, "Unable to allocate DMA channel.\n");805 goto free_irq;806 }807 if (sh->dma_channel == 0 || sh->dma_channel >= 5) {808 set_dma_mode(sh->dma_channel, DMA_MODE_CASCADE);809 enable_dma(sh->dma_channel);810 }811 }812 813 if (scsi_add_host(sh, pdev))814 goto free_dma;815 816 scsi_scan_host(sh);817 818 return sh;819 820free_dma:821 if (sh->dma_channel != 0xff)822 free_dma(sh->dma_channel);823free_irq:824 free_irq(sh->irq, sh);825free_ccb:826 dma_free_coherent(pdev, AHA1542_MAILBOXES * sizeof(struct ccb),827 aha1542->ccb, aha1542->ccb_handle);828free_mb:829 dma_free_coherent(pdev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),830 aha1542->mb, aha1542->mb_handle);831unregister:832 scsi_host_put(sh);833release:834 release_region(base_io, AHA1542_REGION_SIZE);835 836 return NULL;837}838 839static int aha1542_release(struct Scsi_Host *sh)840{841 struct aha1542_hostdata *aha1542 = shost_priv(sh);842 struct device *dev = sh->dma_dev;843 844 scsi_remove_host(sh);845 if (sh->dma_channel != 0xff)846 free_dma(sh->dma_channel);847 dma_free_coherent(dev, AHA1542_MAILBOXES * sizeof(struct ccb),848 aha1542->ccb, aha1542->ccb_handle);849 dma_free_coherent(dev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),850 aha1542->mb, aha1542->mb_handle);851 if (sh->irq)852 free_irq(sh->irq, sh);853 if (sh->io_port && sh->n_io_port)854 release_region(sh->io_port, sh->n_io_port);855 scsi_host_put(sh);856 return 0;857}858 859 860/*861 * This is a device reset. This is handled by sending a special command862 * to the device.863 */864static int aha1542_dev_reset(struct scsi_cmnd *cmd)865{866 struct Scsi_Host *sh = cmd->device->host;867 struct aha1542_hostdata *aha1542 = shost_priv(sh);868 unsigned long flags;869 struct mailbox *mb = aha1542->mb;870 u8 target = cmd->device->id;871 u8 lun = cmd->device->lun;872 int mbo;873 struct ccb *ccb = aha1542->ccb;874 875 spin_lock_irqsave(sh->host_lock, flags);876 mbo = aha1542->aha1542_last_mbo_used + 1;877 if (mbo >= AHA1542_MAILBOXES)878 mbo = 0;879 880 do {881 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)882 break;883 mbo++;884 if (mbo >= AHA1542_MAILBOXES)885 mbo = 0;886 } while (mbo != aha1542->aha1542_last_mbo_used);887 888 if (mb[mbo].status || aha1542->int_cmds[mbo])889 panic("Unable to find empty mailbox for aha1542.\n");890 891 aha1542->int_cmds[mbo] = cmd; /* This will effectively892 * prevent someone else from893 * screwing with this cdb.894 */895 896 aha1542->aha1542_last_mbo_used = mbo;897 898 /* This gets trashed for some reason */899 any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));900 901 memset(&ccb[mbo], 0, sizeof(struct ccb));902 903 ccb[mbo].op = 0x81; /* BUS DEVICE RESET */904 905 ccb[mbo].idlun = (target & 7) << 5 | (lun & 7); /*SCSI Target Id */906 907 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;908 ccb[mbo].commlinkid = 0;909 910 /*911 * Now tell the 1542 to flush all pending commands for this912 * target913 */914 aha1542_outb(sh->io_port, CMD_START_SCSI);915 spin_unlock_irqrestore(sh->host_lock, flags);916 917 scmd_printk(KERN_WARNING, cmd,918 "Trying device reset for target\n");919 920 return SUCCESS;921}922 923static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)924{925 struct Scsi_Host *sh = cmd->device->host;926 struct aha1542_hostdata *aha1542 = shost_priv(sh);927 unsigned long flags;928 int i;929 930 spin_lock_irqsave(sh->host_lock, flags);931 /*932 * This does a scsi reset for all devices on the bus.933 * In principle, we could also reset the 1542 - should934 * we do this? Try this first, and we can add that later935 * if it turns out to be useful.936 */937 outb(reset_cmd, CONTROL(cmd->device->host->io_port));938 939 if (!wait_mask(STATUS(cmd->device->host->io_port),940 STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {941 spin_unlock_irqrestore(sh->host_lock, flags);942 return FAILED;943 }944 945 /*946 * We need to do this too before the 1542 can interact with947 * us again after host reset.948 */949 if (reset_cmd & HRST)950 setup_mailboxes(cmd->device->host);951 952 /*953 * Now try to pick up the pieces. For all pending commands,954 * free any internal data structures, and basically clear things955 * out. We do not try and restart any commands or anything -956 * the strategy handler takes care of that crap.957 */958 shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);959 960 for (i = 0; i < AHA1542_MAILBOXES; i++) {961 if (aha1542->int_cmds[i] != NULL) {962 struct scsi_cmnd *tmp_cmd;963 tmp_cmd = aha1542->int_cmds[i];964 965 if (tmp_cmd->device->soft_reset) {966 /*967 * If this device implements the soft reset option,968 * then it is still holding onto the command, and969 * may yet complete it. In this case, we don't970 * flush the data.971 */972 continue;973 }974 aha1542_free_cmd(tmp_cmd);975 aha1542->int_cmds[i] = NULL;976 aha1542->mb[i].status = 0;977 }978 }979 980 spin_unlock_irqrestore(sh->host_lock, flags);981 return SUCCESS;982}983 984static int aha1542_bus_reset(struct scsi_cmnd *cmd)985{986 return aha1542_reset(cmd, SCRST);987}988 989static int aha1542_host_reset(struct scsi_cmnd *cmd)990{991 return aha1542_reset(cmd, HRST | SCRST);992}993 994static int aha1542_biosparam(struct scsi_device *sdev,995 struct block_device *bdev, sector_t capacity, int geom[])996{997 struct aha1542_hostdata *aha1542 = shost_priv(sdev->host);998 999 if (capacity >= 0x200000 &&1000 aha1542->bios_translation == BIOS_TRANSLATION_25563) {1001 /* Please verify that this is the same as what DOS returns */1002 geom[0] = 255; /* heads */1003 geom[1] = 63; /* sectors */1004 } else {1005 geom[0] = 64; /* heads */1006 geom[1] = 32; /* sectors */1007 }1008 geom[2] = sector_div(capacity, geom[0] * geom[1]); /* cylinders */1009 1010 return 0;1011}1012 1013MODULE_DESCRIPTION("Adaptec AHA-1542 SCSI host adapter driver");1014MODULE_LICENSE("GPL");1015 1016static int aha1542_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)1017{1018 struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);1019 1020 acmd->data_buffer = dma_alloc_coherent(shost->dma_dev,1021 SECTOR_SIZE * AHA1542_MAX_SECTORS,1022 &acmd->data_buffer_handle, GFP_KERNEL);1023 if (!acmd->data_buffer)1024 return -ENOMEM;1025 return 0;1026}1027 1028static int aha1542_exit_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)1029{1030 struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);1031 1032 dma_free_coherent(shost->dma_dev, SECTOR_SIZE * AHA1542_MAX_SECTORS,1033 acmd->data_buffer, acmd->data_buffer_handle);1034 return 0;1035}1036 1037static const struct scsi_host_template driver_template = {1038 .module = THIS_MODULE,1039 .proc_name = "aha1542",1040 .name = "Adaptec 1542",1041 .cmd_size = sizeof(struct aha1542_cmd),1042 .queuecommand = aha1542_queuecommand,1043 .eh_device_reset_handler= aha1542_dev_reset,1044 .eh_bus_reset_handler = aha1542_bus_reset,1045 .eh_host_reset_handler = aha1542_host_reset,1046 .bios_param = aha1542_biosparam,1047 .init_cmd_priv = aha1542_init_cmd_priv,1048 .exit_cmd_priv = aha1542_exit_cmd_priv,1049 .can_queue = AHA1542_MAILBOXES,1050 .this_id = 7,1051 .max_sectors = AHA1542_MAX_SECTORS,1052 .sg_tablesize = SG_ALL,1053};1054 1055static int aha1542_isa_match(struct device *pdev, unsigned int ndev)1056{1057 struct Scsi_Host *sh = aha1542_hw_init(&driver_template, pdev, ndev);1058 1059 if (!sh)1060 return 0;1061 1062 dev_set_drvdata(pdev, sh);1063 return 1;1064}1065 1066static void aha1542_isa_remove(struct device *pdev,1067 unsigned int ndev)1068{1069 aha1542_release(dev_get_drvdata(pdev));1070 dev_set_drvdata(pdev, NULL);1071}1072 1073static struct isa_driver aha1542_isa_driver = {1074 .match = aha1542_isa_match,1075 .remove = aha1542_isa_remove,1076 .driver = {1077 .name = "aha1542"1078 },1079};1080static int isa_registered;1081 1082#ifdef CONFIG_PNP1083static const struct pnp_device_id aha1542_pnp_ids[] = {1084 { .id = "ADP1542" },1085 { .id = "" }1086};1087MODULE_DEVICE_TABLE(pnp, aha1542_pnp_ids);1088 1089static int aha1542_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)1090{1091 int indx;1092 struct Scsi_Host *sh;1093 1094 for (indx = 0; indx < ARRAY_SIZE(io); indx++) {1095 if (io[indx])1096 continue;1097 1098 if (pnp_activate_dev(pdev) < 0)1099 continue;1100 1101 io[indx] = pnp_port_start(pdev, 0);1102 1103 /*1104 * The card can be queried for its DMA, we have1105 * the DMA set up that is enough1106 */1107 1108 dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]);1109 }1110 1111 sh = aha1542_hw_init(&driver_template, &pdev->dev, indx);1112 if (!sh)1113 return -ENODEV;1114 1115 pnp_set_drvdata(pdev, sh);1116 return 0;1117}1118 1119static void aha1542_pnp_remove(struct pnp_dev *pdev)1120{1121 aha1542_release(pnp_get_drvdata(pdev));1122 pnp_set_drvdata(pdev, NULL);1123}1124 1125static struct pnp_driver aha1542_pnp_driver = {1126 .name = "aha1542",1127 .id_table = aha1542_pnp_ids,1128 .probe = aha1542_pnp_probe,1129 .remove = aha1542_pnp_remove,1130};1131static int pnp_registered;1132#endif /* CONFIG_PNP */1133 1134static int __init aha1542_init(void)1135{1136 int ret = 0;1137 1138#ifdef CONFIG_PNP1139 if (isapnp) {1140 ret = pnp_register_driver(&aha1542_pnp_driver);1141 if (!ret)1142 pnp_registered = 1;1143 }1144#endif1145 ret = isa_register_driver(&aha1542_isa_driver, MAXBOARDS);1146 if (!ret)1147 isa_registered = 1;1148 1149#ifdef CONFIG_PNP1150 if (pnp_registered)1151 ret = 0;1152#endif1153 if (isa_registered)1154 ret = 0;1155 1156 return ret;1157}1158 1159static void __exit aha1542_exit(void)1160{1161#ifdef CONFIG_PNP1162 if (pnp_registered)1163 pnp_unregister_driver(&aha1542_pnp_driver);1164#endif1165 if (isa_registered)1166 isa_unregister_driver(&aha1542_isa_driver);1167}1168 1169module_init(aha1542_init);1170module_exit(aha1542_exit);1171