summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c121
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h17
2 files changed, 5 insertions, 133 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index d0c71da58e85..ca796b9d737b 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -433,7 +433,6 @@ static void ahc_linux_release_simq(u_long arg);
static void ahc_linux_dev_timed_unfreeze(u_long arg);
static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
-static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc);
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo);
static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
@@ -454,29 +453,17 @@ static void ahc_linux_setup_tag_info_global(char *p);
static aic_option_callback_t ahc_linux_setup_tag_info;
static int aic7xxx_setup(char *s);
static int ahc_linux_next_unit(void);
-static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc);
/********************************* Inlines ************************************/
static __inline struct ahc_linux_device*
ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
u_int target, u_int lun, int alloc);
-static __inline void ahc_schedule_completeq(struct ahc_softc *ahc);
static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
struct ahc_dma_seg *sg,
dma_addr_t addr, bus_size_t len);
-static __inline void
-ahc_schedule_completeq(struct ahc_softc *ahc)
-{
- if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) {
- ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER;
- ahc->platform_data->completeq_timer.expires = jiffies;
- add_timer(&ahc->platform_data->completeq_timer);
- }
-}
-
static __inline struct ahc_linux_device*
ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
u_int lun, int alloc)
@@ -503,42 +490,6 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
return (dev);
}
-#define AHC_LINUX_MAX_RETURNED_ERRORS 4
-static struct ahc_cmd *
-ahc_linux_run_complete_queue(struct ahc_softc *ahc)
-{
- struct ahc_cmd *acmd;
- int with_errors;
-
- with_errors = 0;
- while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) {
- struct scsi_cmnd *cmd;
-
- if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) {
- /*
- * Linux uses stack recursion to requeue
- * commands that need to be retried. Avoid
- * blowing out the stack by "spoon feeding"
- * commands that completed with error back
- * the operating system in case they are going
- * to be retried. "ick"
- */
- ahc_schedule_completeq(ahc);
- break;
- }
- TAILQ_REMOVE(&ahc->platform_data->completeq,
- acmd, acmd_links.tqe);
- cmd = &acmd_scsi_cmd(acmd);
- cmd->host_scribble = NULL;
- if (ahc_cmd_get_transaction_status(cmd) != DID_OK
- || (cmd->result & 0xFF) != SCSI_STATUS_OK)
- with_errors++;
-
- cmd->scsi_done(cmd);
- }
- return (acmd);
-}
-
static __inline void
ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
{
@@ -856,7 +807,6 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
/*initiate reset*/TRUE);
- ahc_linux_run_complete_queue(ahc);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "
@@ -1331,13 +1281,8 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
if (ahc->platform_data == NULL)
return (ENOMEM);
memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data));
- TAILQ_INIT(&ahc->platform_data->completeq);
ahc->platform_data->irq = AHC_LINUX_NOIRQ;
ahc_lockinit(ahc);
- init_timer(&ahc->platform_data->completeq_timer);
- ahc->platform_data->completeq_timer.data = (u_long)ahc;
- ahc->platform_data->completeq_timer.function =
- (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue;
init_MUTEX_LOCKED(&ahc->platform_data->eh_sem);
ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
@@ -1355,7 +1300,6 @@ ahc_platform_free(struct ahc_softc *ahc)
int i, j;
if (ahc->platform_data != NULL) {
- del_timer_sync(&ahc->platform_data->completeq_timer);
if (ahc->platform_data->host != NULL) {
scsi_remove_host(ahc->platform_data->host);
scsi_host_put(ahc->platform_data->host);
@@ -1504,18 +1448,6 @@ ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
return 0;
}
-static void
-ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc)
-{
- u_long flags;
-
- ahc_lock(ahc, &flags);
- del_timer(&ahc->platform_data->completeq_timer);
- ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER;
- ahc_linux_run_complete_queue(ahc);
- ahc_unlock(ahc, &flags);
-}
-
static u_int
ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
{
@@ -1785,7 +1717,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
ahc = (struct ahc_softc *) dev_id;
ahc_lock(ahc, &flags);
ours = ahc_intr(ahc);
- ahc_linux_run_complete_queue(ahc);
ahc_unlock(ahc, &flags);
return IRQ_RETVAL(ours);
}
@@ -1794,8 +1725,6 @@ void
ahc_platform_flushwork(struct ahc_softc *ahc)
{
- while (ahc_linux_run_complete_queue(ahc) != NULL)
- ;
}
static struct ahc_linux_target*
@@ -2275,22 +2204,6 @@ static void
ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
{
/*
- * Typically, the complete queue has very few entries
- * queued to it before the queue is emptied by
- * ahc_linux_run_complete_queue, so sorting the entries
- * by generation number should be inexpensive.
- * We perform the sort so that commands that complete
- * with an error are retuned in the order origionally
- * queued to the controller so that any subsequent retries
- * are performed in order. The underlying ahc routines do
- * not guarantee the order that aborted commands will be
- * returned to us.
- */
- struct ahc_completeq *completeq;
- struct ahc_cmd *list_cmd;
- struct ahc_cmd *acmd;
-
- /*
* Map CAM error codes into Linux Error codes. We
* avoid the conversion so that the DV code has the
* full error information available when making
@@ -2343,26 +2256,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
new_status = DID_ERROR;
break;
case CAM_REQUEUE_REQ:
- /*
- * If we want the request requeued, make sure there
- * are sufficent retries. In the old scsi error code,
- * we used to be able to specify a result code that
- * bypassed the retry count. Now we must use this
- * hack. We also "fake" a check condition with
- * a sense code of ABORTED COMMAND. This seems to
- * evoke a retry even if this command is being sent
- * via the eh thread. Ick! Ick! Ick!
- */
- if (cmd->retries > 0)
- cmd->retries--;
- new_status = DID_OK;
- ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND);
- cmd->result |= (DRIVER_SENSE << 24);
- memset(cmd->sense_buffer, 0,
- sizeof(cmd->sense_buffer));
- cmd->sense_buffer[0] = SSD_ERRCODE_VALID
- | SSD_CURRENT_ERROR;
- cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND;
+ new_status = DID_REQUEUE;
break;
default:
/* We should never get here */
@@ -2373,17 +2267,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
ahc_cmd_set_transaction_status(cmd, new_status);
}
- completeq = &ahc->platform_data->completeq;
- list_cmd = TAILQ_FIRST(completeq);
- acmd = (struct ahc_cmd *)cmd;
- while (list_cmd != NULL
- && acmd_scsi_cmd(list_cmd).serial_number
- < acmd_scsi_cmd(acmd).serial_number)
- list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe);
- if (list_cmd != NULL)
- TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe);
- else
- TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe);
+ cmd->scsi_done(cmd);
}
static void
@@ -2747,7 +2631,6 @@ done:
}
spin_lock_irq(&ahc->platform_data->spin_lock);
}
- ahc_linux_run_complete_queue(ahc);
return (retval);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 9ce7639dc739..e70c1fa47db2 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -436,16 +436,11 @@ struct ahc_linux_target {
/*
* Per-SCB OSM storage.
*/
-typedef enum {
- AHC_UP_EH_SEMAPHORE = 0x1
-} ahc_linux_scb_flags;
-
struct scb_platform_data {
struct ahc_linux_device *dev;
dma_addr_t buf_busaddr;
uint32_t xfer_len;
uint32_t sense_resid; /* Auto-Sense residual */
- ahc_linux_scb_flags flags;
};
/*
@@ -454,22 +449,14 @@ struct scb_platform_data {
* alignment restrictions of the various platforms supported by
* this driver.
*/
-typedef enum {
- AHC_RUN_CMPLT_Q_TIMER = 0x10
-} ahc_linux_softc_flags;
-
-TAILQ_HEAD(ahc_completeq, ahc_cmd);
-
struct ahc_platform_data {
/*
* Fields accessed from interrupt context.
*/
struct ahc_linux_target *targets[AHC_NUM_TARGETS];
- struct ahc_completeq completeq;
spinlock_t spin_lock;
u_int qfrozen;
- struct timer_list completeq_timer;
struct timer_list reset_timer;
struct semaphore eh_sem;
struct Scsi_Host *host; /* pointer to scsi host */
@@ -477,7 +464,9 @@ struct ahc_platform_data {
uint32_t irq; /* IRQ for this adapter */
uint32_t bios_address;
uint32_t mem_busaddr; /* Mem Base Addr */
- ahc_linux_softc_flags flags;
+
+#define AHC_UP_EH_SEMAPHORE 0x1
+ uint32_t flags;
};
/************************** OS Utility Wrappers *******************************/
OpenPOWER on IntegriCloud