[SCSI] aic7xxx: fix timer handling bug
The driver is doing a rather stupid mod_timer allegedly to "give request sense more time to complete". This is illegal and pointless, so just eliminate it. Also eliminate all the other uses of struct timer_list in the driver, which are mostly bogus. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
8e0df4a757
commit
dacee84b07
|
@ -42,13 +42,13 @@ config AIC7XXX_CMDS_PER_DEVICE
|
||||||
config AIC7XXX_RESET_DELAY_MS
|
config AIC7XXX_RESET_DELAY_MS
|
||||||
int "Initial bus reset delay in milli-seconds"
|
int "Initial bus reset delay in milli-seconds"
|
||||||
depends on SCSI_AIC7XXX
|
depends on SCSI_AIC7XXX
|
||||||
default "15000"
|
default "5000"
|
||||||
---help---
|
---help---
|
||||||
The number of milliseconds to delay after an initial bus reset.
|
The number of milliseconds to delay after an initial bus reset.
|
||||||
The bus settle delay following all error recovery actions is
|
The bus settle delay following all error recovery actions is
|
||||||
dictated by the SCSI layer and is not affected by this value.
|
dictated by the SCSI layer and is not affected by this value.
|
||||||
|
|
||||||
Default: 15000 (15 seconds)
|
Default: 5000 (5 seconds)
|
||||||
|
|
||||||
config AIC7XXX_PROBE_EISA_VL
|
config AIC7XXX_PROBE_EISA_VL
|
||||||
bool "Probe for EISA and VL AIC7XXX Adapters"
|
bool "Probe for EISA and VL AIC7XXX Adapters"
|
||||||
|
|
|
@ -375,7 +375,7 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
|
||||||
struct scsi_cmnd *cmd);
|
struct scsi_cmnd *cmd);
|
||||||
static void ahc_linux_sem_timeout(u_long arg);
|
static void ahc_linux_sem_timeout(u_long arg);
|
||||||
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
|
static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
|
||||||
static void ahc_linux_release_simq(u_long arg);
|
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_cmnd *cmd, scb_flag flag);
|
||||||
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
|
static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
|
||||||
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
|
static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
|
||||||
|
@ -1073,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
|
|
||||||
*((struct ahc_softc **)host->hostdata) = ahc;
|
*((struct ahc_softc **)host->hostdata) = ahc;
|
||||||
ahc_lock(ahc, &s);
|
|
||||||
ahc->platform_data->host = host;
|
ahc->platform_data->host = host;
|
||||||
host->can_queue = AHC_MAX_QUEUE;
|
host->can_queue = AHC_MAX_QUEUE;
|
||||||
host->cmd_per_lun = 2;
|
host->cmd_per_lun = 2;
|
||||||
|
@ -1084,7 +1083,9 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
|
||||||
host->max_lun = AHC_NUM_LUNS;
|
host->max_lun = AHC_NUM_LUNS;
|
||||||
host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
|
host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
|
||||||
host->sg_tablesize = AHC_NSEG;
|
host->sg_tablesize = AHC_NSEG;
|
||||||
|
ahc_lock(ahc, &s);
|
||||||
ahc_set_unit(ahc, ahc_linux_unit++);
|
ahc_set_unit(ahc, ahc_linux_unit++);
|
||||||
|
ahc_unlock(ahc, &s);
|
||||||
sprintf(buf, "scsi%d", host->host_no);
|
sprintf(buf, "scsi%d", host->host_no);
|
||||||
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
|
new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
|
||||||
if (new_name != NULL) {
|
if (new_name != NULL) {
|
||||||
|
@ -1094,7 +1095,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
|
||||||
host->unique_id = ahc->unit;
|
host->unique_id = ahc->unit;
|
||||||
ahc_linux_initialize_scsi_bus(ahc);
|
ahc_linux_initialize_scsi_bus(ahc);
|
||||||
ahc_intr_enable(ahc, TRUE);
|
ahc_intr_enable(ahc, TRUE);
|
||||||
ahc_unlock(ahc, &s);
|
|
||||||
|
|
||||||
host->transportt = ahc_linux_transport_template;
|
host->transportt = ahc_linux_transport_template;
|
||||||
|
|
||||||
|
@ -1120,10 +1120,13 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int numtarg;
|
int numtarg;
|
||||||
|
unsigned long s;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
numtarg = 0;
|
numtarg = 0;
|
||||||
|
|
||||||
|
ahc_lock(ahc, &s);
|
||||||
|
|
||||||
if (aic7xxx_no_reset != 0)
|
if (aic7xxx_no_reset != 0)
|
||||||
ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
|
ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
|
||||||
|
|
||||||
|
@ -1170,16 +1173,12 @@ ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
|
||||||
ahc_update_neg_request(ahc, &devinfo, tstate,
|
ahc_update_neg_request(ahc, &devinfo, tstate,
|
||||||
tinfo, AHC_NEG_ALWAYS);
|
tinfo, AHC_NEG_ALWAYS);
|
||||||
}
|
}
|
||||||
|
ahc_unlock(ahc, &s);
|
||||||
/* Give the bus some time to recover */
|
/* Give the bus some time to recover */
|
||||||
if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
|
if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
|
||||||
ahc_linux_freeze_simq(ahc);
|
ahc_linux_freeze_simq(ahc);
|
||||||
init_timer(&ahc->platform_data->reset_timer);
|
msleep(AIC7XXX_RESET_DELAY);
|
||||||
ahc->platform_data->reset_timer.data = (u_long)ahc;
|
ahc_linux_release_simq(ahc);
|
||||||
ahc->platform_data->reset_timer.expires =
|
|
||||||
jiffies + (AIC7XXX_RESET_DELAY * HZ)/1000;
|
|
||||||
ahc->platform_data->reset_timer.function =
|
|
||||||
ahc_linux_release_simq;
|
|
||||||
add_timer(&ahc->platform_data->reset_timer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2059,6 +2058,9 @@ ahc_linux_sem_timeout(u_long arg)
|
||||||
static void
|
static void
|
||||||
ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
||||||
{
|
{
|
||||||
|
unsigned long s;
|
||||||
|
|
||||||
|
ahc_lock(ahc, &s);
|
||||||
ahc->platform_data->qfrozen++;
|
ahc->platform_data->qfrozen++;
|
||||||
if (ahc->platform_data->qfrozen == 1) {
|
if (ahc->platform_data->qfrozen == 1) {
|
||||||
scsi_block_requests(ahc->platform_data->host);
|
scsi_block_requests(ahc->platform_data->host);
|
||||||
|
@ -2068,17 +2070,15 @@ ahc_linux_freeze_simq(struct ahc_softc *ahc)
|
||||||
CAM_LUN_WILDCARD, SCB_LIST_NULL,
|
CAM_LUN_WILDCARD, SCB_LIST_NULL,
|
||||||
ROLE_INITIATOR, CAM_REQUEUE_REQ);
|
ROLE_INITIATOR, CAM_REQUEUE_REQ);
|
||||||
}
|
}
|
||||||
|
ahc_unlock(ahc, &s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ahc_linux_release_simq(u_long arg)
|
ahc_linux_release_simq(struct ahc_softc *ahc)
|
||||||
{
|
{
|
||||||
struct ahc_softc *ahc;
|
|
||||||
u_long s;
|
u_long s;
|
||||||
int unblock_reqs;
|
int unblock_reqs;
|
||||||
|
|
||||||
ahc = (struct ahc_softc *)arg;
|
|
||||||
|
|
||||||
unblock_reqs = 0;
|
unblock_reqs = 0;
|
||||||
ahc_lock(ahc, &s);
|
ahc_lock(ahc, &s);
|
||||||
if (ahc->platform_data->qfrozen > 0)
|
if (ahc->platform_data->qfrozen > 0)
|
||||||
|
|
|
@ -223,9 +223,6 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
|
||||||
*/
|
*/
|
||||||
#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
|
#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
|
||||||
|
|
||||||
/************************** Timer DataStructures ******************************/
|
|
||||||
typedef struct timer_list ahc_timer_t;
|
|
||||||
|
|
||||||
/********************************** Includes **********************************/
|
/********************************** Includes **********************************/
|
||||||
#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
|
#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
|
||||||
#define AIC_DEBUG_REGISTERS 1
|
#define AIC_DEBUG_REGISTERS 1
|
||||||
|
@ -235,30 +232,9 @@ typedef struct timer_list ahc_timer_t;
|
||||||
#include "aic7xxx.h"
|
#include "aic7xxx.h"
|
||||||
|
|
||||||
/***************************** Timer Facilities *******************************/
|
/***************************** Timer Facilities *******************************/
|
||||||
#define ahc_timer_init init_timer
|
|
||||||
#define ahc_timer_stop del_timer_sync
|
|
||||||
typedef void ahc_linux_callback_t (u_long);
|
|
||||||
static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
|
|
||||||
ahc_callback_t *func, void *arg);
|
|
||||||
static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
|
|
||||||
|
|
||||||
static __inline void
|
|
||||||
ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
|
|
||||||
{
|
|
||||||
struct ahc_softc *ahc;
|
|
||||||
|
|
||||||
ahc = (struct ahc_softc *)arg;
|
|
||||||
del_timer(timer);
|
|
||||||
timer->data = (u_long)arg;
|
|
||||||
timer->expires = jiffies + (usec * HZ)/1000000;
|
|
||||||
timer->function = (ahc_linux_callback_t*)func;
|
|
||||||
add_timer(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
ahc_scb_timer_reset(struct scb *scb, u_int usec)
|
ahc_scb_timer_reset(struct scb *scb, u_int usec)
|
||||||
{
|
{
|
||||||
mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************** SMP support ************************************/
|
/***************************** SMP support ************************************/
|
||||||
|
@ -393,7 +369,6 @@ struct ahc_platform_data {
|
||||||
|
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
u_int qfrozen;
|
u_int qfrozen;
|
||||||
struct timer_list reset_timer;
|
|
||||||
struct semaphore eh_sem;
|
struct semaphore eh_sem;
|
||||||
struct Scsi_Host *host; /* pointer to scsi host */
|
struct Scsi_Host *host; /* pointer to scsi host */
|
||||||
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
|
||||||
|
|
Loading…
Reference in a new issue