SCSI fixes for 2.6.36-rc3
Subsystems (5)
This includes the oops from use after free, a set of qla2xxx fixes, some misc warning cleanups from the recently introduced printk issue, an hpsa lockup fix and a medium removal bug in sd introduced by the BKL pushdown.
The patch is available here:
master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
The short changelog is:
James Bottomley (1):
fix use-after-free in scsi_init_io()
Jayamohan Kallickal (1):
be2iscsi: Fix for Login failure
Jean Sacren (1):
Fix warning: zero-length gnu_printf format string
Jiri Slaby (1):
fix bio.bi_rw handling
Lalit Chandivade (2):
qla2xxx: Cover UNDERRUN case where SCSI status is set.
qla2xxx: Reset seconds_since_last_heartbeat correctly.
Madhuranath Iyengar (1):
qla2xxx: Update version number to 8.03.04-k0.
Stephen M. Cameron (1):
hpsa: disable doorbell reset on reset_devices
The diffstat:
drivers/scsi/be2iscsi/be_iscsi.c | 5 - drivers/scsi/be2iscsi/be_mgmt.c | 2 drivers/scsi/constants.c | 6 +- drivers/scsi/hpsa.c | 6 ++ drivers/scsi/osd/osd_initiator.c | 2 drivers/scsi/qla2xxx/qla_attr.c | 23 +++++--- drivers/scsi/qla2xxx/qla_dbg.h | 2 drivers/scsi/qla2xxx/qla_def.h | 20 +++++++ drivers/scsi/qla2xxx/qla_init.c | 94 +++++++++++++++++++++++++++++++----- drivers/scsi/qla2xxx/qla_isr.c | 7 +- drivers/scsi/qla2xxx/qla_mbx.c | 7 +- drivers/scsi/qla2xxx/qla_mid.c | 68 ++++++++++++++++++++++---- drivers/scsi/qla2xxx/qla_nx.c | 36 ++++++++++--- drivers/scsi/qla2xxx/qla_os.c | 30 +++++++++-- drivers/scsi/qla2xxx/qla_version.h | 4 - drivers/scsi/scsi_lib.c | 2 drivers/scsi/sd.c | 8 +-- drivers/scsi/sym53c8xx_2/sym_hipd.c | 10 +-- 18 files changed, 262 insertions(+), 70 deletions(-)
and the full diff is attached below.
James
---
drivers/scsi/be2iscsi/be_iscsi.c +2 -3
@@ -300,8 +300,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf) { struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); -int len =0 ; -int status; +int status =0 ;SE_DEBUG (DBG_LVL_8 ,"In beiscsi_get_host_param, param= %d\n" , param);switch (param) {
@@ -315,7 +314,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,default :return iscsi_host_get_param (shost, param, buf); } -return len; +return status; }int beiscsi_get_macaddr (char *buf,struct beiscsi_hba *phba)
drivers/scsi/be2iscsi/be_mgmt.c +1 -1
@@ -368,7 +368,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba,memset (req,0 ,sizeof (*req)); wrb->tag0 |= tag; -be_wrb_hdr_prepare (wrb,sizeof (*req), true,1 ); +be_wrb_hdr_prepare (wrb,sizeof (*req), false,1 );be_cmd_hdr_prepare (&req->hdr,CMD_SUBSYSTEM_ISCSI ,OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD ,sizeof (*req));
drivers/scsi/constants.c +3 -3
@@ -1404,13 +1404,13 @@ void scsi_print_sense(char *name, struct scsi_cmnd *cmd) {struct scsi_sense_hdr sshdr; -scmd_printk (KERN_INFO , cmd,"" ); +scmd_printk (KERN_INFO , cmd," " );scsi_decode_sense_buffer (cmd->sense_buffer,SCSI_SENSE_BUFFERSIZE , &sshdr);scsi_show_sense_hdr (&sshdr);scsi_decode_sense_extras (cmd->sense_buffer,SCSI_SENSE_BUFFERSIZE , &sshdr); -scmd_printk (KERN_INFO , cmd,"" ); +scmd_printk (KERN_INFO , cmd," " );scsi_show_extd_sense (sshdr.asc, sshdr.ascq); }EXPORT_SYMBOL (scsi_print_sense);
@@ -1453,7 +1453,7 @@ EXPORT_SYMBOL(scsi_show_result);void scsi_print_result (struct scsi_cmnd *cmd) { -scmd_printk (KERN_INFO , cmd,"" ); +scmd_printk (KERN_INFO , cmd," " );scsi_show_result (cmd->result); }EXPORT_SYMBOL (scsi_print_result);
drivers/scsi/hpsa.c +6 -0
@@ -3231,6 +3231,12 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) misc_fw_support =readl (&cfgtable->misc_fw_support); use_doorbell = misc_fw_support &MISC_FW_DOORBELL_RESET ; +/* The doorbell reset seems to cause lockups on some Smart +* Arrays (e.g. P410, P410i, maybe others). Until this is +* fixed or at least isolated, avoid the doorbell reset. +*/ + use_doorbell =0 ; + rc =hpsa_controller_hard_reset (pdev, vaddr, use_doorbell);if (rc) goto unmap_cfgtable;
drivers/scsi/osd/osd_initiator.c +1 -1
@@ -865,7 +865,7 @@ void osd_req_read(struct osd_request *or, {_osd_req_encode_common (or,OSD_ACT_READ , obj, offset, len);WARN_ON (or->in.bio || or->in.total_bytes); -WARN_ON (1 == (bio->bi_rw &REQ_WRITE )); +WARN_ON (bio->bi_rw &REQ_WRITE ); or->in.bio = bio; or->in.total_bytes = len; }
drivers/scsi/qla2xxx/qla_attr.c +15 -8
@@ -1838,26 +1838,33 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)qla24xx_disable_vp (vha); + vha->flags.delete_progress =1 ; +fc_remove_host (vha->host);scsi_remove_host (vha->host); -qla2x00_free_fcports (vha); +if (vha->timer_active) { +qla2x00_vp_stop_timer (vha); +DEBUG15 (printk (KERN_INFO "scsi(%ld): timer for the vport[%d]" +" = %p has stopped\n" , vha->host_no, vha->vp_idx, vha)); + }qla24xx_deallocate_vp_id (vha); +/* No pending activities shall be there on the vha now */ +DEBUG (msleep (random32 ()%10 ));/* Just to see if something falls on +* the net we have placed below */ + +BUG_ON (atomic_read (&vha->vref_count)); + +qla2x00_free_fcports (vha); +mutex_lock (&ha->vport_lock); ha->cur_vport_count--;clear_bit (vha->vp_idx, ha->vp_idx_map);mutex_unlock (&ha->vport_lock); -if (vha->timer_active) { -qla2x00_vp_stop_timer (vha); -DEBUG15 (printk ("scsi(%ld): timer for the vport[%d] = %p " -"has stopped\n" , - vha->host_no, vha->vp_idx, vha)); - } -if (vha->req->id && !ha->flags.cpu_affinity_enabled) {if (qla25xx_delete_req_que (vha, vha->req) !=QLA_SUCCESS ) qla_printk(KERN_WARNING, ha,
drivers/scsi/qla2xxx/qla_dbg.h +0 -2
@@ -29,8 +29,6 @@/* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ /* #define QL_DEBUG_LEVEL_18 */ /* Output T10 CRC trace messages */ -/* #define QL_PRINTK_BUF */ /* Captures printk to buffer */ -/* * Macros use for debugging the driver. */
drivers/scsi/qla2xxx/qla_def.h +20 -0
@@ -2641,6 +2641,7 @@ struct qla_hw_data {#define MBX_UPDATE_FLASH_ACTIVE 3struct mutex vport_lock;/* Virtual port synchronization */ +spinlock_t vport_slock;/* order is hardware_lock, then vport_slock */ struct completion mbx_cmd_comp;/* Serialize mbx access */ struct completion mbx_intr_comp;/* Used for completion notification */ struct completion dcbx_comp;/* For set port config notification */
@@ -2828,6 +2829,7 @@ typedef struct scsi_qla_host { uint32_t management_server_logged_in :1; uint32_t process_response_queue :1; uint32_t difdix_supported:1; + uint32_t delete_progress:1; } flags;atomic_t loop_state;
@@ -2922,6 +2924,8 @@ typedef struct scsi_qla_host {struct req_que *req;int fw_heartbeat_counter;int seconds_since_last_heartbeat; + +atomic_t vref_count; } scsi_qla_host_t;/*
@@ -2932,6 +2936,22 @@ typedef struct scsi_qla_host { test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ atomic_read(&ha->loop_state) == LOOP_DOWN) +#define QLA_VHA_MARK_BUSY (__vha, __bail) do { \ + atomic_inc(&__vha->vref_count); \ + mb(); \ + if (__vha->flags.delete_progress) { \ + atomic_dec(&__vha->vref_count); \ + __bail = 1; \ + } else { \ + __bail = 0; \ + } \ +} while (0) + +#define QLA_VHA_MARK_NOT_BUSY (__vha) do { \ + atomic_dec(&__vha->vref_count); \ +} while (0) + + #define qla_printk(level, ha, format, arg...) \ dev_printk(level , &((ha)->pdev->dev) , format , ## arg)
drivers/scsi/qla2xxx/qla_init.c +81 -13
213 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_isr.c +4 -3
@@ -1706,19 +1706,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) cp->result =DID_ERROR <<16 ;break ; } - }else if (!lscsi_status) { + }else {DEBUG2 (qla_printk (KERN_INFO , ha,"scsi(%ld:%d:%d) Dropped frame(s) detected (0x%x " "of 0x%x bytes).\n" , vha->host_no, cp->device->id, cp->device->lun, resid,scsi_bufflen (cp))); - cp->result =DID_ERROR <<16 ; -break ; + cp->result =DID_ERROR <<16 | lscsi_status; + goto check_scsi_status; } cp->result =DID_OK <<16 | lscsi_status; logit =0 ; +check_scsi_status:/* * Check to see if SCSI Status is non zero. If so report SCSI * Status.
drivers/scsi/qla2xxx/qla_mbx.c +5 -2
@@ -2913,7 +2913,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,uint16_t stat =le16_to_cpu (rptid_entry->vp_idx);struct qla_hw_data *ha = vha->hw;scsi_qla_host_t *vp; -scsi_qla_host_t *tvp; +unsigned long flags;if (rptid_entry->entry_status !=0 )return ;
@@ -2945,9 +2945,12 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,return ; } -list_for_each_entry_safe (vp, tvp, &ha->vp_list, list) +spin_lock_irqsave (&ha->vport_slock, flags); +list_for_each_entry (vp, &ha->vp_list, list)if (vp_idx == vp->vp_idx)break ; +spin_unlock_irqrestore (&ha->vport_slock, flags); +if (!vp)return ;
drivers/scsi/qla2xxx/qla_mid.c +60 -8
148 lines not on this page · raw message
drivers/scsi/qla2xxx/qla_nx.c +27 -9
@@ -2672,6 +2672,19 @@ qla82xx_start_scsi(srb_t *sp) sufficient_dsds: req_cnt =1 ; +if (req->cnt < (req_cnt +2 )) { + cnt = (uint16_t )RD_REG_DWORD_RELAXED ( + ®->req_q_out[0 ]); +if (req->ring_index < cnt) + req->cnt = cnt - req->ring_index; +else + req->cnt = req->length - + (req->ring_index - cnt); + } + +if (req->cnt < (req_cnt +2 )) + goto queuing_error; + ctx = sp->ctx =mempool_alloc (ha->ctx_mempool,GFP_ATOMIC );if (!sp->ctx) { DEBUG(printk(KERN_INFO
@@ -3307,16 +3320,19 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha)set_bit (ISP_ABORT_NEEDED , &vha->dpc_flags); }qla2xxx_wake_dpc (vha); + ha->flags.fw_hung =1 ;if (ha->flags.mbox_busy) { - ha->flags.fw_hung =1 ; ha->flags.mbox_int =1 ;DEBUG2 (qla_printk (KERN_ERR , ha, -"Due to fw hung, doing premature " -"completion of mbx command\n" )); -complete (&ha->mbx_intr_comp); +"Due to fw hung, doing premature " +"completion of mbx command\n" )); +if (test_bit (MBX_INTR_WAIT , + &ha->mbx_cmd_flags)) +complete (&ha->mbx_intr_comp); } } - } + }else + vha->seconds_since_last_heartbeat =0 ; vha->fw_heartbeat_counter = fw_heartbeat_counter; }
@@ -3418,13 +3434,15 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) "%s(): Adapter reset needed!\n", __func__);set_bit (ISP_ABORT_NEEDED , &vha->dpc_flags);qla2xxx_wake_dpc (vha); + ha->flags.fw_hung =1 ;if (ha->flags.mbox_busy) { - ha->flags.fw_hung =1 ; ha->flags.mbox_int =1 ;DEBUG2 (qla_printk (KERN_ERR , ha, -"Need reset, doing premature " -"completion of mbx command\n" )); -complete (&ha->mbx_intr_comp); +"Need reset, doing premature " +"completion of mbx command\n" )); +if (test_bit (MBX_INTR_WAIT , + &ha->mbx_cmd_flags)) +complete (&ha->mbx_intr_comp); } }else {qla82xx_check_fw_alive (vha);
drivers/scsi/qla2xxx/qla_os.c +26 -4
@@ -2341,16 +2341,28 @@ probe_out:static void qla2x00_remove_one (struct pci_dev *pdev) { -scsi_qla_host_t *base_vha, *vha, *temp; +scsi_qla_host_t *base_vha, *vha;struct qla_hw_data *ha; +unsigned long flags; base_vha =pci_get_drvdata (pdev); ha = base_vha->hw; -list_for_each_entry_safe (vha, temp, &ha->vp_list, list) { -if (vha && vha->fc_vport) +spin_lock_irqsave (&ha->vport_slock, flags); +list_for_each_entry (vha, &ha->vp_list, list) { +atomic_inc (&vha->vref_count); + +if (vha && vha->fc_vport) { +spin_unlock_irqrestore (&ha->vport_slock, flags); +fc_vport_terminate (vha->fc_vport); + +spin_lock_irqsave (&ha->vport_slock, flags); + } + +atomic_dec (&vha->vref_count); } +spin_unlock_irqrestore (&ha->vport_slock, flags);set_bit (UNLOADING , &base_vha->dpc_flags);
@@ -2975,10 +2987,17 @@ static struct qla_work_evt * qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) {struct qla_work_evt *e; +uint8_t bail; + +QLA_VHA_MARK_BUSY (vha, bail); +if (bail) +return NULL ; e =kzalloc (sizeof (struct qla_work_evt ),GFP_ATOMIC ); -if (!e) +if (!e) { +QLA_VHA_MARK_NOT_BUSY (vha);return NULL ; + }INIT_LIST_HEAD (&e->list); e->type = type;
@@ -3135,6 +3154,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) }if (e->flags &QLA_EVT_FLAG_FREE )kfree (e); + +/* For each work completed decrement vha ref count */ +QLA_VHA_MARK_NOT_BUSY (vha); } }
drivers/scsi/qla2xxx/qla_version.h +2 -2
@@ -7,9 +7,9 @@/* * Driver version */ -#define QLA2XXX_VERSION "8.03.03-k0" +#define QLA2XXX_VERSION "8.03.04-k0"#define QLA_DRIVER_MAJOR_VER 8#define QLA_DRIVER_MINOR_VER 3 -#define QLA_DRIVER_PATCH_VER 3 +#define QLA_DRIVER_PATCH_VER 4#define QLA_DRIVER_BETA_VER 0
drivers/scsi/scsi_lib.c +1 -1
@@ -1011,8 +1011,8 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) err_exit:scsi_release_buffers (cmd); -scsi_put_command (cmd); cmd->request->special =NULL ; +scsi_put_command (cmd);return error; }EXPORT_SYMBOL (scsi_init_io);
drivers/scsi/sd.c +4 -4
@@ -870,7 +870,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)SCSI_LOG_HLQUEUE (3 ,sd_printk (KERN_INFO , sdkp,"sd_release\n" )); -if (atomic_dec_return (&sdkp->openers) && sdev->removable) { +if (atomic_dec_return (&sdkp->openers) ==0 && sdev->removable) {if (scsi_block_when_processing_errors (sdev))scsi_set_medium_removal (sdev,SCSI_REMOVAL_ALLOW ); }
@@ -2625,15 +2625,15 @@ module_exit(exit_sd);static void sd_print_sense_hdr (struct scsi_disk *sdkp,struct scsi_sense_hdr *sshdr) { -sd_printk (KERN_INFO , sdkp,"" ); +sd_printk (KERN_INFO , sdkp," " );scsi_show_sense_hdr (sshdr); -sd_printk (KERN_INFO , sdkp,"" ); +sd_printk (KERN_INFO , sdkp," " );scsi_show_extd_sense (sshdr->asc, sshdr->ascq); }static void sd_print_result (struct scsi_disk *sdkp,int result) { -sd_printk (KERN_INFO , sdkp,"" ); +sd_printk (KERN_INFO , sdkp," " );scsi_show_result (result); }
drivers/scsi/sym53c8xx_2/sym_hipd.c +4 -6
@@ -72,10 +72,7 @@ static void sym_printl_hex(u_char *p, int n)static void sym_print_msg (struct sym_ccb *cp,char *label,u_char *msg) { -if (label) -sym_print_addr (cp->cmd,"%s: " , label); -else -sym_print_addr (cp->cmd,"" ); +sym_print_addr (cp->cmd,"%s: " , label);spi_print_msg (msg);printf ("\n" );
@@ -4558,7 +4555,8 @@ static void sym_int_sir(struct sym_hcb *np)switch (np->msgin [2 ]) {case M_X_MODIFY_DP :if (DEBUG_FLAGS &DEBUG_POINTER ) -sym_print_msg (cp,NULL , np->msgin); +sym_print_msg (cp,"extended msg " , + np->msgin); tmp = (np->msgin[3 ]<<24 ) + (np->msgin[4 ]<<16 ) + (np->msgin[5 ]<<8 ) + (np->msgin[6 ]);sym_modify_dp (np, tp, cp, tmp);
@@ -4585,7 +4583,7 @@ static void sym_int_sir(struct sym_hcb *np)*/ case M_IGN_RESIDUE :if (DEBUG_FLAGS &DEBUG_POINTER ) -sym_print_msg (cp,NULL , np->msgin); +sym_print_msg (cp,"1 or 2 byte " , np->msgin);if (cp->host_flags &HF_SENSE )OUTL_DSP (np,SCRIPTA_BA (np, clrack));else