diff options
Diffstat (limited to 'drivers/scsi/pm8001/pm80xx_hwi.c')
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 101 |
1 files changed, 91 insertions, 10 deletions
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 5fe50e0effcd..1ba93fb76093 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1960,13 +1960,15 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) sas_ssp_task_response(pm8001_ha->dev, t, iu); } if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_ABORTED: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_ABORTED IOMB Tag\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_UNDERFLOW: /* SSP Completion with error */ @@ -1977,13 +1979,15 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_DATA_UNDERRUN; ts->residual = param; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_NO_DEVICE: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_PHY_DOWN; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, @@ -1992,6 +1996,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_OPEN_REJECT; /* Force the midlayer to retry */ ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_PHY_NOT_READY: PM8001_IO_DBG(pm8001_ha, @@ -1999,6 +2005,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_INVALID_SSP_RSP_FRAME: PM8001_IO_DBG(pm8001_ha, @@ -2006,6 +2014,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: PM8001_IO_DBG(pm8001_ha, @@ -2013,6 +2023,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_EPROTO; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: PM8001_IO_DBG(pm8001_ha, @@ -2020,6 +2032,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_UNKNOWN; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, @@ -2027,6 +2041,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: @@ -2050,6 +2066,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_BAD_DEST; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: PM8001_IO_DBG(pm8001_ha, pm8001_printk( @@ -2057,6 +2075,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_CONN_RATE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: PM8001_IO_DBG(pm8001_ha, @@ -2064,6 +2084,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_NAK_RECEIVED: PM8001_IO_DBG(pm8001_ha, @@ -2071,18 +2093,24 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_ACK_NAK_TIMEOUT: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_NAK_R_ERR; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_DMA: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_DMA\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_OPEN_RETRY_TIMEOUT: PM8001_IO_DBG(pm8001_ha, @@ -2090,18 +2118,24 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_OFFSET_MISMATCH: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_PORT_IN_RESET: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_PORT_IN_RESET\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_DS_NON_OPERATIONAL: PM8001_IO_DBG(pm8001_ha, @@ -2118,18 +2152,24 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk("IO_DS_IN_RECOVERY\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_TM_TAG_NOT_FOUND: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_TM_TAG_NOT_FOUND\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_SSP_EXT_IU_ZERO_LEN_ERROR: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: PM8001_IO_DBG(pm8001_ha, @@ -2137,6 +2177,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; default: PM8001_DEVIO_DBG(pm8001_ha, @@ -2144,6 +2186,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; } PM8001_IO_DBG(pm8001_ha, @@ -2203,7 +2247,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_DATA_OVERRUN; ts->residual = 0; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, @@ -2528,7 +2572,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("response too large\n")); } if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_ABORTED: PM8001_IO_DBG(pm8001_ha, @@ -2536,7 +2580,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_ABORTED_TASK; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; /* following cases are to do cases */ case IO_UNDERFLOW: @@ -2547,19 +2591,23 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_DATA_UNDERRUN; ts->residual = param; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_NO_DEVICE: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_PHY_DOWN; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_BREAK\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_INTERRUPTED; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_PHY_NOT_READY: PM8001_IO_DBG(pm8001_ha, @@ -2567,6 +2615,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: PM8001_IO_DBG(pm8001_ha, pm8001_printk( @@ -2574,6 +2624,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_EPROTO; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: PM8001_IO_DBG(pm8001_ha, @@ -2581,6 +2633,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_UNKNOWN; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, @@ -2588,6 +2642,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: @@ -2631,6 +2687,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_CONN_RATE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: PM8001_IO_DBG(pm8001_ha, pm8001_printk( @@ -2653,48 +2711,64 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_WRONG_DEST; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_NAK_RECEIVED: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_NAK_R_ERR; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_ACK_NAK_TIMEOUT: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_NAK_R_ERR; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_DMA: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_DMA\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_ABORTED_TASK; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_SATA_LINK_TIMEOUT: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n")); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_DEV_NO_RESPONSE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_REJECTED_NCQ_MODE: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_DATA_UNDERRUN; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_OPEN_RETRY_TIMEOUT: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_TO; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_PORT_IN_RESET: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_PORT_IN_RESET\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_DEV_NO_RESPONSE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_DS_NON_OPERATIONAL: PM8001_IO_DBG(pm8001_ha, @@ -2715,6 +2789,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("IO_DS_IN_RECOVERY\n")); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_DEV_NO_RESPONSE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; case IO_DS_IN_ERROR: PM8001_IO_DBG(pm8001_ha, @@ -2736,6 +2812,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; default: PM8001_DEVIO_DBG(pm8001_ha, @@ -2743,6 +2821,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) /* not allowed case. Therefore, return failed status */ ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_DEV_NO_RESPONSE; + if (pm8001_dev) + atomic_dec(&pm8001_dev->running_req); break; } spin_lock_irqsave(&t->task_state_lock, flags); @@ -2820,7 +2900,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_DATA_OVERRUN; ts->residual = 0; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_XFER_ERROR_BREAK: PM8001_IO_DBG(pm8001_ha, @@ -3040,7 +3120,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAM_STAT_GOOD; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); if (pm8001_ha->smp_exp_mode == SMP_DIRECT) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("DIRECT RESPONSE Length:%d\n", @@ -3063,7 +3143,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_ABORTED_TASK; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_OVERFLOW: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); @@ -3071,7 +3151,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_DATA_OVERRUN; ts->residual = 0; if (pm8001_dev) - pm8001_dev->running_req--; + atomic_dec(&pm8001_dev->running_req); break; case IO_NO_DEVICE: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); @@ -4809,6 +4889,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, flags); pm8001_ccb_task_free_done(pm8001_ha, task, ccb, tag); + atomic_dec(&pm8001_ha_dev->running_req); return 0; } } |