aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic79xx_osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c561
1 files changed, 260 insertions, 301 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 7254ea535a16..bcced0a417e6 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -373,8 +373,7 @@ static void ahd_linux_handle_scsi_status(struct ahd_softc *,
373 struct scb *); 373 struct scb *);
374static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, 374static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
375 struct scsi_cmnd *cmd); 375 struct scsi_cmnd *cmd);
376static void ahd_linux_sem_timeout(u_long arg); 376static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd);
377static int ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
378static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); 377static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
379static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, 378static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
380 struct ahd_devinfo *devinfo); 379 struct ahd_devinfo *devinfo);
@@ -453,18 +452,13 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
453 struct ahd_softc *ahd; 452 struct ahd_softc *ahd;
454 struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device); 453 struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
455 int rtn = SCSI_MLQUEUE_HOST_BUSY; 454 int rtn = SCSI_MLQUEUE_HOST_BUSY;
456 unsigned long flags;
457 455
458 ahd = *(struct ahd_softc **)cmd->device->host->hostdata; 456 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
459 457
460 ahd_lock(ahd, &flags); 458 cmd->scsi_done = scsi_done;
461 if (ahd->platform_data->qfrozen == 0) { 459 cmd->result = CAM_REQ_INPROG << 16;
462 cmd->scsi_done = scsi_done; 460 rtn = ahd_linux_run_command(ahd, dev, cmd);
463 cmd->result = CAM_REQ_INPROG << 16;
464 rtn = ahd_linux_run_command(ahd, dev, cmd);
465 461
466 }
467 ahd_unlock(ahd, &flags);
468 return rtn; 462 return rtn;
469} 463}
470 464
@@ -487,6 +481,7 @@ ahd_linux_target_alloc(struct scsi_target *starget)
487{ 481{
488 struct ahd_softc *ahd = 482 struct ahd_softc *ahd =
489 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata); 483 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
484 struct seeprom_config *sc = ahd->seep_config;
490 unsigned long flags; 485 unsigned long flags;
491 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); 486 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
492 struct ahd_linux_target *targ = scsi_transport_target_data(starget); 487 struct ahd_linux_target *targ = scsi_transport_target_data(starget);
@@ -502,18 +497,38 @@ ahd_linux_target_alloc(struct scsi_target *starget)
502 *ahd_targp = starget; 497 *ahd_targp = starget;
503 memset(targ, 0, sizeof(*targ)); 498 memset(targ, 0, sizeof(*targ));
504 499
500 if (sc) {
501 int flags = sc->device_flags[starget->id];
502
503 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
504 starget->id, &tstate);
505
506 if ((flags & CFPACKETIZED) == 0) {
507 /* Do not negotiate packetized transfers */
508 spi_rd_strm(starget) = 0;
509 spi_pcomp_en(starget) = 0;
510 spi_rti(starget) = 0;
511 spi_wr_flow(starget) = 0;
512 spi_hold_mcs(starget) = 0;
513 } else {
514 if ((ahd->features & AHD_RTI) == 0)
515 spi_rti(starget) = 0;
516 }
517
518 if ((flags & CFQAS) == 0)
519 spi_qas(starget) = 0;
520
521 /* Transinfo values have been set to BIOS settings */
522 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
523 spi_min_period(starget) = tinfo->user.period;
524 spi_max_offset(starget) = tinfo->user.offset;
525 }
526
505 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id, 527 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
506 starget->id, &tstate); 528 starget->id, &tstate);
507 ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id, 529 ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
508 CAM_LUN_WILDCARD, channel, 530 CAM_LUN_WILDCARD, channel,
509 ROLE_INITIATOR); 531 ROLE_INITIATOR);
510 spi_min_period(starget) = AHD_SYNCRATE_MAX; /* We can do U320 */
511 if ((ahd->bugs & AHD_PACED_NEGTABLE_BUG) != 0)
512 spi_max_offset(starget) = MAX_OFFSET_PACED_BUG;
513 else
514 spi_max_offset(starget) = MAX_OFFSET_PACED;
515 spi_max_width(starget) = ahd->features & AHD_WIDE;
516
517 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0, 532 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
518 AHD_TRANS_GOAL, /*paused*/FALSE); 533 AHD_TRANS_GOAL, /*paused*/FALSE);
519 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, 534 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
@@ -654,10 +669,9 @@ static int
654ahd_linux_abort(struct scsi_cmnd *cmd) 669ahd_linux_abort(struct scsi_cmnd *cmd)
655{ 670{
656 int error; 671 int error;
672
673 error = ahd_linux_queue_abort_cmd(cmd);
657 674
658 error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT);
659 if (error != 0)
660 printf("aic79xx_abort returns 0x%x\n", error);
661 return error; 675 return error;
662} 676}
663 677
@@ -667,12 +681,97 @@ ahd_linux_abort(struct scsi_cmnd *cmd)
667static int 681static int
668ahd_linux_dev_reset(struct scsi_cmnd *cmd) 682ahd_linux_dev_reset(struct scsi_cmnd *cmd)
669{ 683{
670 int error; 684 struct ahd_softc *ahd;
685 struct ahd_linux_device *dev;
686 struct scb *reset_scb;
687 u_int cdb_byte;
688 int retval = SUCCESS;
689 int paused;
690 int wait;
691 struct ahd_initiator_tinfo *tinfo;
692 struct ahd_tmode_tstate *tstate;
693 unsigned long flags;
694 DECLARE_COMPLETION(done);
671 695
672 error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); 696 reset_scb = NULL;
673 if (error != 0) 697 paused = FALSE;
674 printf("aic79xx_dev_reset returns 0x%x\n", error); 698 wait = FALSE;
675 return error; 699 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
700
701 scmd_printk(KERN_INFO, cmd,
702 "Attempting to queue a TARGET RESET message:");
703
704 printf("CDB:");
705 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
706 printf(" 0x%x", cmd->cmnd[cdb_byte]);
707 printf("\n");
708
709 /*
710 * Determine if we currently own this command.
711 */
712 dev = scsi_transport_device_data(cmd->device);
713
714 if (dev == NULL) {
715 /*
716 * No target device for this command exists,
717 * so we must not still own the command.
718 */
719 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
720 return SUCCESS;
721 }
722
723 /*
724 * Generate us a new SCB
725 */
726 reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
727 if (!reset_scb) {
728 scmd_printk(KERN_INFO, cmd, "No SCB available\n");
729 return FAILED;
730 }
731
732 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
733 cmd->device->id, &tstate);
734 reset_scb->io_ctx = cmd;
735 reset_scb->platform_data->dev = dev;
736 reset_scb->sg_count = 0;
737 ahd_set_residual(reset_scb, 0);
738 ahd_set_sense_residual(reset_scb, 0);
739 reset_scb->platform_data->xfer_len = 0;
740 reset_scb->hscb->control = 0;
741 reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
742 reset_scb->hscb->lun = cmd->device->lun;
743 reset_scb->hscb->cdb_len = 0;
744 reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
745 reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
746 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
747 reset_scb->flags |= SCB_PACKETIZED;
748 } else {
749 reset_scb->hscb->control |= MK_MESSAGE;
750 }
751 dev->openings--;
752 dev->active++;
753 dev->commands_issued++;
754
755 ahd_lock(ahd, &flags);
756
757 LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
758 ahd_queue_scb(ahd, reset_scb);
759
760 ahd->platform_data->eh_done = &done;
761 ahd_unlock(ahd, &flags);
762
763 printf("%s: Device reset code sleeping\n", ahd_name(ahd));
764 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
765 ahd_lock(ahd, &flags);
766 ahd->platform_data->eh_done = NULL;
767 ahd_unlock(ahd, &flags);
768 printf("%s: Device reset timer expired (active %d)\n",
769 ahd_name(ahd), dev->active);
770 retval = FAILED;
771 }
772 printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
773
774 return (retval);
676} 775}
677 776
678/* 777/*
@@ -682,7 +781,6 @@ static int
682ahd_linux_bus_reset(struct scsi_cmnd *cmd) 781ahd_linux_bus_reset(struct scsi_cmnd *cmd)
683{ 782{
684 struct ahd_softc *ahd; 783 struct ahd_softc *ahd;
685 u_long s;
686 int found; 784 int found;
687 785
688 ahd = *(struct ahd_softc **)cmd->device->host->hostdata; 786 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
@@ -691,10 +789,8 @@ ahd_linux_bus_reset(struct scsi_cmnd *cmd)
691 printf("%s: Bus reset called for cmd %p\n", 789 printf("%s: Bus reset called for cmd %p\n",
692 ahd_name(ahd), cmd); 790 ahd_name(ahd), cmd);
693#endif 791#endif
694 ahd_lock(ahd, &s);
695 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A', 792 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
696 /*initiate reset*/TRUE); 793 /*initiate reset*/TRUE);
697 ahd_unlock(ahd, &s);
698 794
699 if (bootverbose) 795 if (bootverbose)
700 printf("%s: SCSI bus reset delivered. " 796 printf("%s: SCSI bus reset delivered. "
@@ -811,59 +907,6 @@ ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
811} 907}
812 908
813/********************* Platform Dependent Functions ***************************/ 909/********************* Platform Dependent Functions ***************************/
814/*
815 * Compare "left hand" softc with "right hand" softc, returning:
816 * < 0 - lahd has a lower priority than rahd
817 * 0 - Softcs are equal
818 * > 0 - lahd has a higher priority than rahd
819 */
820int
821ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd)
822{
823 int value;
824
825 /*
826 * Under Linux, cards are ordered as follows:
827 * 1) PCI devices that are marked as the boot controller.
828 * 2) PCI devices with BIOS enabled sorted by bus/slot/func.
829 * 3) All remaining PCI devices sorted by bus/slot/func.
830 */
831#if 0
832 value = (lahd->flags & AHD_BOOT_CHANNEL)
833 - (rahd->flags & AHD_BOOT_CHANNEL);
834 if (value != 0)
835 /* Controllers set for boot have a *higher* priority */
836 return (value);
837#endif
838
839 value = (lahd->flags & AHD_BIOS_ENABLED)
840 - (rahd->flags & AHD_BIOS_ENABLED);
841 if (value != 0)
842 /* Controllers with BIOS enabled have a *higher* priority */
843 return (value);
844
845 /* Still equal. Sort by bus/slot/func. */
846 if (aic79xx_reverse_scan != 0)
847 value = ahd_get_pci_bus(lahd->dev_softc)
848 - ahd_get_pci_bus(rahd->dev_softc);
849 else
850 value = ahd_get_pci_bus(rahd->dev_softc)
851 - ahd_get_pci_bus(lahd->dev_softc);
852 if (value != 0)
853 return (value);
854 if (aic79xx_reverse_scan != 0)
855 value = ahd_get_pci_slot(lahd->dev_softc)
856 - ahd_get_pci_slot(rahd->dev_softc);
857 else
858 value = ahd_get_pci_slot(rahd->dev_softc)
859 - ahd_get_pci_slot(lahd->dev_softc);
860 if (value != 0)
861 return (value);
862
863 value = rahd->channel - lahd->channel;
864 return (value);
865}
866
867static void 910static void
868ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value) 911ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
869{ 912{
@@ -1194,7 +1237,6 @@ ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1194 memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data)); 1237 memset(ahd->platform_data, 0, sizeof(struct ahd_platform_data));
1195 ahd->platform_data->irq = AHD_LINUX_NOIRQ; 1238 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
1196 ahd_lockinit(ahd); 1239 ahd_lockinit(ahd);
1197 init_MUTEX_LOCKED(&ahd->platform_data->eh_sem);
1198 ahd->seltime = (aic79xx_seltime & 0x3) << 4; 1240 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
1199 return (0); 1241 return (0);
1200} 1242}
@@ -1346,14 +1388,12 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
1346 1388
1347 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) { 1389 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
1348 case AHD_DEV_Q_BASIC: 1390 case AHD_DEV_Q_BASIC:
1349 scsi_adjust_queue_depth(sdev, 1391 scsi_set_tag_type(sdev, MSG_SIMPLE_TASK);
1350 MSG_SIMPLE_TASK, 1392 scsi_activate_tcq(sdev, dev->openings + dev->active);
1351 dev->openings + dev->active);
1352 break; 1393 break;
1353 case AHD_DEV_Q_TAGGED: 1394 case AHD_DEV_Q_TAGGED:
1354 scsi_adjust_queue_depth(sdev, 1395 scsi_set_tag_type(sdev, MSG_ORDERED_TASK);
1355 MSG_ORDERED_TASK, 1396 scsi_activate_tcq(sdev, dev->openings + dev->active);
1356 dev->openings + dev->active);
1357 break; 1397 break;
1358 default: 1398 default:
1359 /* 1399 /*
@@ -1362,9 +1402,7 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
1362 * serially on the controller/device. This should 1402 * serially on the controller/device. This should
1363 * remove some latency. 1403 * remove some latency.
1364 */ 1404 */
1365 scsi_adjust_queue_depth(sdev, 1405 scsi_deactivate_tcq(sdev, 1);
1366 /*NON-TAGGED*/0,
1367 /*queue depth*/2);
1368 break; 1406 break;
1369 } 1407 }
1370} 1408}
@@ -1443,6 +1481,9 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1443 struct ahd_tmode_tstate *tstate; 1481 struct ahd_tmode_tstate *tstate;
1444 u_int col_idx; 1482 u_int col_idx;
1445 uint16_t mask; 1483 uint16_t mask;
1484 unsigned long flags;
1485
1486 ahd_lock(ahd, &flags);
1446 1487
1447 /* 1488 /*
1448 * Get an scb to use. 1489 * Get an scb to use.
@@ -1458,6 +1499,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1458 } 1499 }
1459 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { 1500 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
1460 ahd->flags |= AHD_RESOURCE_SHORTAGE; 1501 ahd->flags |= AHD_RESOURCE_SHORTAGE;
1502 ahd_unlock(ahd, &flags);
1461 return SCSI_MLQUEUE_HOST_BUSY; 1503 return SCSI_MLQUEUE_HOST_BUSY;
1462 } 1504 }
1463 1505
@@ -1484,30 +1526,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1484 if ((tstate->auto_negotiate & mask) != 0) { 1526 if ((tstate->auto_negotiate & mask) != 0) {
1485 scb->flags |= SCB_AUTO_NEGOTIATE; 1527 scb->flags |= SCB_AUTO_NEGOTIATE;
1486 scb->hscb->control |= MK_MESSAGE; 1528 scb->hscb->control |= MK_MESSAGE;
1487 } else if (cmd->cmnd[0] == INQUIRY
1488 && (tinfo->curr.offset != 0
1489 || tinfo->curr.width != MSG_EXT_WDTR_BUS_8_BIT
1490 || tinfo->curr.ppr_options != 0)
1491 && (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ)==0) {
1492 /*
1493 * The SCSI spec requires inquiry
1494 * commands to complete without
1495 * reporting unit attention conditions.
1496 * Because of this, an inquiry command
1497 * that occurs just after a device is
1498 * reset will result in a data phase
1499 * with mismatched negotiated rates.
1500 * The core already forces a renegotiation
1501 * for reset events that are visible to
1502 * our controller or that we initiate,
1503 * but a third party device reset or a
1504 * hot-plug insertion can still cause this
1505 * issue. Therefore, we force a re-negotiation
1506 * for every inquiry command unless we
1507 * are async.
1508 */
1509 scb->flags |= SCB_NEGOTIATE;
1510 scb->hscb->control |= MK_MESSAGE;
1511 } 1529 }
1512 1530
1513 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) { 1531 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
@@ -1583,6 +1601,8 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1583 scb->flags |= SCB_ACTIVE; 1601 scb->flags |= SCB_ACTIVE;
1584 ahd_queue_scb(ahd, scb); 1602 ahd_queue_scb(ahd, scb);
1585 1603
1604 ahd_unlock(ahd, &flags);
1605
1586 return 0; 1606 return 0;
1587} 1607}
1588 1608
@@ -1604,12 +1624,6 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
1604} 1624}
1605 1625
1606void 1626void
1607ahd_platform_flushwork(struct ahd_softc *ahd)
1608{
1609
1610}
1611
1612void
1613ahd_send_async(struct ahd_softc *ahd, char channel, 1627ahd_send_async(struct ahd_softc *ahd, char channel,
1614 u_int target, u_int lun, ac_code code, void *arg) 1628 u_int target, u_int lun, ac_code code, void *arg)
1615{ 1629{
@@ -1618,7 +1632,6 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
1618 { 1632 {
1619 char buf[80]; 1633 char buf[80];
1620 struct scsi_target *starget; 1634 struct scsi_target *starget;
1621 struct ahd_linux_target *targ;
1622 struct info_str info; 1635 struct info_str info;
1623 struct ahd_initiator_tinfo *tinfo; 1636 struct ahd_initiator_tinfo *tinfo;
1624 struct ahd_tmode_tstate *tstate; 1637 struct ahd_tmode_tstate *tstate;
@@ -1651,7 +1664,6 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
1651 starget = ahd->platform_data->starget[target]; 1664 starget = ahd->platform_data->starget[target];
1652 if (starget == NULL) 1665 if (starget == NULL)
1653 break; 1666 break;
1654 targ = scsi_transport_target_data(starget);
1655 1667
1656 target_ppr_options = 1668 target_ppr_options =
1657 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0) 1669 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
@@ -1803,10 +1815,9 @@ ahd_done(struct ahd_softc *ahd, struct scb *scb)
1803 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT 1815 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
1804 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) 1816 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
1805 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); 1817 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1806 if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) { 1818
1807 ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM; 1819 if (ahd->platform_data->eh_done)
1808 up(&ahd->platform_data->eh_sem); 1820 complete(ahd->platform_data->eh_done);
1809 }
1810 } 1821 }
1811 1822
1812 ahd_free_scb(ahd, scb); 1823 ahd_free_scb(ahd, scb);
@@ -1961,133 +1972,125 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1961static void 1972static void
1962ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd) 1973ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
1963{ 1974{
1975 int status;
1976 int new_status = DID_OK;
1977 int do_fallback = 0;
1978 int scsi_status;
1979
1964 /* 1980 /*
1965 * Map CAM error codes into Linux Error codes. We 1981 * Map CAM error codes into Linux Error codes. We
1966 * avoid the conversion so that the DV code has the 1982 * avoid the conversion so that the DV code has the
1967 * full error information available when making 1983 * full error information available when making
1968 * state change decisions. 1984 * state change decisions.
1969 */ 1985 */
1970 { 1986
1971 uint32_t status; 1987 status = ahd_cmd_get_transaction_status(cmd);
1972 u_int new_status; 1988 switch (status) {
1973 1989 case CAM_REQ_INPROG:
1974 status = ahd_cmd_get_transaction_status(cmd); 1990 case CAM_REQ_CMP:
1975 switch (status) { 1991 new_status = DID_OK;
1976 case CAM_REQ_INPROG: 1992 break;
1977 case CAM_REQ_CMP: 1993 case CAM_AUTOSENSE_FAIL:
1978 case CAM_SCSI_STATUS_ERROR: 1994 new_status = DID_ERROR;
1979 new_status = DID_OK; 1995 /* Fallthrough */
1980 break; 1996 case CAM_SCSI_STATUS_ERROR:
1981 case CAM_REQ_ABORTED: 1997 scsi_status = ahd_cmd_get_scsi_status(cmd);
1982 new_status = DID_ABORT; 1998
1983 break; 1999 switch(scsi_status) {
1984 case CAM_BUSY: 2000 case SCSI_STATUS_CMD_TERMINATED:
1985 new_status = DID_BUS_BUSY; 2001 case SCSI_STATUS_CHECK_COND:
1986 break; 2002 if ((cmd->result >> 24) != DRIVER_SENSE) {
1987 case CAM_REQ_INVALID: 2003 do_fallback = 1;
1988 case CAM_PATH_INVALID: 2004 } else {
1989 new_status = DID_BAD_TARGET; 2005 struct scsi_sense_data *sense;
1990 break; 2006
1991 case CAM_SEL_TIMEOUT: 2007 sense = (struct scsi_sense_data *)
1992 new_status = DID_NO_CONNECT; 2008 &cmd->sense_buffer;
1993 break; 2009 if (sense->extra_len >= 5 &&
1994 case CAM_SCSI_BUS_RESET: 2010 (sense->add_sense_code == 0x47
1995 case CAM_BDR_SENT: 2011 || sense->add_sense_code == 0x48))
1996 new_status = DID_RESET; 2012 do_fallback = 1;
1997 break; 2013 }
1998 case CAM_UNCOR_PARITY:
1999 new_status = DID_PARITY;
2000 break;
2001 case CAM_CMD_TIMEOUT:
2002 new_status = DID_TIME_OUT;
2003 break;
2004 case CAM_UA_ABORT:
2005 case CAM_REQ_CMP_ERR:
2006 case CAM_AUTOSENSE_FAIL:
2007 case CAM_NO_HBA:
2008 case CAM_DATA_RUN_ERR:
2009 case CAM_UNEXP_BUSFREE:
2010 case CAM_SEQUENCE_FAIL:
2011 case CAM_CCB_LEN_ERR:
2012 case CAM_PROVIDE_FAIL:
2013 case CAM_REQ_TERMIO:
2014 case CAM_UNREC_HBA_ERROR:
2015 case CAM_REQ_TOO_BIG:
2016 new_status = DID_ERROR;
2017 break;
2018 case CAM_REQUEUE_REQ:
2019 new_status = DID_REQUEUE;
2020 break; 2014 break;
2021 default: 2015 default:
2022 /* We should never get here */
2023 new_status = DID_ERROR;
2024 break; 2016 break;
2025 } 2017 }
2026 2018 break;
2027 ahd_cmd_set_transaction_status(cmd, new_status); 2019 case CAM_REQ_ABORTED:
2020 new_status = DID_ABORT;
2021 break;
2022 case CAM_BUSY:
2023 new_status = DID_BUS_BUSY;
2024 break;
2025 case CAM_REQ_INVALID:
2026 case CAM_PATH_INVALID:
2027 new_status = DID_BAD_TARGET;
2028 break;
2029 case CAM_SEL_TIMEOUT:
2030 new_status = DID_NO_CONNECT;
2031 break;
2032 case CAM_SCSI_BUS_RESET:
2033 case CAM_BDR_SENT:
2034 new_status = DID_RESET;
2035 break;
2036 case CAM_UNCOR_PARITY:
2037 new_status = DID_PARITY;
2038 do_fallback = 1;
2039 break;
2040 case CAM_CMD_TIMEOUT:
2041 new_status = DID_TIME_OUT;
2042 do_fallback = 1;
2043 break;
2044 case CAM_REQ_CMP_ERR:
2045 case CAM_UNEXP_BUSFREE:
2046 case CAM_DATA_RUN_ERR:
2047 new_status = DID_ERROR;
2048 do_fallback = 1;
2049 break;
2050 case CAM_UA_ABORT:
2051 case CAM_NO_HBA:
2052 case CAM_SEQUENCE_FAIL:
2053 case CAM_CCB_LEN_ERR:
2054 case CAM_PROVIDE_FAIL:
2055 case CAM_REQ_TERMIO:
2056 case CAM_UNREC_HBA_ERROR:
2057 case CAM_REQ_TOO_BIG:
2058 new_status = DID_ERROR;
2059 break;
2060 case CAM_REQUEUE_REQ:
2061 new_status = DID_REQUEUE;
2062 break;
2063 default:
2064 /* We should never get here */
2065 new_status = DID_ERROR;
2066 break;
2028 } 2067 }
2029 2068
2030 cmd->scsi_done(cmd); 2069 if (do_fallback) {
2031} 2070 printf("%s: device overrun (status %x) on %d:%d:%d\n",
2032 2071 ahd_name(ahd), status, cmd->device->channel,
2033static void 2072 cmd->device->id, cmd->device->lun);
2034ahd_linux_sem_timeout(u_long arg) 2073 }
2035{
2036 struct ahd_softc *ahd;
2037 u_long s;
2038 2074
2039 ahd = (struct ahd_softc *)arg; 2075 ahd_cmd_set_transaction_status(cmd, new_status);
2040 2076
2041 ahd_lock(ahd, &s); 2077 cmd->scsi_done(cmd);
2042 if ((ahd->platform_data->flags & AHD_SCB_UP_EH_SEM) != 0) {
2043 ahd->platform_data->flags &= ~AHD_SCB_UP_EH_SEM;
2044 up(&ahd->platform_data->eh_sem);
2045 }
2046 ahd_unlock(ahd, &s);
2047} 2078}
2048 2079
2049void 2080void
2050ahd_freeze_simq(struct ahd_softc *ahd) 2081ahd_freeze_simq(struct ahd_softc *ahd)
2051{ 2082{
2052 unsigned long s; 2083 scsi_block_requests(ahd->platform_data->host);
2053
2054 ahd_lock(ahd, &s);
2055 ahd->platform_data->qfrozen++;
2056 if (ahd->platform_data->qfrozen == 1) {
2057 scsi_block_requests(ahd->platform_data->host);
2058 ahd_platform_abort_scbs(ahd, CAM_TARGET_WILDCARD, ALL_CHANNELS,
2059 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2060 ROLE_INITIATOR, CAM_REQUEUE_REQ);
2061 }
2062 ahd_unlock(ahd, &s);
2063} 2084}
2064 2085
2065void 2086void
2066ahd_release_simq(struct ahd_softc *ahd) 2087ahd_release_simq(struct ahd_softc *ahd)
2067{ 2088{
2068 u_long s; 2089 scsi_unblock_requests(ahd->platform_data->host);
2069 int unblock_reqs;
2070
2071 unblock_reqs = 0;
2072 ahd_lock(ahd, &s);
2073 if (ahd->platform_data->qfrozen > 0)
2074 ahd->platform_data->qfrozen--;
2075 if (ahd->platform_data->qfrozen == 0) {
2076 unblock_reqs = 1;
2077 }
2078 ahd_unlock(ahd, &s);
2079 /*
2080 * There is still a race here. The mid-layer
2081 * should keep its own freeze count and use
2082 * a bottom half handler to run the queues
2083 * so we can unblock with our own lock held.
2084 */
2085 if (unblock_reqs)
2086 scsi_unblock_requests(ahd->platform_data->host);
2087} 2090}
2088 2091
2089static int 2092static int
2090ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) 2093ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
2091{ 2094{
2092 struct ahd_softc *ahd; 2095 struct ahd_softc *ahd;
2093 struct ahd_linux_device *dev; 2096 struct ahd_linux_device *dev;
@@ -2102,7 +2105,6 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2102 int paused; 2105 int paused;
2103 int wait; 2106 int wait;
2104 int disconnected; 2107 int disconnected;
2105 int found;
2106 ahd_mode_state saved_modes; 2108 ahd_mode_state saved_modes;
2107 unsigned long flags; 2109 unsigned long flags;
2108 2110
@@ -2112,8 +2114,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2112 ahd = *(struct ahd_softc **)cmd->device->host->hostdata; 2114 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
2113 2115
2114 scmd_printk(KERN_INFO, cmd, 2116 scmd_printk(KERN_INFO, cmd,
2115 "Attempting to queue a%s message:", 2117 "Attempting to queue an ABORT message:");
2116 flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
2117 2118
2118 printf("CDB:"); 2119 printf("CDB:");
2119 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) 2120 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
@@ -2149,19 +2150,6 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2149 break; 2150 break;
2150 } 2151 }
2151 2152
2152 if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
2153
2154 /* Any SCB for this device will do for a target reset */
2155 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
2156 if (ahd_match_scb(ahd, pending_scb,
2157 scmd_id(cmd),
2158 scmd_channel(cmd) + 'A',
2159 CAM_LUN_WILDCARD,
2160 SCB_LIST_NULL, ROLE_INITIATOR))
2161 break;
2162 }
2163 }
2164
2165 if (pending_scb == NULL) { 2153 if (pending_scb == NULL) {
2166 scmd_printk(KERN_INFO, cmd, "Command not found\n"); 2154 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2167 goto no_cmd; 2155 goto no_cmd;
@@ -2195,25 +2183,17 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2195 ahd_dump_card_state(ahd); 2183 ahd_dump_card_state(ahd);
2196 2184
2197 disconnected = TRUE; 2185 disconnected = TRUE;
2198 if (flag == SCB_ABORT) { 2186 if (ahd_search_qinfifo(ahd, cmd->device->id,
2199 if (ahd_search_qinfifo(ahd, cmd->device->id, 2187 cmd->device->channel + 'A',
2200 cmd->device->channel + 'A', 2188 cmd->device->lun,
2201 cmd->device->lun, 2189 pending_scb->hscb->tag,
2202 pending_scb->hscb->tag, 2190 ROLE_INITIATOR, CAM_REQ_ABORTED,
2203 ROLE_INITIATOR, CAM_REQ_ABORTED, 2191 SEARCH_COMPLETE) > 0) {
2204 SEARCH_COMPLETE) > 0) { 2192 printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2205 printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", 2193 ahd_name(ahd), cmd->device->channel,
2206 ahd_name(ahd), cmd->device->channel, 2194 cmd->device->id, cmd->device->lun);
2207 cmd->device->id, cmd->device->lun); 2195 retval = SUCCESS;
2208 retval = SUCCESS; 2196 goto done;
2209 goto done;
2210 }
2211 } else if (ahd_search_qinfifo(ahd, cmd->device->id,
2212 cmd->device->channel + 'A',
2213 cmd->device->lun, pending_scb->hscb->tag,
2214 ROLE_INITIATOR, /*status*/0,
2215 SEARCH_COUNT) > 0) {
2216 disconnected = FALSE;
2217 } 2197 }
2218 2198
2219 saved_modes = ahd_save_modes(ahd); 2199 saved_modes = ahd_save_modes(ahd);
@@ -2221,17 +2201,12 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2221 last_phase = ahd_inb(ahd, LASTPHASE); 2201 last_phase = ahd_inb(ahd, LASTPHASE);
2222 saved_scbptr = ahd_get_scbptr(ahd); 2202 saved_scbptr = ahd_get_scbptr(ahd);
2223 active_scbptr = saved_scbptr; 2203 active_scbptr = saved_scbptr;
2224 if (disconnected && ((last_phase != P_BUSFREE) || 2204 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2225 (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0)) {
2226 struct scb *bus_scb; 2205 struct scb *bus_scb;
2227 2206
2228 bus_scb = ahd_lookup_scb(ahd, active_scbptr); 2207 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
2229 if (bus_scb == pending_scb) 2208 if (bus_scb == pending_scb)
2230 disconnected = FALSE; 2209 disconnected = FALSE;
2231 else if (flag != SCB_ABORT
2232 && ahd_inb(ahd, SAVED_SCSIID) == pending_scb->hscb->scsiid
2233 && ahd_inb(ahd, SAVED_LUN) == SCB_GET_LUN(pending_scb))
2234 disconnected = FALSE;
2235 } 2210 }
2236 2211
2237 /* 2212 /*
@@ -2240,41 +2215,26 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2240 * bus or is in the disconnected state. 2215 * bus or is in the disconnected state.
2241 */ 2216 */
2242 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID); 2217 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2243 if (SCB_GET_TAG(pending_scb) == active_scbptr 2218 if (last_phase != P_BUSFREE
2244 || (flag == SCB_DEVICE_RESET 2219 && SCB_GET_TAG(pending_scb) == active_scbptr) {
2245 && SCSIID_TARGET(ahd, saved_scsiid) == scmd_id(cmd))) {
2246 2220
2247 /* 2221 /*
2248 * We're active on the bus, so assert ATN 2222 * We're active on the bus, so assert ATN
2249 * and hope that the target responds. 2223 * and hope that the target responds.
2250 */ 2224 */
2251 pending_scb = ahd_lookup_scb(ahd, active_scbptr); 2225 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
2252 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_DEVICE_RESET; 2226 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2253 ahd_outb(ahd, MSG_OUT, HOST_MSG); 2227 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2254 ahd_outb(ahd, SCSISIGO, last_phase|ATNO); 2228 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
2255 scmd_printk(KERN_INFO, cmd, "BDR message in message buffer\n"); 2229 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2256 wait = TRUE; 2230 wait = TRUE;
2257 } else if (last_phase != P_BUSFREE
2258 && ahd_inb(ahd, SCSIPHASE) == 0) {
2259 /*
2260 * SCB is not identified, there
2261 * is no pending REQ, and the sequencer
2262 * has not seen a busfree. Looks like
2263 * a stuck connection waiting to
2264 * go busfree. Reset the bus.
2265 */
2266 found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
2267 /*Initiate Reset*/TRUE);
2268 printf("%s: Issued Channel %c Bus Reset. "
2269 "%d SCBs aborted\n", ahd_name(ahd),
2270 cmd->device->channel + 'A', found);
2271 } else if (disconnected) { 2231 } else if (disconnected) {
2272 2232
2273 /* 2233 /*
2274 * Actually re-queue this SCB in an attempt 2234 * Actually re-queue this SCB in an attempt
2275 * to select the device before it reconnects. 2235 * to select the device before it reconnects.
2276 */ 2236 */
2277 pending_scb->flags |= SCB_RECOVERY_SCB|flag; 2237 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2278 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb)); 2238 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
2279 pending_scb->hscb->cdb_len = 0; 2239 pending_scb->hscb->cdb_len = 0;
2280 pending_scb->hscb->task_attribute = 0; 2240 pending_scb->hscb->task_attribute = 0;
@@ -2344,30 +2304,29 @@ done:
2344 if (paused) 2304 if (paused)
2345 ahd_unpause(ahd); 2305 ahd_unpause(ahd);
2346 if (wait) { 2306 if (wait) {
2347 struct timer_list timer; 2307 DECLARE_COMPLETION(done);
2348 int ret;
2349 2308
2350 ahd->platform_data->flags |= AHD_SCB_UP_EH_SEM; 2309 ahd->platform_data->eh_done = &done;
2351 ahd_unlock(ahd, &flags); 2310 ahd_unlock(ahd, &flags);
2352 2311
2353 init_timer(&timer);
2354 timer.data = (u_long)ahd;
2355 timer.expires = jiffies + (5 * HZ);
2356 timer.function = ahd_linux_sem_timeout;
2357 add_timer(&timer);
2358 printf("%s: Recovery code sleeping\n", ahd_name(ahd)); 2312 printf("%s: Recovery code sleeping\n", ahd_name(ahd));
2359 down(&ahd->platform_data->eh_sem); 2313 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2360 printf("%s: Recovery code awake\n", ahd_name(ahd)); 2314 ahd_lock(ahd, &flags);
2361 ret = del_timer_sync(&timer); 2315 ahd->platform_data->eh_done = NULL;
2362 if (ret == 0) { 2316 ahd_unlock(ahd, &flags);
2363 printf("%s: Timer Expired (active %d)\n", 2317 printf("%s: Timer Expired (active %d)\n",
2364 ahd_name(ahd), dev->active); 2318 ahd_name(ahd), dev->active);
2365 retval = FAILED; 2319 retval = FAILED;
2366 } 2320 }
2321 printf("Recovery code awake\n");
2367 } else 2322 } else
2368 ahd_unlock(ahd, &flags); 2323 ahd_unlock(ahd, &flags);
2369 2324
2370 return (retval); 2325 if (retval != SUCCESS)
2326 printf("%s: Command abort returning 0x%x\n",
2327 ahd_name(ahd), retval);
2328
2329 return retval;
2371} 2330}
2372 2331
2373static void ahd_linux_set_width(struct scsi_target *starget, int width) 2332static void ahd_linux_set_width(struct scsi_target *starget, int width)