diff options
| -rw-r--r-- | drivers/scsi/ipr.c | 28 | ||||
| -rw-r--r-- | drivers/scsi/ipr.h | 1 | ||||
| -rw-r--r-- | drivers/scsi/scsi_error.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 6 |
4 files changed, 23 insertions, 14 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 882744852aac..a9aa38903efe 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -599,9 +599,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, | |||
| 599 | { | 599 | { |
| 600 | struct ipr_trace_entry *trace_entry; | 600 | struct ipr_trace_entry *trace_entry; |
| 601 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 601 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 602 | unsigned int trace_index; | ||
| 602 | 603 | ||
| 603 | trace_entry = &ioa_cfg->trace[atomic_add_return | 604 | trace_index = atomic_add_return(1, &ioa_cfg->trace_index) & IPR_TRACE_INDEX_MASK; |
| 604 | (1, &ioa_cfg->trace_index)%IPR_NUM_TRACE_ENTRIES]; | 605 | trace_entry = &ioa_cfg->trace[trace_index]; |
| 605 | trace_entry->time = jiffies; | 606 | trace_entry->time = jiffies; |
| 606 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; | 607 | trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; |
| 607 | trace_entry->type = type; | 608 | trace_entry->type = type; |
| @@ -1051,10 +1052,15 @@ static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd, | |||
| 1051 | 1052 | ||
| 1052 | static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg) | 1053 | static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg) |
| 1053 | { | 1054 | { |
| 1055 | unsigned int hrrq; | ||
| 1056 | |||
| 1054 | if (ioa_cfg->hrrq_num == 1) | 1057 | if (ioa_cfg->hrrq_num == 1) |
| 1055 | return 0; | 1058 | hrrq = 0; |
| 1056 | else | 1059 | else { |
| 1057 | return (atomic_add_return(1, &ioa_cfg->hrrq_index) % (ioa_cfg->hrrq_num - 1)) + 1; | 1060 | hrrq = atomic_add_return(1, &ioa_cfg->hrrq_index); |
| 1061 | hrrq = (hrrq % (ioa_cfg->hrrq_num - 1)) + 1; | ||
| 1062 | } | ||
| 1063 | return hrrq; | ||
| 1058 | } | 1064 | } |
| 1059 | 1065 | ||
| 1060 | /** | 1066 | /** |
| @@ -6263,21 +6269,23 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) | |||
| 6263 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; | 6269 | struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; |
| 6264 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; | 6270 | struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; |
| 6265 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); | 6271 | u32 ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); |
| 6266 | unsigned long hrrq_flags; | 6272 | unsigned long lock_flags; |
| 6267 | 6273 | ||
| 6268 | scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len)); | 6274 | scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->s.ioasa.hdr.residual_data_len)); |
| 6269 | 6275 | ||
| 6270 | if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { | 6276 | if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) { |
| 6271 | scsi_dma_unmap(scsi_cmd); | 6277 | scsi_dma_unmap(scsi_cmd); |
| 6272 | 6278 | ||
| 6273 | spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags); | 6279 | spin_lock_irqsave(ipr_cmd->hrrq->lock, lock_flags); |
| 6274 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); | 6280 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); |
| 6275 | scsi_cmd->scsi_done(scsi_cmd); | 6281 | scsi_cmd->scsi_done(scsi_cmd); |
| 6276 | spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags); | 6282 | spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); |
| 6277 | } else { | 6283 | } else { |
| 6278 | spin_lock_irqsave(ipr_cmd->hrrq->lock, hrrq_flags); | 6284 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
| 6285 | spin_lock(&ipr_cmd->hrrq->_lock); | ||
| 6279 | ipr_erp_start(ioa_cfg, ipr_cmd); | 6286 | ipr_erp_start(ioa_cfg, ipr_cmd); |
| 6280 | spin_unlock_irqrestore(ipr_cmd->hrrq->lock, hrrq_flags); | 6287 | spin_unlock(&ipr_cmd->hrrq->_lock); |
| 6288 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
| 6281 | } | 6289 | } |
| 6282 | } | 6290 | } |
| 6283 | 6291 | ||
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 73790a1d0969..6b97ee45c7b4 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -1486,6 +1486,7 @@ struct ipr_ioa_cfg { | |||
| 1486 | 1486 | ||
| 1487 | #define IPR_NUM_TRACE_INDEX_BITS 8 | 1487 | #define IPR_NUM_TRACE_INDEX_BITS 8 |
| 1488 | #define IPR_NUM_TRACE_ENTRIES (1 << IPR_NUM_TRACE_INDEX_BITS) | 1488 | #define IPR_NUM_TRACE_ENTRIES (1 << IPR_NUM_TRACE_INDEX_BITS) |
| 1489 | #define IPR_TRACE_INDEX_MASK (IPR_NUM_TRACE_ENTRIES - 1) | ||
| 1489 | #define IPR_TRACE_SIZE (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES) | 1490 | #define IPR_TRACE_SIZE (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES) |
| 1490 | char trace_start[8]; | 1491 | char trace_start[8]; |
| 1491 | #define IPR_TRACE_START_LABEL "trace" | 1492 | #define IPR_TRACE_START_LABEL "trace" |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 106884a5444e..cfadccef045c 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -944,7 +944,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, | |||
| 944 | scmd->sdb.length); | 944 | scmd->sdb.length); |
| 945 | scmd->sdb.table.sgl = &ses->sense_sgl; | 945 | scmd->sdb.table.sgl = &ses->sense_sgl; |
| 946 | scmd->sc_data_direction = DMA_FROM_DEVICE; | 946 | scmd->sc_data_direction = DMA_FROM_DEVICE; |
| 947 | scmd->sdb.table.nents = 1; | 947 | scmd->sdb.table.nents = scmd->sdb.table.orig_nents = 1; |
| 948 | scmd->cmnd[0] = REQUEST_SENSE; | 948 | scmd->cmnd[0] = REQUEST_SENSE; |
| 949 | scmd->cmnd[4] = scmd->sdb.length; | 949 | scmd->cmnd[4] = scmd->sdb.length; |
| 950 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | 950 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index b1a263137a23..448ebdaa3d69 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -583,7 +583,7 @@ static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask) | |||
| 583 | 583 | ||
| 584 | static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq) | 584 | static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq) |
| 585 | { | 585 | { |
| 586 | if (mq && sdb->table.nents <= SCSI_MAX_SG_SEGMENTS) | 586 | if (mq && sdb->table.orig_nents <= SCSI_MAX_SG_SEGMENTS) |
| 587 | return; | 587 | return; |
| 588 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free); | 588 | __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free); |
| 589 | } | 589 | } |
| @@ -597,8 +597,8 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) | |||
| 597 | 597 | ||
| 598 | if (mq) { | 598 | if (mq) { |
| 599 | if (nents <= SCSI_MAX_SG_SEGMENTS) { | 599 | if (nents <= SCSI_MAX_SG_SEGMENTS) { |
| 600 | sdb->table.nents = nents; | 600 | sdb->table.nents = sdb->table.orig_nents = nents; |
| 601 | sg_init_table(sdb->table.sgl, sdb->table.nents); | 601 | sg_init_table(sdb->table.sgl, nents); |
| 602 | return 0; | 602 | return 0; |
| 603 | } | 603 | } |
| 604 | first_chunk = sdb->table.sgl; | 604 | first_chunk = sdb->table.sgl; |
