Lines Matching +full:hw +full:- +full:settle +full:- +full:time
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for Adaptec AHA-1542 SCSI host adapters
38 /* time AHA spends on the AT-bus during data transfer */
39 static int bus_on[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 11us */
41 MODULE_PARM_DESC(bus_on, "bus on time [us] (2-15, default=-1 [HW default: 11])");
43 /* time AHA spends off the bus (not to monopolize it) during data transfer */
44 static int bus_off[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 4us */
46 MODULE_PARM_DESC(bus_off, "bus off time [us] (1-64, default=-1 [HW default: 4])");
49 static int dma_speed[MAXBOARDS] = { -1, -1, -1, -1 };
51 MODULE_PARM_DESC(dma_speed, "DMA speed [MB/s] (5,6,7,8,10, default=-1 [by jumper])");
58 int bios_translation; /* Mapping bios uses - for compatibility */
93 if (--timeout == 0) in wait_mask()
111 while (len--) { in aha1542_out()
122 /* Only used at boot time, so we do not need to worry about latency as much
127 while (len--) { in aha1542_in()
144 case 0x11: /* Selection time out-The initiator selection or target in makecode()
145 reselection was not complete within the SCSI Time out period */ in makecode()
149 case 0x12: /* Data overrun/underrun-The target attempted to transfer more data in makecode()
153 case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ in makecode()
155 case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was in makecode()
158 case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. in makecode()
161 case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set in makecode()
164 case 0x18: /* Invalid Target Direction received from Host-The direction of a in makecode()
167 case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was in makecode()
171 case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero in makecode()
180 case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus in makecode()
199 if (inb(STATUS(sh->io_port)) == 0xff) in aha1542_test_port()
205 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */ in aha1542_test_port()
207 outb(SRST | IRST /*|SCRST */ , CONTROL(sh->io_port)); in aha1542_test_port()
209 mdelay(20); /* Wait a little bit for things to settle down. */ in aha1542_test_port()
212 if (!wait_mask(STATUS(sh->io_port), STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) in aha1542_test_port()
216 if (inb(INTRFLAGS(sh->io_port)) & INTRMASK) in aha1542_test_port()
220 up the mailboxes ahead of time */ in aha1542_test_port()
222 aha1542_outb(sh->io_port, CMD_INQUIRY); in aha1542_test_port()
225 if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0)) in aha1542_test_port()
227 inquiry_result[i] = inb(DATA(sh->io_port)); in aha1542_test_port()
231 if (inb(STATUS(sh->io_port)) & DF) in aha1542_test_port()
235 if (!wait_mask(INTRFLAGS(sh->io_port), HACC, HACC, 0, 0)) in aha1542_test_port()
239 outb(IRST, CONTROL(sh->io_port)); in aha1542_test_port()
247 struct device *dev = cmd->device->host->dma_dev; in aha1542_free_cmd()
250 if (acmd->chain) { in aha1542_free_cmd()
251 dma_unmap_single(dev, acmd->chain_handle, len, DMA_TO_DEVICE); in aha1542_free_cmd()
252 kfree(acmd->chain); in aha1542_free_cmd()
255 acmd->chain = NULL; in aha1542_free_cmd()
269 struct mailbox *mb = aha1542->mb; in aha1542_interrupt()
270 struct ccb *ccb = aha1542->ccb; in aha1542_interrupt()
274 flag = inb(INTRFLAGS(sh->io_port)); in aha1542_interrupt()
286 printk("status %02x\n", inb(STATUS(sh->io_port))); in aha1542_interrupt()
291 spin_lock_irqsave(sh->host_lock, flags); in aha1542_interrupt()
293 flag = inb(INTRFLAGS(sh->io_port)); in aha1542_interrupt()
307 aha1542_intr_reset(sh->io_port); in aha1542_interrupt()
309 mbi = aha1542->aha1542_last_mbi_used + 1; in aha1542_interrupt()
319 } while (mbi != aha1542->aha1542_last_mbi_used); in aha1542_interrupt()
322 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_interrupt()
323 /* Hmm, no mail. Must have read it the last time around */ in aha1542_interrupt()
329 mbo = (scsi2int(mb[mbi].ccbptr) - (unsigned long)aha1542->ccb_handle) / sizeof(struct ccb); in aha1542_interrupt()
332 aha1542->aha1542_last_mbi_used = mbi; in aha1542_interrupt()
347 tmp_cmd = aha1542->int_cmds[mbo]; in aha1542_interrupt()
349 if (!tmp_cmd || !tmp_cmd->scsi_done) { in aha1542_interrupt()
350 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_interrupt()
356 my_done = tmp_cmd->scsi_done; in aha1542_interrupt()
362 memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen], in aha1542_interrupt()
366 /* is there mail :-) */ in aha1542_interrupt()
384 tmp_cmd->result = errstatus; in aha1542_interrupt()
385 aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as in aha1542_interrupt()
397 u8 target = cmd->device->id; in aha1542_queuecommand()
398 u8 lun = cmd->device->lun; in aha1542_queuecommand()
402 struct mailbox *mb = aha1542->mb; in aha1542_queuecommand()
403 struct ccb *ccb = aha1542->ccb; in aha1542_queuecommand()
405 if (*cmd->cmnd == REQUEST_SENSE) { in aha1542_queuecommand()
406 /* Don't do the command - we have the sense data already */ in aha1542_queuecommand()
407 cmd->result = 0; in aha1542_queuecommand()
408 cmd->scsi_done(cmd); in aha1542_queuecommand()
413 int i = -1; in aha1542_queuecommand()
414 if (*cmd->cmnd == READ_10 || *cmd->cmnd == WRITE_10) in aha1542_queuecommand()
415 i = xscsi2int(cmd->cmnd + 2); in aha1542_queuecommand()
416 else if (*cmd->cmnd == READ_6 || *cmd->cmnd == WRITE_6) in aha1542_queuecommand()
417 i = scsi2int(cmd->cmnd + 2); in aha1542_queuecommand()
419 target, *cmd->cmnd, i, bufflen); in aha1542_queuecommand()
420 print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len); in aha1542_queuecommand()
427 acmd->chain = kmalloc(len, GFP_DMA); in aha1542_queuecommand()
428 if (!acmd->chain) in aha1542_queuecommand()
430 acmd->chain_handle = dma_map_single(sh->dma_dev, acmd->chain, in aha1542_queuecommand()
432 if (dma_mapping_error(sh->dma_dev, acmd->chain_handle)) in aha1542_queuecommand()
436 /* Use the outgoing mailboxes in a round-robin fashion, because this in aha1542_queuecommand()
439 spin_lock_irqsave(sh->host_lock, flags); in aha1542_queuecommand()
440 mbo = aha1542->aha1542_last_mbo_used + 1; in aha1542_queuecommand()
445 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL) in aha1542_queuecommand()
450 } while (mbo != aha1542->aha1542_last_mbo_used); in aha1542_queuecommand()
452 if (mb[mbo].status || aha1542->int_cmds[mbo]) in aha1542_queuecommand()
455 aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from in aha1542_queuecommand()
458 aha1542->aha1542_last_mbo_used = mbo; in aha1542_queuecommand()
461 shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done); in aha1542_queuecommand()
465 any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb)); in aha1542_queuecommand()
469 ccb[mbo].cdblen = cmd->cmd_len; in aha1542_queuecommand()
472 if (*cmd->cmnd == READ_10 || *cmd->cmnd == READ_6) in aha1542_queuecommand()
474 else if (*cmd->cmnd == WRITE_10 || *cmd->cmnd == WRITE_6) in aha1542_queuecommand()
477 memcpy(ccb[mbo].cdb, cmd->cmnd, ccb[mbo].cdblen); in aha1542_queuecommand()
483 ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */ in aha1542_queuecommand()
485 any2scsi(acmd->chain[i].dataptr, sg_dma_address(sg)); in aha1542_queuecommand()
486 any2scsi(acmd->chain[i].datalen, sg_dma_len(sg)); in aha1542_queuecommand()
489 any2scsi(ccb[mbo].dataptr, acmd->chain_handle); in aha1542_queuecommand()
491 shost_printk(KERN_DEBUG, sh, "cptr %p: ", acmd->chain); in aha1542_queuecommand()
492 print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, acmd->chain, 18); in aha1542_queuecommand()
505 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10); in aha1542_queuecommand()
509 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI); in aha1542_queuecommand()
510 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_queuecommand()
514 kfree(acmd->chain); in aha1542_queuecommand()
515 acmd->chain = NULL; in aha1542_queuecommand()
529 aha1542->mb[i].status = 0; in setup_mailboxes()
530 any2scsi(aha1542->mb[i].ccbptr, in setup_mailboxes()
531 aha1542->ccb_handle + i * sizeof(struct ccb)); in setup_mailboxes()
532 aha1542->mb[AHA1542_MAILBOXES + i].status = 0; in setup_mailboxes()
534 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */ in setup_mailboxes()
535 any2scsi(mb_cmd + 2, aha1542->mb_handle); in setup_mailboxes()
536 if (aha1542_out(sh->io_port, mb_cmd, 5)) in setup_mailboxes()
538 aha1542_intr_reset(sh->io_port); in setup_mailboxes()
545 i = inb(STATUS(sh->io_port)); in aha1542_getconfig()
547 i = inb(DATA(sh->io_port)); in aha1542_getconfig()
549 aha1542_outb(sh->io_port, CMD_RETCONF); in aha1542_getconfig()
550 aha1542_in(sh->io_port, inquiry_result, 3, 0); in aha1542_getconfig()
551 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0)) in aha1542_getconfig()
553 aha1542_intr_reset(sh->io_port); in aha1542_getconfig()
556 sh->dma_channel = 7; in aha1542_getconfig()
559 sh->dma_channel = 6; in aha1542_getconfig()
562 sh->dma_channel = 5; in aha1542_getconfig()
565 sh->dma_channel = 0; in aha1542_getconfig()
569 Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */ in aha1542_getconfig()
570 sh->dma_channel = 0xFF; in aha1542_getconfig()
574 return -1; in aha1542_getconfig()
578 sh->irq = 15; in aha1542_getconfig()
581 sh->irq = 14; in aha1542_getconfig()
584 sh->irq = 12; in aha1542_getconfig()
587 sh->irq = 11; in aha1542_getconfig()
590 sh->irq = 10; in aha1542_getconfig()
593 sh->irq = 9; in aha1542_getconfig()
597 return -1; in aha1542_getconfig()
599 sh->this_id = inquiry_result[2] & 7; in aha1542_getconfig()
603 /* This function should only be called for 1542C boards - we can detect
614 aha1542_outb(sh->io_port, CMD_EXTBIOS); in aha1542_mbenable()
615 if (aha1542_in(sh->io_port, mbenable_result, 2, 100)) in aha1542_mbenable()
617 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 100)) in aha1542_mbenable()
619 aha1542_intr_reset(sh->io_port); in aha1542_mbenable()
629 if (aha1542_out(sh->io_port, mbenable_cmd, 3)) in aha1542_mbenable()
636 aha1542_intr_reset(sh->io_port); in aha1542_mbenable()
646 i = inb(STATUS(sh->io_port)); in aha1542_query()
648 i = inb(DATA(sh->io_port)); in aha1542_query()
650 aha1542_outb(sh->io_port, CMD_INQUIRY); in aha1542_query()
651 aha1542_in(sh->io_port, inquiry_result, 4, 0); in aha1542_query()
652 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0)) in aha1542_query()
654 aha1542_intr_reset(sh->io_port); in aha1542_query()
656 aha1542->bios_translation = BIOS_TRANSLATION_6432; /* Default case */ in aha1542_query()
665 …shost_printk(KERN_INFO, sh, "Emulation mode not supported for AHA-1740 hardware, use aha1740 drive… in aha1542_query()
669 /* Always call this - boards that do not support extended bios translation in aha1542_query()
672 aha1542->bios_translation = aha1542_mbenable(sh); in aha1542_query()
695 /* Set the Bus on/off-times as not to ruin floppy performance */
701 aha1542_intr_reset(sh->io_port); in aha1542_set_bus_times()
702 if (aha1542_out(sh->io_port, oncmd, 2)) in aha1542_set_bus_times()
709 aha1542_intr_reset(sh->io_port); in aha1542_set_bus_times()
710 if (aha1542_out(sh->io_port, offcmd, 2)) in aha1542_set_bus_times()
717 aha1542_intr_reset(sh->io_port); in aha1542_set_bus_times()
718 if (aha1542_out(sh->io_port, dmacmd, 2)) in aha1542_set_bus_times()
721 aha1542_intr_reset(sh->io_port); in aha1542_set_bus_times()
724 shost_printk(KERN_ERR, sh, "setting bus on/off-time failed\n"); in aha1542_set_bus_times()
725 aha1542_intr_reset(sh->io_port); in aha1542_set_bus_times()
728 /* return non-zero on detection */
747 sh->unique_id = base_io; in aha1542_hw_init()
748 sh->io_port = base_io; in aha1542_hw_init()
749 sh->n_io_port = AHA1542_REGION_SIZE; in aha1542_hw_init()
750 aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1; in aha1542_hw_init()
751 aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1; in aha1542_hw_init()
759 if (aha1542_getconfig(sh) == -1) in aha1542_hw_init()
762 if (sh->dma_channel != 0xFF) in aha1542_hw_init()
763 snprintf(dma_info, sizeof(dma_info), "DMA %d", sh->dma_channel); in aha1542_hw_init()
764 shost_printk(KERN_INFO, sh, "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d, %s\n", in aha1542_hw_init()
765 sh->this_id, base_io, sh->irq, dma_info); in aha1542_hw_init()
766 if (aha1542->bios_translation == BIOS_TRANSLATION_25563) in aha1542_hw_init()
772 aha1542->mb = dma_alloc_coherent(pdev, in aha1542_hw_init()
774 &aha1542->mb_handle, GFP_KERNEL); in aha1542_hw_init()
775 if (!aha1542->mb) in aha1542_hw_init()
778 aha1542->ccb = dma_alloc_coherent(pdev, in aha1542_hw_init()
780 &aha1542->ccb_handle, GFP_KERNEL); in aha1542_hw_init()
781 if (!aha1542->ccb) in aha1542_hw_init()
786 if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) { in aha1542_hw_init()
790 if (sh->dma_channel != 0xFF) { in aha1542_hw_init()
791 if (request_dma(sh->dma_channel, "aha1542")) { in aha1542_hw_init()
795 if (sh->dma_channel == 0 || sh->dma_channel >= 5) { in aha1542_hw_init()
796 set_dma_mode(sh->dma_channel, DMA_MODE_CASCADE); in aha1542_hw_init()
797 enable_dma(sh->dma_channel); in aha1542_hw_init()
809 if (sh->dma_channel != 0xff) in aha1542_hw_init()
810 free_dma(sh->dma_channel); in aha1542_hw_init()
812 free_irq(sh->irq, sh); in aha1542_hw_init()
815 aha1542->ccb, aha1542->ccb_handle); in aha1542_hw_init()
818 aha1542->mb, aha1542->mb_handle); in aha1542_hw_init()
830 struct device *dev = sh->dma_dev; in aha1542_release()
833 if (sh->dma_channel != 0xff) in aha1542_release()
834 free_dma(sh->dma_channel); in aha1542_release()
836 aha1542->ccb, aha1542->ccb_handle); in aha1542_release()
838 aha1542->mb, aha1542->mb_handle); in aha1542_release()
839 if (sh->irq) in aha1542_release()
840 free_irq(sh->irq, sh); in aha1542_release()
841 if (sh->io_port && sh->n_io_port) in aha1542_release()
842 release_region(sh->io_port, sh->n_io_port); in aha1542_release()
854 struct Scsi_Host *sh = cmd->device->host; in aha1542_dev_reset()
857 struct mailbox *mb = aha1542->mb; in aha1542_dev_reset()
858 u8 target = cmd->device->id; in aha1542_dev_reset()
859 u8 lun = cmd->device->lun; in aha1542_dev_reset()
861 struct ccb *ccb = aha1542->ccb; in aha1542_dev_reset()
863 spin_lock_irqsave(sh->host_lock, flags); in aha1542_dev_reset()
864 mbo = aha1542->aha1542_last_mbo_used + 1; in aha1542_dev_reset()
869 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL) in aha1542_dev_reset()
874 } while (mbo != aha1542->aha1542_last_mbo_used); in aha1542_dev_reset()
876 if (mb[mbo].status || aha1542->int_cmds[mbo]) in aha1542_dev_reset()
879 aha1542->int_cmds[mbo] = cmd; /* This will effectively in aha1542_dev_reset()
883 aha1542->aha1542_last_mbo_used = mbo; in aha1542_dev_reset()
886 any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb)); in aha1542_dev_reset()
901 aha1542_outb(sh->io_port, CMD_START_SCSI); in aha1542_dev_reset()
902 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_dev_reset()
912 struct Scsi_Host *sh = cmd->device->host; in aha1542_reset()
917 spin_lock_irqsave(sh->host_lock, flags); in aha1542_reset()
920 * In principle, we could also reset the 1542 - should in aha1542_reset()
924 outb(reset_cmd, CONTROL(cmd->device->host->io_port)); in aha1542_reset()
926 if (!wait_mask(STATUS(cmd->device->host->io_port), in aha1542_reset()
928 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_reset()
937 setup_mailboxes(cmd->device->host); in aha1542_reset()
942 * out. We do not try and restart any commands or anything - in aha1542_reset()
945 …shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->hos… in aha1542_reset()
948 if (aha1542->int_cmds[i] != NULL) { in aha1542_reset()
950 tmp_cmd = aha1542->int_cmds[i]; in aha1542_reset()
952 if (tmp_cmd->device->soft_reset) { in aha1542_reset()
962 aha1542->int_cmds[i] = NULL; in aha1542_reset()
963 aha1542->mb[i].status = 0; in aha1542_reset()
967 spin_unlock_irqrestore(sh->host_lock, flags); in aha1542_reset()
984 struct aha1542_hostdata *aha1542 = shost_priv(sdev->host); in aha1542_biosparam()
987 aha1542->bios_translation == BIOS_TRANSLATION_25563) { in aha1542_biosparam()
1069 dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]); in aha1542_pnp_probe()
1072 sh = aha1542_hw_init(&driver_template, &pdev->dev, indx); in aha1542_pnp_probe()
1074 return -ENODEV; in aha1542_pnp_probe()