Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixe…
Browse files Browse the repository at this point in the history
…s-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: (25 commits)
  [SCSI] qlogicpt: section fixes
  [SCSI] mvsas: convert from rough draft to working driver
  [SCSI] mvsas: Add Marvell 6440 SAS/SATA driver
  [SCSI] libsas: correctly flush the LU queue on error recovery
  [SCSI] aic94xx: fix sequencer hang on error recovery
  [SCSI] st: compile fix when DEBUG set to one
  [SCSI] stex: stex_internal_copy should be called with sg_count in struct st_ccb
  [SCSI] stex: stex_direct_copy shouldn't call dma_map_sg
  [SCSI] lpfc: Balance locking
  [SCSI] qla4xxx: fix up residual handling
  [SCSI] libsas: fix error handling
  [SCSI] arcmsr: fix message allocation
  [SCSI] mptbase: fix use-after-free's
  [SCSI] iscsi transport: make 2 functions static
  [SCSI] lpfc: make lpfc_disable_node() static
  [SCSI] ips: fix data buffer accessors conversion bug
  [SCSI] gdth: don't call pci_free_consistent under spinlock
  [SCSI] qla2xxx: fix compile warning for printk format
  [SCSI] aic7xx: mitigate HOST_MSG_LOOP invalid SCB ff panic
  [SCSI] scsi_debug: disable clustering
  ...
  • Loading branch information
Linus Torvalds committed Feb 23, 2008
2 parents 1e83527 + cfb37ae commit b23c9cc
Show file tree
Hide file tree
Showing 26 changed files with 3,184 additions and 183 deletions.
4 changes: 2 additions & 2 deletions drivers/message/fusion/mptbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,15 +1481,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)

ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (pci_enable_device_mem(pdev)) {
kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
"failed\n", ioc->name);
kfree(ioc);
return r;
}
if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
"MEM failed\n", ioc->name);
kfree(ioc);
return r;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/message/fusion/mptbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ extern struct proc_dir_entry *mpt_proc_root_dir;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */

#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) || defined(__powerpc__)
#ifdef CONFIG_64BIT
#define CAST_U32_TO_PTR(x) ((void *)(u64)x)
#define CAST_PTR_TO_U32(x) ((u32)(u64)x)
#else
Expand Down
10 changes: 10 additions & 0 deletions drivers/scsi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,16 @@ config SCSI_IZIP_SLOW_CTR

Generally, saying N is fine.

config SCSI_MVSAS
tristate "Marvell 88SE6440 SAS/SATA support"
depends on PCI && SCSI
select SCSI_SAS_LIBSAS
help
This driver supports Marvell SAS/SATA PCI devices.

To compiler this driver as a module, choose M here: the module
will be called mvsas.

config SCSI_NCR53C406A
tristate "NCR53c406a SCSI support"
depends on ISA && SCSI
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o
obj-$(CONFIG_SCSI_MVSAS) += mvsas.o
obj-$(CONFIG_PS3_ROM) += ps3rom.o

obj-$(CONFIG_ARM) += arm/
Expand Down
11 changes: 6 additions & 5 deletions drivers/scsi/aic7xxx/aic7xxx_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,15 +695,16 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
scb_index = ahc_inb(ahc, SCB_TAG);
scb = ahc_lookup_scb(ahc, scb_index);
if (devinfo.role == ROLE_INITIATOR) {
if (scb == NULL)
panic("HOST_MSG_LOOP with "
"invalid SCB %x\n", scb_index);
if (bus_phase == P_MESGOUT) {
if (scb == NULL)
panic("HOST_MSG_LOOP with "
"invalid SCB %x\n",
scb_index);

if (bus_phase == P_MESGOUT)
ahc_setup_initiator_msgout(ahc,
&devinfo,
scb);
else {
} else {
ahc->msg_type =
MSG_TYPE_INITIATOR_MSGIN;
ahc->msgin_index = 0;
Expand Down
14 changes: 10 additions & 4 deletions drivers/scsi/aic94xx/aic94xx_scb.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,13 +458,19 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
tc_abort = le16_to_cpu(tc_abort);

list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
struct sas_task *task = ascb->uldd_task;
struct sas_task *task = a->uldd_task;

if (a->tc_index != tc_abort)
continue;

if (task && a->tc_index == tc_abort) {
if (task) {
failed_dev = task->dev;
sas_task_abort(task);
break;
} else {
ASD_DPRINTK("R_T_A for non TASK scb 0x%x\n",
a->scb->header.opcode);
}
break;
}

if (!failed_dev) {
Expand All @@ -478,7 +484,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
* that the EH will wake up and do something.
*/
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
struct sas_task *task = ascb->uldd_task;
struct sas_task *task = a->uldd_task;

if (task &&
task->dev == failed_dev &&
Expand Down
4 changes: 0 additions & 4 deletions drivers/scsi/aic94xx/aic94xx_tmf.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ static int asd_clear_nexus_I_T(struct domain_device *dev)
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T;
scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
if (dev->tproto)
scb->clear_nexus.flags |= SUSPEND_TX;
scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev);
CLEAR_NEXUS_POST;
Expand All @@ -169,8 +167,6 @@ static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T_L;
scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ;
if (dev->tproto)
scb->clear_nexus.flags |= SUSPEND_TX;
memcpy(scb->clear_nexus.ssp_task.lun, lun, 8);
scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev);
Expand Down
26 changes: 11 additions & 15 deletions drivers/scsi/arcmsr/arcmsr_hba.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,18 +1387,16 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
switch(controlcode) {

case ARCMSR_MESSAGE_READ_RQBUFFER: {
unsigned long *ver_addr;
unsigned char *ver_addr;
uint8_t *pQbuffer, *ptmpQbuffer;
int32_t allxfer_len = 0;
void *tmp;

tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
ver_addr = (unsigned long *)tmp;
if (!tmp) {
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
ptmpQbuffer = (uint8_t *) ver_addr;
ptmpQbuffer = ver_addr;
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
Expand Down Expand Up @@ -1427,26 +1425,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
}
arcmsr_iop_message_read(acb);
}
memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
pcmdmessagefld->cmdmessage.Length = allxfer_len;
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
kfree(tmp);
kfree(ver_addr);
}
break;

case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
unsigned long *ver_addr;
unsigned char *ver_addr;
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer;
void *tmp;

tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
ver_addr = (unsigned long *)tmp;
if (!tmp) {
ver_addr = kmalloc(1032, GFP_ATOMIC);
if (!ver_addr) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
}
ptmpuserbuffer = (uint8_t *)ver_addr;
ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length;
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
wqbuf_lastindex = acb->wqbuf_lastindex;
Expand Down Expand Up @@ -1492,7 +1488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
retvalue = ARCMSR_MESSAGE_FAIL;
}
}
kfree(tmp);
kfree(ver_addr);
}
break;

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/arm/fas216.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ typedef struct {

/* miscellaneous */
int internal_done; /* flag to indicate request done */
struct scsi_eh_save *ses; /* holds request sense restore info */
struct scsi_eh_save ses; /* holds request sense restore info */
unsigned long magic_end;
} FAS216_Info;

Expand Down
6 changes: 2 additions & 4 deletions drivers/scsi/gdth_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,15 +694,13 @@ static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr)
{
ulong flags;

spin_lock_irqsave(&ha->smp_lock, flags);

if (buf == ha->pscratch) {
spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE;
spin_unlock_irqrestore(&ha->smp_lock, flags);
} else {
pci_free_consistent(ha->pdev, size, buf, paddr);
}

spin_unlock_irqrestore(&ha->smp_lock, flags);
}

#ifdef GDTH_IOCTL_PROC
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/ips.c
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
METHOD_TRACE("ips_make_passthru", 1);

scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
length += sg[i].length;
length += sg->length;

if (length < sizeof (ips_passthru_t)) {
/* wrong size */
Expand Down
68 changes: 43 additions & 25 deletions drivers/scsi/libsas/sas_scsi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,14 @@ static void sas_scsi_task_done(struct sas_task *task)
{
struct task_status_struct *ts = &task->task_status;
struct scsi_cmnd *sc = task->uldd_task;
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host);
unsigned ts_flags = task->task_state_flags;
int hs = 0, stat = 0;

if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
/* Aborted tasks will be completed by the error handler */
SAS_DPRINTK("task done but aborted\n");
return;
}

if (unlikely(!sc)) {
SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
list_del_init(&task->list);
Expand Down Expand Up @@ -120,11 +124,7 @@ static void sas_scsi_task_done(struct sas_task *task)
sc->result = (hs << 16) | stat;
list_del_init(&task->list);
sas_free_task(task);
/* This is very ugly but this is how SCSI Core works. */
if (ts_flags & SAS_TASK_STATE_ABORTED)
scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q);
else
sc->scsi_done(sc);
sc->scsi_done(sc);
}

static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
Expand Down Expand Up @@ -255,13 +255,34 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
return res;
}

static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
{
struct sas_task *task = TO_SAS_TASK(cmd);
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);

/* remove the aborted task flag to allow the task to be
* completed now. At this point, we only get called following
* an actual abort of the task, so we should be guaranteed not
* to be racing with any completions from the LLD (hence we
* don't need the task state lock to clear the flag) */
task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
/* Now call task_done. However, task will be free'd after
* this */
task->task_done(task);
/* now finish the command and move it on to the error
* handler done list, this also takes it off the
* error handler pending list */
scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
}

static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
{
struct scsi_cmnd *cmd, *n;

list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
if (cmd == my_cmd)
list_del_init(&cmd->eh_entry);
if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
cmd->device->lun == my_cmd->device->lun)
sas_eh_finish_cmd(cmd);
}
}

Expand All @@ -274,7 +295,7 @@ static void sas_scsi_clear_queue_I_T(struct list_head *error_q,
struct domain_device *x = cmd_to_domain_dev(cmd);

if (x == dev)
list_del_init(&cmd->eh_entry);
sas_eh_finish_cmd(cmd);
}
}

Expand All @@ -288,7 +309,7 @@ static void sas_scsi_clear_queue_port(struct list_head *error_q,
struct asd_sas_port *x = dev->port;

if (x == port)
list_del_init(&cmd->eh_entry);
sas_eh_finish_cmd(cmd);
}
}

Expand Down Expand Up @@ -528,14 +549,14 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
case TASK_IS_DONE:
SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
task);
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
continue;
case TASK_IS_ABORTED:
SAS_DPRINTK("%s: task 0x%p is aborted\n",
__FUNCTION__, task);
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
continue;
Expand All @@ -547,7 +568,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
"recovered\n",
SAS_ADDR(task->dev),
cmd->device->lun);
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_lu(work_q, cmd);
Expand All @@ -562,7 +583,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("I_T %016llx recovered\n",
SAS_ADDR(task->dev->sas_addr));
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_I_T(work_q, task->dev);
Expand All @@ -577,7 +598,7 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus port:%d "
"succeeded\n", port->id);
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_port(work_q,
Expand All @@ -591,10 +612,10 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus ha "
"succeeded\n");
task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
goto out;
goto clear_q;
}
}
/* If we are here -- this means that no amount
Expand All @@ -606,21 +627,18 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
SAS_ADDR(task->dev->sas_addr),
cmd->device->lun);

task->task_done(task);
sas_eh_finish_cmd(cmd);
if (need_reset)
try_to_reset_cmd_device(shost, cmd);
goto clear_q;
}
}
out:
return list_empty(work_q);
clear_q:
SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
struct sas_task *task = TO_SAS_TASK(cmd);
list_del_init(&cmd->eh_entry);
task->task_done(task);
}
list_for_each_entry_safe(cmd, n, work_q, eh_entry)
sas_eh_finish_cmd(cmd);

return list_empty(work_q);
}

Expand Down
Loading

0 comments on commit b23c9cc

Please sign in to comment.