diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 319 |
1 files changed, 145 insertions, 174 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index c0c62583b542..8b2b98666d61 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1,3 +1,4 @@ + /* * Adaptec AIC7xxx device driver for Linux. * @@ -145,16 +146,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; #endif /* - * Control collection of SCSI transfer statistics for the /proc filesystem. - * - * NOTE: Do NOT enable this when running on kernels version 1.2.x and below. - * NOTE: This does affect performance since it has to maintain statistics. - */ -#ifdef CONFIG_AIC7XXX_PROC_STATS -#define AIC7XXX_PROC_STATS -#endif - -/* * To change the default number of tagged transactions allowed per-device, * add a line to the lilo.conf file like: * append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}" @@ -375,7 +366,8 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd); static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_release_simq(struct ahc_softc *ahc); -static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); +static int ahc_linux_queue_recovery_cmd(struct scsi_device *sdev, + struct scsi_cmnd *cmd); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo); @@ -462,7 +454,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count) static void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, - struct ahc_dma_seg *sg, + struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len); static void @@ -527,8 +519,7 @@ ahc_linux_info(struct Scsi_Host *host) /* * Queue an SCB to the controller. */ -static int -ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) +static int ahc_linux_queue_lck(struct scsi_cmnd *cmd) { struct ahc_softc *ahc; struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device); @@ -539,7 +530,6 @@ ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd ahc_lock(ahc, &flags); if (ahc->platform_data->qfrozen == 0) { - cmd->scsi_done = scsi_done; cmd->result = CAM_REQ_INPROG << 16; rtn = ahc_linux_run_command(ahc, dev, cmd); } @@ -574,8 +564,6 @@ ahc_linux_target_alloc(struct scsi_target *starget) struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget); unsigned short scsirate; struct ahc_devinfo devinfo; - struct ahc_initiator_tinfo *tinfo; - struct ahc_tmode_tstate *tstate; char channel = starget->channel + 'A'; unsigned int our_id = ahc->our_id; unsigned int target_offset; @@ -583,7 +571,7 @@ ahc_linux_target_alloc(struct scsi_target *starget) target_offset = starget->id; if (starget->channel != 0) target_offset += 8; - + if (starget->channel) our_id = ahc->our_id_b; @@ -609,22 +597,19 @@ ahc_linux_target_alloc(struct scsi_target *starget) ultra = 0; flags &= ~CFXFER; } - + if ((ahc->features & AHC_ULTRA2) != 0) { scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0); } else { scsirate = (flags & CFXFER) << 4; - maxsync = ultra ? AHC_SYNCRATE_ULTRA : + maxsync = ultra ? AHC_SYNCRATE_ULTRA : AHC_SYNCRATE_FAST; } spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0; if (!(flags & CFSYNCH)) spi_max_offset(starget) = 0; - spi_min_period(starget) = + spi_min_period(starget) = ahc_find_period(ahc, scsirate, maxsync); - - tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id, - starget->id, &tstate); } ahc_compile_devinfo(&devinfo, our_id, starget->id, CAM_LUN_WILDCARD, channel, @@ -647,7 +632,7 @@ ahc_linux_target_destroy(struct scsi_target *starget) } static int -ahc_linux_slave_alloc(struct scsi_device *sdev) +ahc_linux_sdev_init(struct scsi_device *sdev) { struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata); @@ -672,19 +657,15 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) * a tagged queuing capable device. */ dev->maxtags = 0; - + spi_period(starget) = 0; return 0; } static int -ahc_linux_slave_configure(struct scsi_device *sdev) +ahc_linux_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) { - struct ahc_softc *ahc; - - ahc = *((struct ahc_softc **)sdev->host->hostdata); - if (bootverbose) sdev_printk(KERN_INFO, sdev, "Slave Configure\n"); @@ -702,14 +683,12 @@ ahc_linux_slave_configure(struct scsi_device *sdev) * Return the disk geometry for the given SCSI device. */ static int -ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, +ahc_linux_biosparam(struct scsi_device *sdev, struct gendisk *disk, sector_t capacity, int geom[]) { - uint8_t *bh; int heads; int sectors; int cylinders; - int ret; int extended; struct ahc_softc *ahc; u_int channel; @@ -717,14 +696,9 @@ ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, ahc = *((struct ahc_softc **)sdev->host->hostdata); channel = sdev_channel(sdev); - bh = scsi_bios_ptable(bdev); - if (bh) { - ret = scsi_partsize(bh, capacity, - &geom[2], &geom[0], &geom[1]); - kfree(bh); - if (ret != -1) - return (ret); - } + if (scsi_partsize(disk, capacity, geom)) + return 0; + heads = 64; sectors = 32; cylinders = aic_sector_div(capacity, heads, sectors); @@ -755,8 +729,8 @@ ahc_linux_abort(struct scsi_cmnd *cmd) { int error; - error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) + error = ahc_linux_queue_recovery_cmd(cmd->device, cmd); + if (error != SUCCESS) printk("aic7xxx_abort returns 0x%x\n", error); return (error); } @@ -769,8 +743,8 @@ ahc_linux_dev_reset(struct scsi_cmnd *cmd) { int error; - error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) + error = ahc_linux_queue_recovery_cmd(cmd->device, NULL); + if (error != SUCCESS) printk("aic7xxx_dev_reset returns 0x%x\n", error); return (error); } @@ -817,20 +791,26 @@ struct scsi_host_template aic7xxx_driver_template = { .this_id = -1, .max_sectors = 8192, .cmd_per_lun = 2, - .use_clustering = ENABLE_CLUSTERING, - .slave_alloc = ahc_linux_slave_alloc, - .slave_configure = ahc_linux_slave_configure, + .sdev_init = ahc_linux_sdev_init, + .sdev_configure = ahc_linux_sdev_configure, .target_alloc = ahc_linux_target_alloc, .target_destroy = ahc_linux_target_destroy, }; /**************************** Tasklet Handler *********************************/ -/******************************** Macros **************************************/ -#define BUILD_SCSIID(ahc, cmd) \ - ((((cmd)->device->id << TID_SHIFT) & TID) \ - | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ - | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB)) + +static inline unsigned int ahc_build_scsiid(struct ahc_softc *ahc, + struct scsi_device *sdev) +{ + unsigned int scsiid = (sdev->id << TID_SHIFT) & TID; + + if (sdev->channel == 0) + scsiid |= ahc->our_id; + else + scsiid |= ahc->our_id_b | TWIN_CHNLB; + return scsiid; +} /******************************** Bus DMA *************************************/ int @@ -871,8 +851,8 @@ int ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, int flags, bus_dmamap_t *mapp) { - *vaddr = pci_alloc_consistent(ahc->dev_softc, - dmat->maxsize, mapp); + /* XXX: check if we really need the GFP_ATOMIC and unwind this mess! */ + *vaddr = dma_alloc_coherent(ahc->dev, dmat->maxsize, mapp, GFP_ATOMIC); if (*vaddr == NULL) return ENOMEM; return 0; @@ -882,8 +862,7 @@ void ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map) { - pci_free_consistent(ahc->dev_softc, dmat->maxsize, - vaddr, map); + dma_free_coherent(ahc->dev, dmat->maxsize, vaddr, map); } int @@ -1106,7 +1085,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa template->name = ahc->description; host = scsi_host_alloc(template, sizeof(struct ahc_softc *)); if (host == NULL) - return (ENOMEM); + return -ENOMEM; *((struct ahc_softc **)host->hostdata) = ahc; ahc->platform_data->host = host; @@ -1134,8 +1113,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa host->transportt = ahc_linux_transport_template; - retval = scsi_add_host(host, - (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); + retval = scsi_add_host(host, ahc->dev); if (retval) { printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n"); scsi_host_put(host); @@ -1151,7 +1129,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa * or forcing transfer negotiations on the next command to any * target. */ -void +static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc) { int i; @@ -1223,10 +1201,9 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) { ahc->platform_data = - kmalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC); + kzalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC); if (ahc->platform_data == NULL) return (ENOMEM); - memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc_lockinit(ahc); ahc->seltime = (aic7xxx_seltime & 0x3) << 4; @@ -1249,8 +1226,8 @@ ahc_platform_free(struct ahc_softc *ahc) starget = ahc->platform_data->starget[i]; if (starget != NULL) { ahc->platform_data->starget[i] = NULL; - } - } + } + } if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) free_irq(ahc->platform_data->irq, ahc); @@ -1297,7 +1274,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, default: case AHC_QUEUE_NONE: now_queuing = 0; - break; + break; case AHC_QUEUE_BASIC: now_queuing = AHC_DEV_Q_BASIC; break; @@ -1344,12 +1321,9 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, } switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { case AHC_DEV_Q_BASIC: - scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); - scsi_activate_tcq(sdev, dev->openings + dev->active); - break; case AHC_DEV_Q_TAGGED: - scsi_set_tag_type(sdev, MSG_ORDERED_TAG); - scsi_activate_tcq(sdev, dev->openings + dev->active); + scsi_change_queue_depth(sdev, + dev->openings + dev->active); break; default: /* @@ -1358,7 +1332,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, * serially on the controller/device. This should * remove some latency. */ - scsi_deactivate_tcq(sdev, 2); + scsi_change_queue_depth(sdev, 2); break; } } @@ -1457,7 +1431,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, * we are storing a full busy target *lun* * table in SCB space. */ - if (!blk_rq_tagged(cmd->request) + if (!(cmd->flags & SCMD_TAGGED) && (ahc->features & AHC_SCB_BTT) == 0) { int target_offset; @@ -1491,7 +1465,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, * Fill out basics of the HSCB. */ hscb->control = 0; - hscb->scsiid = BUILD_SCSIID(ahc, cmd); + hscb->scsiid = ahc_build_scsiid(ahc, cmd->device); hscb->lun = cmd->device->lun; mask = SCB_GET_TARGET_MASK(ahc, scb); tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), @@ -1501,30 +1475,22 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, hscb->scsioffset = tinfo->curr.offset; if ((tstate->ultraenb & mask) != 0) hscb->control |= ULTRAENB; - + if ((ahc->user_discenable & mask) != 0) hscb->control |= DISCENB; - + if ((tstate->auto_negotiate & mask) != 0) { scb->flags |= SCB_AUTO_NEGOTIATE; scb->hscb->control |= MK_MESSAGE; } if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { - int msg_bytes; - uint8_t tag_msgs[2]; - - msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); - if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { - hscb->control |= tag_msgs[0]; - if (tag_msgs[0] == MSG_ORDERED_TASK) - dev->commands_since_idle_or_otag = 0; - } else if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH + if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { - hscb->control |= MSG_ORDERED_TASK; + hscb->control |= ORDERED_QUEUE_TAG; dev->commands_since_idle_or_otag = 0; } else { - hscb->control |= MSG_SIMPLE_TASK; + hscb->control |= SIMPLE_QUEUE_TAG; } } @@ -1572,7 +1538,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, */ scb->hscb->sgptr = ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); - + /* * Copy the first SG into the "current" * data pointer area. @@ -1592,7 +1558,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, dev->commands_issued++; if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0) dev->commands_since_idle_or_otag++; - + scb->flags |= SCB_ACTIVE; if (untagged_q) { TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); @@ -1613,7 +1579,7 @@ ahc_linux_isr(int irq, void *dev_id) int ours; ahc = (struct ahc_softc *) dev_id; - ahc_lock(ahc, &flags); + ahc_lock(ahc, &flags); ours = ahc_intr(ahc); ahc_unlock(ahc, &flags); return IRQ_RETVAL(ours); @@ -1633,7 +1599,6 @@ ahc_send_async(struct ahc_softc *ahc, char channel, case AC_TRANSFER_NEG: { struct scsi_target *starget; - struct ahc_linux_target *targ; struct ahc_initiator_tinfo *tinfo; struct ahc_tmode_tstate *tstate; int target_offset; @@ -1667,7 +1632,6 @@ ahc_send_async(struct ahc_softc *ahc, char channel, starget = ahc->platform_data->starget[target_offset]; if (starget == NULL) break; - targ = scsi_transport_target_data(starget); target_ppr_options = (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0) @@ -1690,22 +1654,22 @@ ahc_send_async(struct ahc_softc *ahc, char channel, spi_display_xfer_agreement(starget); break; } - case AC_SENT_BDR: + case AC_SENT_BDR: { WARN_ON(lun != CAM_LUN_WILDCARD); scsi_report_device_reset(ahc->platform_data->host, channel - 'A', target); break; } - case AC_BUS_RESET: + case AC_BUS_RESET: if (ahc->platform_data->host != NULL) { scsi_report_bus_reset(ahc->platform_data->host, channel - 'A'); } - break; - default: - panic("ahc_send_async: Unexpected async event"); - } + break; + default: + panic("ahc_send_async: Unexpected async event"); + } } /* @@ -1754,10 +1718,12 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) */ cmd->sense_buffer[0] = 0; if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) { +#ifdef AHC_REPORT_UNDERFLOWS uint32_t amount_xferred; amount_xferred = ahc_get_transfer_length(scb) - ahc_get_residual(scb); +#endif if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) { #ifdef AHC_DEBUG if ((ahc_debug & AHC_SHOW_MISC) != 0) { @@ -1800,7 +1766,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) if (dev->openings == 1 && ahc_get_transaction_status(scb) == CAM_REQ_CMP - && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL) + && ahc_get_scsi_status(scb) != SAM_STAT_TASK_SET_FULL) dev->tag_success_count++; /* * Some devices deal with temporary internal resource @@ -1843,7 +1809,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, sdev->sdev_target->id, sdev->lun, sdev->sdev_target->channel == 0 ? 'A' : 'B', ROLE_INITIATOR); - + /* * We don't currently trust the mid-layer to * properly deal with queue full or busy. So, @@ -1857,8 +1823,8 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, switch (ahc_get_scsi_status(scb)) { default: break; - case SCSI_STATUS_CHECK_COND: - case SCSI_STATUS_CMD_TERMINATED: + case SAM_STAT_CHECK_CONDITION: + case SAM_STAT_COMMAND_TERMINATED: { struct scsi_cmnd *cmd; @@ -1878,7 +1844,6 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, if (sense_size < SCSI_SENSE_BUFFERSIZE) memset(&cmd->sense_buffer[sense_size], 0, SCSI_SENSE_BUFFERSIZE - sense_size); - cmd->result |= (DRIVER_SENSE << 24); #ifdef AHC_DEBUG if (ahc_debug & AHC_SHOW_SENSE) { int i; @@ -1896,7 +1861,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, } break; } - case SCSI_STATUS_QUEUE_FULL: + case SAM_STAT_TASK_SET_FULL: { /* * By the time the core driver has returned this @@ -1940,7 +1905,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, dev->last_queuefull_same_count = 0; } ahc_set_transaction_status(scb, CAM_REQUEUE_REQ); - ahc_set_scsi_status(scb, SCSI_STATUS_OK); + ahc_set_scsi_status(scb, SAM_STAT_GOOD); ahc_platform_set_tags(ahc, sdev, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); @@ -1951,7 +1916,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, * as if the target returned BUSY SCSI status. */ dev->openings = 1; - ahc_set_scsi_status(scb, SCSI_STATUS_BUSY); + ahc_set_scsi_status(scb, SAM_STAT_BUSY); ahc_platform_set_tags(ahc, sdev, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); @@ -2027,7 +1992,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) ahc_cmd_set_transaction_status(cmd, new_status); } - cmd->scsi_done(cmd); + scsi_done(cmd); } static void @@ -2072,11 +2037,12 @@ ahc_linux_release_simq(struct ahc_softc *ahc) } static int -ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) +ahc_linux_queue_recovery_cmd(struct scsi_device *sdev, + struct scsi_cmnd *cmd) { struct ahc_softc *ahc; struct ahc_linux_device *dev; - struct scb *pending_scb; + struct scb *pending_scb = NULL, *scb; u_int saved_scbptr; u_int active_scb_index; u_int last_phase; @@ -2089,18 +2055,19 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) int disconnected; unsigned long flags; - pending_scb = NULL; paused = FALSE; wait = FALSE; - ahc = *(struct ahc_softc **)cmd->device->host->hostdata; + ahc = *(struct ahc_softc **)sdev->host->hostdata; - scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n", - flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); + sdev_printk(KERN_INFO, sdev, "Attempting to queue a%s message\n", + cmd ? "n ABORT" : " TARGET RESET"); - printk("CDB:"); - for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) - printk(" 0x%x", cmd->cmnd[cdb_byte]); - printk("\n"); + if (cmd) { + printk("CDB:"); + for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++) + printk(" 0x%x", cmd->cmnd[cdb_byte]); + printk("\n"); + } ahc_lock(ahc, &flags); @@ -2111,7 +2078,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * at all, and the system wanted us to just abort the * command, return success. */ - dev = scsi_transport_device_data(cmd->device); + dev = scsi_transport_device_data(sdev); if (dev == NULL) { /* @@ -2119,20 +2086,19 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * so we must not still own the command. */ printk("%s:%d:%d:%d: Is not an active device\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + ahc_name(ahc), sdev->channel, sdev->id, (u8)sdev->lun); retval = SUCCESS; goto no_cmd; } - if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 + if (cmd && (dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, cmd->device->channel + 'A', - cmd->device->lun, + (u8)cmd->device->lun, CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) { printk("%s:%d:%d:%d: Command found on untagged queue\n", ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); + (u8)cmd->device->lun); retval = SUCCESS; goto done; } @@ -2140,25 +2106,28 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) /* * See if we can find a matching cmd in the pending list. */ - LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (pending_scb->io_ctx == cmd) - break; - } - - if (pending_scb == NULL && flag == SCB_DEVICE_RESET) { - + if (cmd) { + LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) { + if (scb->io_ctx == cmd) { + pending_scb = scb; + break; + } + } + } else { /* Any SCB for this device will do for a target reset */ - LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd), - scmd_channel(cmd) + 'A', + LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) { + if (ahc_match_scb(ahc, scb, sdev->id, + sdev->channel + 'A', CAM_LUN_WILDCARD, - SCB_LIST_NULL, ROLE_INITIATOR)) + SCB_LIST_NULL, ROLE_INITIATOR)) { + pending_scb = scb; break; + } } } if (pending_scb == NULL) { - scmd_printk(KERN_INFO, cmd, "Command not found\n"); + sdev_printk(KERN_INFO, sdev, "Command not found\n"); goto no_cmd; } @@ -2189,22 +2158,23 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) ahc_dump_card_state(ahc); disconnected = TRUE; - if (flag == SCB_ABORT) { - if (ahc_search_qinfifo(ahc, cmd->device->id, - cmd->device->channel + 'A', - cmd->device->lun, + if (cmd) { + if (ahc_search_qinfifo(ahc, sdev->id, + sdev->channel + 'A', + sdev->lun, pending_scb->hscb->tag, ROLE_INITIATOR, CAM_REQ_ABORTED, SEARCH_COMPLETE) > 0) { printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahc_name(ahc), cmd->device->channel, - cmd->device->id, cmd->device->lun); + ahc_name(ahc), sdev->channel, + sdev->id, (u8)sdev->lun); retval = SUCCESS; goto done; } - } else if (ahc_search_qinfifo(ahc, cmd->device->id, - cmd->device->channel + 'A', - cmd->device->lun, pending_scb->hscb->tag, + } else if (ahc_search_qinfifo(ahc, sdev->id, + sdev->channel + 'A', + sdev->lun, + pending_scb->hscb->tag, ROLE_INITIATOR, /*status*/0, SEARCH_COUNT) > 0) { disconnected = FALSE; @@ -2216,7 +2186,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG)); if (bus_scb == pending_scb) disconnected = FALSE; - else if (flag != SCB_ABORT + else if (!cmd && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb)) disconnected = FALSE; @@ -2236,18 +2206,18 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) saved_scsiid = ahc_inb(ahc, SAVED_SCSIID); if (last_phase != P_BUSFREE && (pending_scb->hscb->tag == active_scb_index - || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) { + || (!cmd && SCSIID_TARGET(ahc, saved_scsiid) == sdev->id))) { /* * We're active on the bus, so assert ATN * and hope that the target responds. */ pending_scb = ahc_lookup_scb(ahc, active_scb_index); - pending_scb->flags |= SCB_RECOVERY_SCB|flag; + pending_scb->flags |= SCB_RECOVERY_SCB; + pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET; ahc_outb(ahc, MSG_OUT, HOST_MSG); ahc_outb(ahc, SCSISIGO, last_phase|ATNO); - scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n"); + sdev_printk(KERN_INFO, sdev, "Device is active, asserting ATN\n"); wait = TRUE; } else if (disconnected) { @@ -2268,7 +2238,8 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * an unsolicited reselection occurred. */ pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; - pending_scb->flags |= SCB_RECOVERY_SCB|flag; + pending_scb->flags |= SCB_RECOVERY_SCB; + pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET; /* * Remove any cached copy of this SCB in the @@ -2277,9 +2248,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * same element in the SCB, SCB_NEXT, for * both the qinfifo and the disconnected list. */ - ahc_search_disc_list(ahc, cmd->device->id, - cmd->device->channel + 'A', - cmd->device->lun, pending_scb->hscb->tag, + ahc_search_disc_list(ahc, sdev->id, + sdev->channel + 'A', + sdev->lun, pending_scb->hscb->tag, /*stop_on_first*/TRUE, /*remove*/TRUE, /*save_state*/FALSE); @@ -2302,9 +2273,9 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * so we are the next SCB for this target * to run. */ - ahc_search_qinfifo(ahc, cmd->device->id, - cmd->device->channel + 'A', - cmd->device->lun, SCB_LIST_NULL, + ahc_search_qinfifo(ahc, sdev->id, + sdev->channel + 'A', + (u8)sdev->lun, SCB_LIST_NULL, ROLE_INITIATOR, CAM_REQUEUE_REQ, SEARCH_COMPLETE); ahc_qinfifo_requeue_tail(ahc, pending_scb); @@ -2313,7 +2284,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) printk("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { - scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n"); + sdev_printk(KERN_INFO, sdev, "Unable to deliver message\n"); retval = FAILED; goto done; } @@ -2350,11 +2321,6 @@ done: return (retval); } -void -ahc_platform_dump_card_state(struct ahc_softc *ahc) -{ -} - static void ahc_linux_set_width(struct scsi_target *starget, int width) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -2374,7 +2340,7 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo + struct ahc_initiator_tinfo *tinfo = ahc_fetch_transinfo(ahc, starget->channel + 'A', shost->this_id, starget->id, &tstate); @@ -2406,7 +2372,8 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) ppr_options &= MSG_EXT_PPR_QAS_REQ; } - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -2418,7 +2385,7 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo + struct ahc_initiator_tinfo *tinfo = ahc_fetch_transinfo(ahc, starget->channel + 'A', shost->this_id, starget->id, &tstate); @@ -2431,7 +2398,8 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); if (offset != 0) { - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); period = tinfo->goal.period; ppr_options = tinfo->goal.ppr_options; } @@ -2446,7 +2414,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo + struct ahc_initiator_tinfo *tinfo = ahc_fetch_transinfo(ahc, starget->channel + 'A', shost->this_id, starget->id, &tstate); @@ -2467,7 +2435,8 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -2484,7 +2453,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo + struct ahc_initiator_tinfo *tinfo = ahc_fetch_transinfo(ahc, starget->channel + 'A', shost->this_id, starget->id, &tstate); @@ -2500,7 +2469,8 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -2512,7 +2482,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo + struct ahc_initiator_tinfo *tinfo = ahc_fetch_transinfo(ahc, starget->channel + 'A', shost->this_id, starget->id, &tstate); @@ -2528,7 +2498,8 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, + AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -2544,7 +2515,7 @@ static void ahc_linux_get_signalling(struct Scsi_Host *shost) if (!(ahc->features & AHC_ULTRA2)) { /* non-LVD chipset, may not have SBLKCTL reg */ - spi_signalling(shost) = + spi_signalling(shost) = ahc->features & AHC_HVD ? SPI_SIGNAL_HVD : SPI_SIGNAL_SE; |
