Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-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
  ...
This commit is contained in:
Linus Torvalds 2008-02-23 12:29:16 -08:00
commit b23c9cc0ce
26 changed files with 3182 additions and 181 deletions

View file

@ -1481,15 +1481,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
if (pci_enable_device_mem(pdev)) { if (pci_enable_device_mem(pdev)) {
kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
"failed\n", ioc->name); "failed\n", ioc->name);
kfree(ioc);
return r; return r;
} }
if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
kfree(ioc);
printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
"MEM failed\n", ioc->name); "MEM failed\n", ioc->name);
kfree(ioc);
return r; return r;
} }

View file

@ -923,7 +923,7 @@ extern struct proc_dir_entry *mpt_proc_root_dir;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#endif /* } __KERNEL__ */ #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_U32_TO_PTR(x) ((void *)(u64)x)
#define CAST_PTR_TO_U32(x) ((u32)(u64)x) #define CAST_PTR_TO_U32(x) ((u32)(u64)x)
#else #else

View file

@ -992,6 +992,16 @@ config SCSI_IZIP_SLOW_CTR
Generally, saying N is fine. 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 config SCSI_NCR53C406A
tristate "NCR53c406a SCSI support" tristate "NCR53c406a SCSI support"
depends on ISA && SCSI depends on ISA && SCSI

View file

@ -119,6 +119,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
obj-$(CONFIG_SCSI_STEX) += stex.o obj-$(CONFIG_SCSI_STEX) += stex.o
obj-$(CONFIG_SCSI_MVSAS) += mvsas.o
obj-$(CONFIG_PS3_ROM) += ps3rom.o obj-$(CONFIG_PS3_ROM) += ps3rom.o
obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_ARM) += arm/

View file

@ -695,15 +695,16 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
scb_index = ahc_inb(ahc, SCB_TAG); scb_index = ahc_inb(ahc, SCB_TAG);
scb = ahc_lookup_scb(ahc, scb_index); scb = ahc_lookup_scb(ahc, scb_index);
if (devinfo.role == ROLE_INITIATOR) { if (devinfo.role == ROLE_INITIATOR) {
if (scb == NULL) if (bus_phase == P_MESGOUT) {
panic("HOST_MSG_LOOP with " if (scb == NULL)
"invalid SCB %x\n", scb_index); panic("HOST_MSG_LOOP with "
"invalid SCB %x\n",
scb_index);
if (bus_phase == P_MESGOUT)
ahc_setup_initiator_msgout(ahc, ahc_setup_initiator_msgout(ahc,
&devinfo, &devinfo,
scb); scb);
else { } else {
ahc->msg_type = ahc->msg_type =
MSG_TYPE_INITIATOR_MSGIN; MSG_TYPE_INITIATOR_MSGIN;
ahc->msgin_index = 0; ahc->msgin_index = 0;

View file

@ -458,13 +458,19 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
tc_abort = le16_to_cpu(tc_abort); tc_abort = le16_to_cpu(tc_abort);
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { 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 && a->tc_index == tc_abort) { if (a->tc_index != tc_abort)
continue;
if (task) {
failed_dev = task->dev; failed_dev = task->dev;
sas_task_abort(task); 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) { if (!failed_dev) {
@ -478,7 +484,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
* that the EH will wake up and do something. * that the EH will wake up and do something.
*/ */
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) { 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 && if (task &&
task->dev == failed_dev && task->dev == failed_dev &&

View file

@ -151,8 +151,6 @@ static int asd_clear_nexus_I_T(struct domain_device *dev)
CLEAR_NEXUS_PRE; CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T; scb->clear_nexus.nexus = NEXUS_I_T;
scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; 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) scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev); dev->lldd_dev);
CLEAR_NEXUS_POST; CLEAR_NEXUS_POST;
@ -169,8 +167,6 @@ static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
CLEAR_NEXUS_PRE; CLEAR_NEXUS_PRE;
scb->clear_nexus.nexus = NEXUS_I_T_L; scb->clear_nexus.nexus = NEXUS_I_T_L;
scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; 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); memcpy(scb->clear_nexus.ssp_task.lun, lun, 8);
scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long)
dev->lldd_dev); dev->lldd_dev);

View file

@ -1387,18 +1387,16 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
switch(controlcode) { switch(controlcode) {
case ARCMSR_MESSAGE_READ_RQBUFFER: { case ARCMSR_MESSAGE_READ_RQBUFFER: {
unsigned long *ver_addr; unsigned char *ver_addr;
uint8_t *pQbuffer, *ptmpQbuffer; uint8_t *pQbuffer, *ptmpQbuffer;
int32_t allxfer_len = 0; int32_t allxfer_len = 0;
void *tmp;
tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA); ver_addr = kmalloc(1032, GFP_ATOMIC);
ver_addr = (unsigned long *)tmp; if (!ver_addr) {
if (!tmp) {
retvalue = ARCMSR_MESSAGE_FAIL; retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out; goto message_out;
} }
ptmpQbuffer = (uint8_t *) ver_addr; ptmpQbuffer = ver_addr;
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
&& (allxfer_len < 1031)) { && (allxfer_len < 1031)) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
@ -1427,26 +1425,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
} }
arcmsr_iop_message_read(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.Length = allxfer_len;
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
kfree(tmp); kfree(ver_addr);
} }
break; break;
case ARCMSR_MESSAGE_WRITE_WQBUFFER: { case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
unsigned long *ver_addr; unsigned char *ver_addr;
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
uint8_t *pQbuffer, *ptmpuserbuffer; uint8_t *pQbuffer, *ptmpuserbuffer;
void *tmp;
tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA); ver_addr = kmalloc(1032, GFP_ATOMIC);
ver_addr = (unsigned long *)tmp; if (!ver_addr) {
if (!tmp) {
retvalue = ARCMSR_MESSAGE_FAIL; retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out; goto message_out;
} }
ptmpuserbuffer = (uint8_t *)ver_addr; ptmpuserbuffer = ver_addr;
user_len = pcmdmessagefld->cmdmessage.Length; user_len = pcmdmessagefld->cmdmessage.Length;
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
wqbuf_lastindex = acb->wqbuf_lastindex; wqbuf_lastindex = acb->wqbuf_lastindex;
@ -1492,7 +1488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
retvalue = ARCMSR_MESSAGE_FAIL; retvalue = ARCMSR_MESSAGE_FAIL;
} }
} }
kfree(tmp); kfree(ver_addr);
} }
break; break;

View file

@ -313,7 +313,7 @@ typedef struct {
/* miscellaneous */ /* miscellaneous */
int internal_done; /* flag to indicate request done */ 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; unsigned long magic_end;
} FAS216_Info; } FAS216_Info;

View file

@ -694,15 +694,13 @@ static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr)
{ {
ulong flags; ulong flags;
spin_lock_irqsave(&ha->smp_lock, flags);
if (buf == ha->pscratch) { if (buf == ha->pscratch) {
spin_lock_irqsave(&ha->smp_lock, flags);
ha->scratch_busy = FALSE; ha->scratch_busy = FALSE;
spin_unlock_irqrestore(&ha->smp_lock, flags);
} else { } else {
pci_free_consistent(ha->pdev, size, buf, paddr); pci_free_consistent(ha->pdev, size, buf, paddr);
} }
spin_unlock_irqrestore(&ha->smp_lock, flags);
} }
#ifdef GDTH_IOCTL_PROC #ifdef GDTH_IOCTL_PROC

View file

@ -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); METHOD_TRACE("ips_make_passthru", 1);
scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i) scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
length += sg[i].length; length += sg->length;
if (length < sizeof (ips_passthru_t)) { if (length < sizeof (ips_passthru_t)) {
/* wrong size */ /* wrong size */

View file

@ -51,10 +51,14 @@ static void sas_scsi_task_done(struct sas_task *task)
{ {
struct task_status_struct *ts = &task->task_status; struct task_status_struct *ts = &task->task_status;
struct scsi_cmnd *sc = task->uldd_task; 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; 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)) { if (unlikely(!sc)) {
SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n"); SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
list_del_init(&task->list); list_del_init(&task->list);
@ -120,11 +124,7 @@ static void sas_scsi_task_done(struct sas_task *task)
sc->result = (hs << 16) | stat; sc->result = (hs << 16) | stat;
list_del_init(&task->list); list_del_init(&task->list);
sas_free_task(task); sas_free_task(task);
/* This is very ugly but this is how SCSI Core works. */ sc->scsi_done(sc);
if (ts_flags & SAS_TASK_STATE_ABORTED)
scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q);
else
sc->scsi_done(sc);
} }
static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd) static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
@ -255,13 +255,34 @@ out:
return res; 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) static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
{ {
struct scsi_cmnd *cmd, *n; struct scsi_cmnd *cmd, *n;
list_for_each_entry_safe(cmd, n, error_q, eh_entry) { list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
if (cmd == my_cmd) if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
list_del_init(&cmd->eh_entry); cmd->device->lun == my_cmd->device->lun)
sas_eh_finish_cmd(cmd);
} }
} }
@ -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); struct domain_device *x = cmd_to_domain_dev(cmd);
if (x == dev) if (x == dev)
list_del_init(&cmd->eh_entry); sas_eh_finish_cmd(cmd);
} }
} }
@ -288,7 +309,7 @@ static void sas_scsi_clear_queue_port(struct list_head *error_q,
struct asd_sas_port *x = dev->port; struct asd_sas_port *x = dev->port;
if (x == port) if (x == port)
list_del_init(&cmd->eh_entry); sas_eh_finish_cmd(cmd);
} }
} }
@ -528,14 +549,14 @@ Again:
case TASK_IS_DONE: case TASK_IS_DONE:
SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
task); task);
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
continue; continue;
case TASK_IS_ABORTED: case TASK_IS_ABORTED:
SAS_DPRINTK("%s: task 0x%p is aborted\n", SAS_DPRINTK("%s: task 0x%p is aborted\n",
__FUNCTION__, task); __FUNCTION__, task);
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
continue; continue;
@ -547,7 +568,7 @@ Again:
"recovered\n", "recovered\n",
SAS_ADDR(task->dev), SAS_ADDR(task->dev),
cmd->device->lun); cmd->device->lun);
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_lu(work_q, cmd); sas_scsi_clear_queue_lu(work_q, cmd);
@ -562,7 +583,7 @@ Again:
if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("I_T %016llx recovered\n", SAS_DPRINTK("I_T %016llx recovered\n",
SAS_ADDR(task->dev->sas_addr)); SAS_ADDR(task->dev->sas_addr));
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_I_T(work_q, task->dev); sas_scsi_clear_queue_I_T(work_q, task->dev);
@ -577,7 +598,7 @@ Again:
if (res == TMF_RESP_FUNC_COMPLETE) { if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus port:%d " SAS_DPRINTK("clear nexus port:%d "
"succeeded\n", port->id); "succeeded\n", port->id);
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
sas_scsi_clear_queue_port(work_q, sas_scsi_clear_queue_port(work_q,
@ -591,10 +612,10 @@ Again:
if (res == TMF_RESP_FUNC_COMPLETE) { if (res == TMF_RESP_FUNC_COMPLETE) {
SAS_DPRINTK("clear nexus ha " SAS_DPRINTK("clear nexus ha "
"succeeded\n"); "succeeded\n");
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
goto out; goto clear_q;
} }
} }
/* If we are here -- this means that no amount /* If we are here -- this means that no amount
@ -606,21 +627,18 @@ Again:
SAS_ADDR(task->dev->sas_addr), SAS_ADDR(task->dev->sas_addr),
cmd->device->lun); cmd->device->lun);
task->task_done(task); sas_eh_finish_cmd(cmd);
if (need_reset) if (need_reset)
try_to_reset_cmd_device(shost, cmd); try_to_reset_cmd_device(shost, cmd);
goto clear_q; goto clear_q;
} }
} }
out:
return list_empty(work_q); return list_empty(work_q);
clear_q: clear_q:
SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
list_for_each_entry_safe(cmd, n, work_q, eh_entry) { list_for_each_entry_safe(cmd, n, work_q, eh_entry)
struct sas_task *task = TO_SAS_TASK(cmd); sas_eh_finish_cmd(cmd);
list_del_init(&cmd->eh_entry);
task->task_done(task);
}
return list_empty(work_q); return list_empty(work_q);
} }

View file

@ -55,7 +55,6 @@ void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *);
void lpfc_disable_node(struct lpfc_vport *, struct lpfc_nodelist *);
struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *, struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *,
struct lpfc_nodelist *, int); struct lpfc_nodelist *, int);
void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int);

View file

@ -1694,7 +1694,7 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
NLP_STE_UNUSED_NODE); NLP_STE_UNUSED_NODE);
} }
void static void
lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{ {
if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)

View file

@ -648,28 +648,24 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
unsigned long flags; unsigned long flags;
struct hbq_dmabuf *hbq_buffer; struct hbq_dmabuf *hbq_buffer;
if (!phba->hbqs[hbqno].hbq_alloc_buffer) { if (!phba->hbqs[hbqno].hbq_alloc_buffer)
return 0; return 0;
}
start = phba->hbqs[hbqno].buffer_count; start = phba->hbqs[hbqno].buffer_count;
end = count + start; end = count + start;
if (end > lpfc_hbq_defs[hbqno]->entry_count) { if (end > lpfc_hbq_defs[hbqno]->entry_count)
end = lpfc_hbq_defs[hbqno]->entry_count; end = lpfc_hbq_defs[hbqno]->entry_count;
}
/* Check whether HBQ is still in use */ /* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags); spin_lock_irqsave(&phba->hbalock, flags);
if (!phba->hbq_in_use) { if (!phba->hbq_in_use)
spin_unlock_irqrestore(&phba->hbalock, flags); goto out;
return 0;
}
/* Populate HBQ entries */ /* Populate HBQ entries */
for (i = start; i < end; i++) { for (i = start; i < end; i++) {
hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (!hbq_buffer) if (!hbq_buffer)
return 1; goto err;
hbq_buffer->tag = (i | (hbqno << 16)); hbq_buffer->tag = (i | (hbqno << 16));
if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
phba->hbqs[hbqno].buffer_count++; phba->hbqs[hbqno].buffer_count++;
@ -677,8 +673,12 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
(phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
} }
out:
spin_unlock_irqrestore(&phba->hbalock, flags); spin_unlock_irqrestore(&phba->hbalock, flags);
return 0; return 0;
err:
spin_unlock_irqrestore(&phba->hbalock, flags);
return 1;
} }
int int

View file

@ -151,19 +151,19 @@ mega_setup_mailbox(adapter_t *adapter)
*/ */
if( adapter->flag & BOARD_IOMAP ) { if( adapter->flag & BOARD_IOMAP ) {
outb_p(adapter->mbox_dma & 0xFF, outb(adapter->mbox_dma & 0xFF,
adapter->host->io_port + MBOX_PORT0); adapter->host->io_port + MBOX_PORT0);
outb_p((adapter->mbox_dma >> 8) & 0xFF, outb((adapter->mbox_dma >> 8) & 0xFF,
adapter->host->io_port + MBOX_PORT1); adapter->host->io_port + MBOX_PORT1);
outb_p((adapter->mbox_dma >> 16) & 0xFF, outb((adapter->mbox_dma >> 16) & 0xFF,
adapter->host->io_port + MBOX_PORT2); adapter->host->io_port + MBOX_PORT2);
outb_p((adapter->mbox_dma >> 24) & 0xFF, outb((adapter->mbox_dma >> 24) & 0xFF,
adapter->host->io_port + MBOX_PORT3); adapter->host->io_port + MBOX_PORT3);
outb_p(ENABLE_MBOX_BYTE, outb(ENABLE_MBOX_BYTE,
adapter->host->io_port + ENABLE_MBOX_REGION); adapter->host->io_port + ENABLE_MBOX_REGION);
irq_ack(adapter); irq_ack(adapter);

2981
drivers/scsi/mvsas.c Executable file

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,7 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
mutex_lock(&ha->fce_mutex); mutex_lock(&ha->fce_mutex);
seq_printf(s, "FCE Trace Buffer\n"); seq_printf(s, "FCE Trace Buffer\n");
seq_printf(s, "In Pointer = %llx\n\n", ha->fce_wr); seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
seq_printf(s, "FCE Enable Registers\n"); seq_printf(s, "FCE Enable Registers\n");
seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",

View file

@ -100,8 +100,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) {
scsi_set_resid(cmd, residual); scsi_set_resid(cmd, residual);
if (!scsi_status && ((scsi_bufflen(cmd) - residual) < if ((scsi_bufflen(cmd) - residual) < cmd->underflow) {
cmd->underflow)) {
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;

View file

@ -651,7 +651,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
static irqreturn_t qpti_intr(int irq, void *dev_id); static irqreturn_t qpti_intr(int irq, void *dev_id);
static void __init qpti_chain_add(struct qlogicpti *qpti) static void __devinit qpti_chain_add(struct qlogicpti *qpti)
{ {
spin_lock_irq(&qptichain_lock); spin_lock_irq(&qptichain_lock);
if (qptichain != NULL) { if (qptichain != NULL) {
@ -667,7 +667,7 @@ static void __init qpti_chain_add(struct qlogicpti *qpti)
spin_unlock_irq(&qptichain_lock); spin_unlock_irq(&qptichain_lock);
} }
static void __init qpti_chain_del(struct qlogicpti *qpti) static void __devexit qpti_chain_del(struct qlogicpti *qpti)
{ {
spin_lock_irq(&qptichain_lock); spin_lock_irq(&qptichain_lock);
if (qptichain == qpti) { if (qptichain == qpti) {
@ -682,7 +682,7 @@ static void __init qpti_chain_del(struct qlogicpti *qpti)
spin_unlock_irq(&qptichain_lock); spin_unlock_irq(&qptichain_lock);
} }
static int __init qpti_map_regs(struct qlogicpti *qpti) static int __devinit qpti_map_regs(struct qlogicpti *qpti)
{ {
struct sbus_dev *sdev = qpti->sdev; struct sbus_dev *sdev = qpti->sdev;
@ -705,7 +705,7 @@ static int __init qpti_map_regs(struct qlogicpti *qpti)
return 0; return 0;
} }
static int __init qpti_register_irq(struct qlogicpti *qpti) static int __devinit qpti_register_irq(struct qlogicpti *qpti)
{ {
struct sbus_dev *sdev = qpti->sdev; struct sbus_dev *sdev = qpti->sdev;
@ -730,7 +730,7 @@ fail:
return -1; return -1;
} }
static void __init qpti_get_scsi_id(struct qlogicpti *qpti) static void __devinit qpti_get_scsi_id(struct qlogicpti *qpti)
{ {
qpti->scsi_id = prom_getintdefault(qpti->prom_node, qpti->scsi_id = prom_getintdefault(qpti->prom_node,
"initiator-id", "initiator-id",
@ -783,7 +783,7 @@ static void qpti_get_clock(struct qlogicpti *qpti)
/* The request and response queues must each be aligned /* The request and response queues must each be aligned
* on a page boundary. * on a page boundary.
*/ */
static int __init qpti_map_queues(struct qlogicpti *qpti) static int __devinit qpti_map_queues(struct qlogicpti *qpti)
{ {
struct sbus_dev *sdev = qpti->sdev; struct sbus_dev *sdev = qpti->sdev;

View file

@ -222,7 +222,7 @@ static struct scsi_host_template sdebug_driver_template = {
.cmd_per_lun = 16, .cmd_per_lun = 16,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.unchecked_isa_dma = 0, .unchecked_isa_dma = 0,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.module = THIS_MODULE, .module = THIS_MODULE,
}; };

View file

@ -231,7 +231,7 @@ static struct {
{ ISCSI_SESSION_FREE, "FREE" }, { ISCSI_SESSION_FREE, "FREE" },
}; };
const char *iscsi_session_state_name(int state) static const char *iscsi_session_state_name(int state)
{ {
int i; int i;
char *name = NULL; char *name = NULL;
@ -373,7 +373,7 @@ static void session_recovery_timedout(struct work_struct *work)
scsi_target_unblock(&session->dev); scsi_target_unblock(&session->dev);
} }
void __iscsi_unblock_session(struct iscsi_cls_session *session) static void __iscsi_unblock_session(struct iscsi_cls_session *session)
{ {
if (!cancel_delayed_work(&session->recovery_work)) if (!cancel_delayed_work(&session->recovery_work))
flush_workqueue(iscsi_eh_timer_workq); flush_workqueue(iscsi_eh_timer_workq);

View file

@ -33,9 +33,9 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
struct ses_device { struct ses_device {
char *page1; unsigned char *page1;
char *page2; unsigned char *page2;
char *page10; unsigned char *page10;
short page1_len; short page1_len;
short page2_len; short page2_len;
short page10_len; short page10_len;
@ -67,7 +67,7 @@ static int ses_probe(struct device *dev)
static int ses_recv_diag(struct scsi_device *sdev, int page_code, static int ses_recv_diag(struct scsi_device *sdev, int page_code,
void *buf, int bufflen) void *buf, int bufflen)
{ {
char cmd[] = { unsigned char cmd[] = {
RECEIVE_DIAGNOSTIC, RECEIVE_DIAGNOSTIC,
1, /* Set PCV bit */ 1, /* Set PCV bit */
page_code, page_code,
@ -85,7 +85,7 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
{ {
u32 result; u32 result;
char cmd[] = { unsigned char cmd[] = {
SEND_DIAGNOSTIC, SEND_DIAGNOSTIC,
0x10, /* Set PF bit */ 0x10, /* Set PF bit */
0, 0,
@ -104,13 +104,13 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code,
static int ses_set_page2_descriptor(struct enclosure_device *edev, static int ses_set_page2_descriptor(struct enclosure_device *edev,
struct enclosure_component *ecomp, struct enclosure_component *ecomp,
char *desc) unsigned char *desc)
{ {
int i, j, count = 0, descriptor = ecomp->number; int i, j, count = 0, descriptor = ecomp->number;
struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); struct scsi_device *sdev = to_scsi_device(edev->cdev.dev);
struct ses_device *ses_dev = edev->scratch; struct ses_device *ses_dev = edev->scratch;
char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
char *desc_ptr = ses_dev->page2 + 8; unsigned char *desc_ptr = ses_dev->page2 + 8;
/* Clear everything */ /* Clear everything */
memset(desc_ptr, 0, ses_dev->page2_len - 8); memset(desc_ptr, 0, ses_dev->page2_len - 8);
@ -133,14 +133,14 @@ static int ses_set_page2_descriptor(struct enclosure_device *edev,
return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
} }
static char *ses_get_page2_descriptor(struct enclosure_device *edev, static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
struct enclosure_component *ecomp) struct enclosure_component *ecomp)
{ {
int i, j, count = 0, descriptor = ecomp->number; int i, j, count = 0, descriptor = ecomp->number;
struct scsi_device *sdev = to_scsi_device(edev->cdev.dev); struct scsi_device *sdev = to_scsi_device(edev->cdev.dev);
struct ses_device *ses_dev = edev->scratch; struct ses_device *ses_dev = edev->scratch;
char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; unsigned char *type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
char *desc_ptr = ses_dev->page2 + 8; unsigned char *desc_ptr = ses_dev->page2 + 8;
ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len); ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
@ -160,17 +160,18 @@ static char *ses_get_page2_descriptor(struct enclosure_device *edev,
static void ses_get_fault(struct enclosure_device *edev, static void ses_get_fault(struct enclosure_device *edev,
struct enclosure_component *ecomp) struct enclosure_component *ecomp)
{ {
char *desc; unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp); desc = ses_get_page2_descriptor(edev, ecomp);
ecomp->fault = (desc[3] & 0x60) >> 4; if (desc)
ecomp->fault = (desc[3] & 0x60) >> 4;
} }
static int ses_set_fault(struct enclosure_device *edev, static int ses_set_fault(struct enclosure_device *edev,
struct enclosure_component *ecomp, struct enclosure_component *ecomp,
enum enclosure_component_setting val) enum enclosure_component_setting val)
{ {
char desc[4] = {0 }; unsigned char desc[4] = {0 };
switch (val) { switch (val) {
case ENCLOSURE_SETTING_DISABLED: case ENCLOSURE_SETTING_DISABLED:
@ -190,26 +191,28 @@ static int ses_set_fault(struct enclosure_device *edev,
static void ses_get_status(struct enclosure_device *edev, static void ses_get_status(struct enclosure_device *edev,
struct enclosure_component *ecomp) struct enclosure_component *ecomp)
{ {
char *desc; unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp); desc = ses_get_page2_descriptor(edev, ecomp);
ecomp->status = (desc[0] & 0x0f); if (desc)
ecomp->status = (desc[0] & 0x0f);
} }
static void ses_get_locate(struct enclosure_device *edev, static void ses_get_locate(struct enclosure_device *edev,
struct enclosure_component *ecomp) struct enclosure_component *ecomp)
{ {
char *desc; unsigned char *desc;
desc = ses_get_page2_descriptor(edev, ecomp); desc = ses_get_page2_descriptor(edev, ecomp);
ecomp->locate = (desc[2] & 0x02) ? 1 : 0; if (desc)
ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
} }
static int ses_set_locate(struct enclosure_device *edev, static int ses_set_locate(struct enclosure_device *edev,
struct enclosure_component *ecomp, struct enclosure_component *ecomp,
enum enclosure_component_setting val) enum enclosure_component_setting val)
{ {
char desc[4] = {0 }; unsigned char desc[4] = {0 };
switch (val) { switch (val) {
case ENCLOSURE_SETTING_DISABLED: case ENCLOSURE_SETTING_DISABLED:
@ -229,7 +232,7 @@ static int ses_set_active(struct enclosure_device *edev,
struct enclosure_component *ecomp, struct enclosure_component *ecomp,
enum enclosure_component_setting val) enum enclosure_component_setting val)
{ {
char desc[4] = {0 }; unsigned char desc[4] = {0 };
switch (val) { switch (val) {
case ENCLOSURE_SETTING_DISABLED: case ENCLOSURE_SETTING_DISABLED:
@ -409,11 +412,11 @@ static int ses_intf_add(struct class_device *cdev,
{ {
struct scsi_device *sdev = to_scsi_device(cdev->dev); struct scsi_device *sdev = to_scsi_device(cdev->dev);
struct scsi_device *tmp_sdev; struct scsi_device *tmp_sdev;
unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr, unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr = NULL,
*addl_desc_ptr; *addl_desc_ptr = NULL;
struct ses_device *ses_dev; struct ses_device *ses_dev;
u32 result; u32 result;
int i, j, types, len, components = 0; int i, j, types, len, page7_len = 0, components = 0;
int err = -ENOMEM; int err = -ENOMEM;
struct enclosure_device *edev; struct enclosure_device *edev;
struct ses_component *scomp = NULL; struct ses_component *scomp = NULL;
@ -447,7 +450,7 @@ static int ses_intf_add(struct class_device *cdev,
* traversal routines more complex */ * traversal routines more complex */
sdev_printk(KERN_ERR, sdev, sdev_printk(KERN_ERR, sdev,
"FIXME driver has no support for subenclosures (%d)\n", "FIXME driver has no support for subenclosures (%d)\n",
buf[1]); hdr_buf[1]);
goto err_free; goto err_free;
} }
@ -461,9 +464,8 @@ static int ses_intf_add(struct class_device *cdev,
goto recv_failed; goto recv_failed;
types = buf[10]; types = buf[10];
len = buf[11];
type_ptr = buf + 12 + len; type_ptr = buf + 12 + buf[11];
for (i = 0; i < types; i++, type_ptr += 4) { for (i = 0; i < types; i++, type_ptr += 4) {
if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
@ -494,22 +496,21 @@ static int ses_intf_add(struct class_device *cdev,
/* The additional information page --- allows us /* The additional information page --- allows us
* to match up the devices */ * to match up the devices */
result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE); result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
if (result) if (!result) {
goto no_page10;
len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
buf = kzalloc(len, GFP_KERNEL); buf = kzalloc(len, GFP_KERNEL);
if (!buf) if (!buf)
goto err_free; goto err_free;
result = ses_recv_diag(sdev, 10, buf, len); result = ses_recv_diag(sdev, 10, buf, len);
if (result) if (result)
goto recv_failed; goto recv_failed;
ses_dev->page10 = buf; ses_dev->page10 = buf;
ses_dev->page10_len = len; ses_dev->page10_len = len;
buf = NULL; buf = NULL;
}
no_page10:
scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
if (!scomp) if (!scomp)
goto err_free; goto err_free;
@ -530,7 +531,7 @@ static int ses_intf_add(struct class_device *cdev,
if (result) if (result)
goto simple_populate; goto simple_populate;
len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
/* add 1 for trailing '\0' we'll use */ /* add 1 for trailing '\0' we'll use */
buf = kzalloc(len + 1, GFP_KERNEL); buf = kzalloc(len + 1, GFP_KERNEL);
if (!buf) if (!buf)
@ -547,7 +548,8 @@ static int ses_intf_add(struct class_device *cdev,
len = (desc_ptr[2] << 8) + desc_ptr[3]; len = (desc_ptr[2] << 8) + desc_ptr[3];
/* skip past overall descriptor */ /* skip past overall descriptor */
desc_ptr += len + 4; desc_ptr += len + 4;
addl_desc_ptr = ses_dev->page10 + 8; if (ses_dev->page10)
addl_desc_ptr = ses_dev->page10 + 8;
} }
type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
components = 0; components = 0;
@ -557,29 +559,35 @@ static int ses_intf_add(struct class_device *cdev,
struct enclosure_component *ecomp; struct enclosure_component *ecomp;
if (desc_ptr) { if (desc_ptr) {
len = (desc_ptr[2] << 8) + desc_ptr[3]; if (desc_ptr >= buf + page7_len) {
desc_ptr += 4; desc_ptr = NULL;
/* Add trailing zero - pushes into } else {
* reserved space */ len = (desc_ptr[2] << 8) + desc_ptr[3];
desc_ptr[len] = '\0'; desc_ptr += 4;
name = desc_ptr; /* Add trailing zero - pushes into
* reserved space */
desc_ptr[len] = '\0';
name = desc_ptr;
}
} }
if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE && if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE) type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
continue;
ecomp = enclosure_component_register(edev, ecomp = enclosure_component_register(edev,
components++, components++,
type_ptr[0], type_ptr[0],
name); name);
if (desc_ptr) {
desc_ptr += len; if (!IS_ERR(ecomp) && addl_desc_ptr)
if (!IS_ERR(ecomp))
ses_process_descriptor(ecomp, ses_process_descriptor(ecomp,
addl_desc_ptr); addl_desc_ptr);
if (addl_desc_ptr)
addl_desc_ptr += addl_desc_ptr[1] + 2;
} }
if (desc_ptr)
desc_ptr += len;
if (addl_desc_ptr)
addl_desc_ptr += addl_desc_ptr[1] + 2;
} }
} }
kfree(buf); kfree(buf);

View file

@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/ */
static const char *verstr = "20080117"; static const char *verstr = "20080221";
#include <linux/module.h> #include <linux/module.h>
@ -1172,7 +1172,7 @@ static int st_open(struct inode *inode, struct file *filp)
STp->try_dio_now = STp->try_dio; STp->try_dio_now = STp->try_dio;
STp->recover_count = 0; STp->recover_count = 0;
DEB( STp->nbr_waits = STp->nbr_finished = 0; DEB( STp->nbr_waits = STp->nbr_finished = 0;
STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; ) STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = 0; )
retval = check_tape(STp, filp); retval = check_tape(STp, filp);
if (retval < 0) if (retval < 0)
@ -1226,8 +1226,8 @@ static int st_flush(struct file *filp, fl_owner_t id)
} }
DEBC( if (STp->nbr_requests) DEBC( if (STp->nbr_requests)
printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d.\n",
name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages));
if (STps->rw == ST_WRITING && !STp->pos_unknown) { if (STps->rw == ST_WRITING && !STp->pos_unknown) {
struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
@ -1422,9 +1422,6 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
if (STbp->do_dio) { if (STbp->do_dio) {
STp->nbr_dio++; STp->nbr_dio++;
STp->nbr_pages += STbp->do_dio; STp->nbr_pages += STbp->do_dio;
for (i=1; i < STbp->do_dio; i++)
if (page_to_pfn(STbp->sg[i].page) == page_to_pfn(STbp->sg[i-1].page) + 1)
STp->nbr_combinable++;
} }
) )
} else } else

View file

@ -164,7 +164,6 @@ struct scsi_tape {
int nbr_requests; int nbr_requests;
int nbr_dio; int nbr_dio;
int nbr_pages; int nbr_pages;
int nbr_combinable;
unsigned char last_cmnd[6]; unsigned char last_cmnd[6];
unsigned char last_sense[16]; unsigned char last_sense[16];
#endif #endif

View file

@ -461,30 +461,14 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
} }
} }
static int stex_direct_copy(struct scsi_cmnd *cmd,
const void *src, size_t count)
{
size_t cp_len = count;
int n_elem = 0;
n_elem = scsi_dma_map(cmd);
if (n_elem < 0)
return 0;
stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
scsi_dma_unmap(cmd);
return cp_len == count;
}
static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
{ {
struct st_frame *p; struct st_frame *p;
size_t count = sizeof(struct st_frame); size_t count = sizeof(struct st_frame);
p = hba->copy_buffer; p = hba->copy_buffer;
stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
ST_FROM_CMD);
memset(p->base, 0, sizeof(u32)*6); memset(p->base, 0, sizeof(u32)*6);
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
p->rom_addr = 0; p->rom_addr = 0;
@ -502,7 +486,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
p->subid = p->subid =
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD); stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
ST_TO_CMD);
} }
static void static void
@ -569,8 +554,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
unsigned char page; unsigned char page;
page = cmd->cmnd[2] & 0x3f; page = cmd->cmnd[2] & 0x3f;
if (page == 0x8 || page == 0x3f) { if (page == 0x8 || page == 0x3f) {
stex_direct_copy(cmd, ms10_caching_page, size_t cp_len = sizeof(ms10_caching_page);
sizeof(ms10_caching_page)); stex_internal_copy(cmd, ms10_caching_page,
&cp_len, scsi_sg_count(cmd),
ST_TO_CMD);
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
done(cmd); done(cmd);
} else } else
@ -599,8 +586,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
if (id != host->max_id - 1) if (id != host->max_id - 1)
break; break;
if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
stex_direct_copy(cmd, console_inq_page, size_t cp_len = sizeof(console_inq_page);
sizeof(console_inq_page)); stex_internal_copy(cmd, console_inq_page,
&cp_len, scsi_sg_count(cmd),
ST_TO_CMD);
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
done(cmd); done(cmd);
} else } else
@ -609,6 +598,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
case PASSTHRU_CMD: case PASSTHRU_CMD:
if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
struct st_drvver ver; struct st_drvver ver;
size_t cp_len = sizeof(ver);
ver.major = ST_VER_MAJOR; ver.major = ST_VER_MAJOR;
ver.minor = ST_VER_MINOR; ver.minor = ST_VER_MINOR;
ver.oem = ST_OEM; ver.oem = ST_OEM;
@ -616,7 +606,9 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
ver.signature[0] = PASSTHRU_SIGNATURE; ver.signature[0] = PASSTHRU_SIGNATURE;
ver.console_id = host->max_id - 1; ver.console_id = host->max_id - 1;
ver.host_no = hba->host->host_no; ver.host_no = hba->host->host_no;
cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ? stex_internal_copy(cmd, &ver, &cp_len,
scsi_sg_count(cmd), ST_TO_CMD);
cmd->result = sizeof(ver) == cp_len ?
DID_OK << 16 | COMMAND_COMPLETE << 8 : DID_OK << 16 | COMMAND_COMPLETE << 8 :
DID_ERROR << 16 | COMMAND_COMPLETE << 8; DID_ERROR << 16 | COMMAND_COMPLETE << 8;
done(cmd); done(cmd);
@ -709,7 +701,7 @@ static void stex_copy_data(struct st_ccb *ccb,
if (ccb->cmd == NULL) if (ccb->cmd == NULL)
return; return;
stex_internal_copy(ccb->cmd, stex_internal_copy(ccb->cmd,
resp->variable, &count, ccb->sg_count, ST_TO_CMD); resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD);
} }
static void stex_ys_commands(struct st_hba *hba, static void stex_ys_commands(struct st_hba *hba,
@ -734,7 +726,7 @@ static void stex_ys_commands(struct st_hba *hba,
count = STEX_EXTRA_SIZE; count = STEX_EXTRA_SIZE;
stex_internal_copy(ccb->cmd, hba->copy_buffer, stex_internal_copy(ccb->cmd, hba->copy_buffer,
&count, ccb->sg_count, ST_FROM_CMD); &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD);
inq_data = (ST_INQ *)hba->copy_buffer; inq_data = (ST_INQ *)hba->copy_buffer;
if (inq_data->DeviceTypeQualifier != 0) if (inq_data->DeviceTypeQualifier != 0)
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;