aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Rangankar <manish.rangankar@cavium.com>2018-02-12 01:48:41 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2018-02-13 21:35:41 -0500
commit1bc5ad3a6acdcf56f83272f2de1cd2389ea9e9e2 (patch)
treed5a3494e29017db8d41210e37282c0276c60d3d3
parent00c20cdc79259c6c5bf978b21af96c2d3edb646d (diff)
scsi: qla4xxx: skip error recovery in case of register disconnect.
A system crashes when continuously removing/re-adding the storage controller. Signed-off-by: Manish Rangankar <manish.rangankar@cavium.com> Reviewed-by: Ewan D. Milne <emilne@redhat.com> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c46
2 files changed, 48 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index fc233717355f..817f312023a9 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -168,6 +168,8 @@
168#define DEV_DB_NON_PERSISTENT 0 168#define DEV_DB_NON_PERSISTENT 0
169#define DEV_DB_PERSISTENT 1 169#define DEV_DB_PERSISTENT 1
170 170
171#define QL4_ISP_REG_DISCONNECT 0xffffffffU
172
171#define COPY_ISID(dst_isid, src_isid) { \ 173#define COPY_ISID(dst_isid, src_isid) { \
172 int i, j; \ 174 int i, j; \
173 for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \ 175 for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 82e889bbe0ed..fc2c97d9a0d6 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -262,6 +262,24 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
262 262
263static struct scsi_transport_template *qla4xxx_scsi_transport; 263static struct scsi_transport_template *qla4xxx_scsi_transport;
264 264
265static int qla4xxx_isp_check_reg(struct scsi_qla_host *ha)
266{
267 u32 reg_val = 0;
268 int rval = QLA_SUCCESS;
269
270 if (is_qla8022(ha))
271 reg_val = readl(&ha->qla4_82xx_reg->host_status);
272 else if (is_qla8032(ha) || is_qla8042(ha))
273 reg_val = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
274 else
275 reg_val = readw(&ha->reg->ctrl_status);
276
277 if (reg_val == QL4_ISP_REG_DISCONNECT)
278 rval = QLA_ERROR;
279
280 return rval;
281}
282
265static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num, 283static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
266 uint32_t iface_type, uint32_t payload_size, 284 uint32_t iface_type, uint32_t payload_size,
267 uint32_t pid, struct sockaddr *dst_addr) 285 uint32_t pid, struct sockaddr *dst_addr)
@@ -9186,10 +9204,17 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
9186 struct srb *srb = NULL; 9204 struct srb *srb = NULL;
9187 int ret = SUCCESS; 9205 int ret = SUCCESS;
9188 int wait = 0; 9206 int wait = 0;
9207 int rval;
9189 9208
9190 ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n", 9209 ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n",
9191 ha->host_no, id, lun, cmd, cmd->cmnd[0]); 9210 ha->host_no, id, lun, cmd, cmd->cmnd[0]);
9192 9211
9212 rval = qla4xxx_isp_check_reg(ha);
9213 if (rval != QLA_SUCCESS) {
9214 ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
9215 return FAILED;
9216 }
9217
9193 spin_lock_irqsave(&ha->hardware_lock, flags); 9218 spin_lock_irqsave(&ha->hardware_lock, flags);
9194 srb = (struct srb *) CMD_SP(cmd); 9219 srb = (struct srb *) CMD_SP(cmd);
9195 if (!srb) { 9220 if (!srb) {
@@ -9241,6 +9266,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
9241 struct scsi_qla_host *ha = to_qla_host(cmd->device->host); 9266 struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
9242 struct ddb_entry *ddb_entry = cmd->device->hostdata; 9267 struct ddb_entry *ddb_entry = cmd->device->hostdata;
9243 int ret = FAILED, stat; 9268 int ret = FAILED, stat;
9269 int rval;
9244 9270
9245 if (!ddb_entry) 9271 if (!ddb_entry)
9246 return ret; 9272 return ret;
@@ -9260,6 +9286,12 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
9260 cmd, jiffies, cmd->request->timeout / HZ, 9286 cmd, jiffies, cmd->request->timeout / HZ,
9261 ha->dpc_flags, cmd->result, cmd->allowed)); 9287 ha->dpc_flags, cmd->result, cmd->allowed));
9262 9288
9289 rval = qla4xxx_isp_check_reg(ha);
9290 if (rval != QLA_SUCCESS) {
9291 ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
9292 return FAILED;
9293 }
9294
9263 /* FIXME: wait for hba to go online */ 9295 /* FIXME: wait for hba to go online */
9264 stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun); 9296 stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);
9265 if (stat != QLA_SUCCESS) { 9297 if (stat != QLA_SUCCESS) {
@@ -9303,6 +9335,7 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
9303 struct scsi_qla_host *ha = to_qla_host(cmd->device->host); 9335 struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
9304 struct ddb_entry *ddb_entry = cmd->device->hostdata; 9336 struct ddb_entry *ddb_entry = cmd->device->hostdata;
9305 int stat, ret; 9337 int stat, ret;
9338 int rval;
9306 9339
9307 if (!ddb_entry) 9340 if (!ddb_entry)
9308 return FAILED; 9341 return FAILED;
@@ -9320,6 +9353,12 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
9320 ha->host_no, cmd, jiffies, cmd->request->timeout / HZ, 9353 ha->host_no, cmd, jiffies, cmd->request->timeout / HZ,
9321 ha->dpc_flags, cmd->result, cmd->allowed)); 9354 ha->dpc_flags, cmd->result, cmd->allowed));
9322 9355
9356 rval = qla4xxx_isp_check_reg(ha);
9357 if (rval != QLA_SUCCESS) {
9358 ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
9359 return FAILED;
9360 }
9361
9323 stat = qla4xxx_reset_target(ha, ddb_entry); 9362 stat = qla4xxx_reset_target(ha, ddb_entry);
9324 if (stat != QLA_SUCCESS) { 9363 if (stat != QLA_SUCCESS) {
9325 starget_printk(KERN_INFO, scsi_target(cmd->device), 9364 starget_printk(KERN_INFO, scsi_target(cmd->device),
@@ -9374,9 +9413,16 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
9374{ 9413{
9375 int return_status = FAILED; 9414 int return_status = FAILED;
9376 struct scsi_qla_host *ha; 9415 struct scsi_qla_host *ha;
9416 int rval;
9377 9417
9378 ha = to_qla_host(cmd->device->host); 9418 ha = to_qla_host(cmd->device->host);
9379 9419
9420 rval = qla4xxx_isp_check_reg(ha);
9421 if (rval != QLA_SUCCESS) {
9422 ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");
9423 return FAILED;
9424 }
9425
9380 if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba) 9426 if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba)
9381 qla4_83xx_set_idc_dontreset(ha); 9427 qla4_83xx_set_idc_dontreset(ha);
9382 9428