Commit 4a2efd4b authored by Viswas G's avatar Viswas G Committed by Martin K. Petersen

scsi: pm80xx: Make running_req atomic

Incorrect value of the running_req was causing the driver unload to be
stuck during the SAS lldd_dev_gone notification handling.  During SATA I/O
completion, for some error status values, the driver schedules the event
handler and running_req is decremented from that.  However, there are some
other error status values (like IO_DS_IN_RECOVERY,
IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR) where the I/O has already been
completed by fw/driver so running_req is not decremented.

Also during NCQ error handling, driver itself will initiate READ_LOG_EXT
and ABORT_ALL. When libsas/libata initiate READ_LOG_EXT (0x2F), driver
increments running_req. This will be completed by the driver in
pm80xx_chip_sata_req(), but running_req was not decremented.

Link: https://lore.kernel.org/r/20201102165528.26510-3-Viswas.G@microchip.com.comAcked-by: default avatarJack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: default avatarViswas G <Viswas.G@microchip.com>
Signed-off-by: default avatarRuksar Devadi <Ruksar.devadi@microchip.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7640e1eb
...@@ -1587,7 +1587,7 @@ void pm8001_work_fn(struct work_struct *work) ...@@ -1587,7 +1587,7 @@ void pm8001_work_fn(struct work_struct *work)
ts->stat = SAS_QUEUE_FULL; ts->stat = SAS_QUEUE_FULL;
pm8001_dev = ccb->device; pm8001_dev = ccb->device;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
spin_lock_irqsave(&t->task_state_lock, flags1); spin_lock_irqsave(&t->task_state_lock, flags1);
t->task_state_flags &= ~SAS_TASK_STATE_PENDING; t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
...@@ -1942,7 +1942,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ...@@ -1942,7 +1942,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
sas_ssp_task_response(pm8001_ha->dev, t, iu); sas_ssp_task_response(pm8001_ha->dev, t, iu);
} }
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_ABORTED: case IO_ABORTED:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -1958,7 +1958,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ...@@ -1958,7 +1958,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
ts->stat = SAS_DATA_UNDERRUN; ts->stat = SAS_DATA_UNDERRUN;
ts->residual = param; ts->residual = param;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_NO_DEVICE: case IO_NO_DEVICE:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2172,7 +2172,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ...@@ -2172,7 +2172,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
ts->stat = SAS_DATA_OVERRUN; ts->stat = SAS_DATA_OVERRUN;
ts->residual = 0; ts->residual = 0;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_BREAK: case IO_XFER_ERROR_BREAK:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2487,7 +2487,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2487,7 +2487,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
pm8001_printk("response to large\n")); pm8001_printk("response to large\n"));
} }
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_ABORTED: case IO_ABORTED:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2495,7 +2495,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2495,7 +2495,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_ABORTED_TASK; ts->stat = SAS_ABORTED_TASK;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
/* following cases are to do cases */ /* following cases are to do cases */
case IO_UNDERFLOW: case IO_UNDERFLOW:
...@@ -2506,19 +2506,23 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2506,19 +2506,23 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->stat = SAS_DATA_UNDERRUN; ts->stat = SAS_DATA_UNDERRUN;
ts->residual = param; ts->residual = param;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_NO_DEVICE: case IO_NO_DEVICE:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_NO_DEVICE\n")); pm8001_printk("IO_NO_DEVICE\n"));
ts->resp = SAS_TASK_UNDELIVERED; ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_PHY_DOWN; ts->stat = SAS_PHY_DOWN;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_BREAK: case IO_XFER_ERROR_BREAK:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_BREAK\n")); pm8001_printk("IO_XFER_ERROR_BREAK\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_INTERRUPTED; ts->stat = SAS_INTERRUPTED;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_PHY_NOT_READY: case IO_XFER_ERROR_PHY_NOT_READY:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2526,6 +2530,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2526,6 +2530,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2534,6 +2540,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2534,6 +2540,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_EPROTO; ts->open_rej_reason = SAS_OREJ_EPROTO;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: case IO_OPEN_CNX_ERROR_ZONE_VIOLATION:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2541,6 +2549,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2541,6 +2549,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_UNKNOWN; ts->open_rej_reason = SAS_OREJ_UNKNOWN;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OPEN_CNX_ERROR_BREAK: case IO_OPEN_CNX_ERROR_BREAK:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2548,6 +2558,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2548,6 +2558,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; ts->open_rej_reason = SAS_OREJ_RSVD_CONT0;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2587,6 +2599,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2587,6 +2599,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_CONN_RATE; ts->open_rej_reason = SAS_OREJ_CONN_RATE;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2610,48 +2624,64 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2610,48 +2624,64 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_WRONG_DEST; ts->open_rej_reason = SAS_OREJ_WRONG_DEST;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_NAK_RECEIVED: case IO_XFER_ERROR_NAK_RECEIVED:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_NAK_R_ERR; ts->stat = SAS_NAK_R_ERR;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_ACK_NAK_TIMEOUT: case IO_XFER_ERROR_ACK_NAK_TIMEOUT:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_NAK_R_ERR; ts->stat = SAS_NAK_R_ERR;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_DMA: case IO_XFER_ERROR_DMA:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_DMA\n")); pm8001_printk("IO_XFER_ERROR_DMA\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_ABORTED_TASK; ts->stat = SAS_ABORTED_TASK;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_SATA_LINK_TIMEOUT: case IO_XFER_ERROR_SATA_LINK_TIMEOUT:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n")); pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n"));
ts->resp = SAS_TASK_UNDELIVERED; ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_DEV_NO_RESPONSE; ts->stat = SAS_DEV_NO_RESPONSE;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_REJECTED_NCQ_MODE: case IO_XFER_ERROR_REJECTED_NCQ_MODE:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DATA_UNDERRUN; ts->stat = SAS_DATA_UNDERRUN;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_OPEN_RETRY_TIMEOUT: case IO_XFER_OPEN_RETRY_TIMEOUT:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_TO; ts->stat = SAS_OPEN_TO;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_PORT_IN_RESET: case IO_PORT_IN_RESET:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("IO_PORT_IN_RESET\n")); pm8001_printk("IO_PORT_IN_RESET\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DEV_NO_RESPONSE; ts->stat = SAS_DEV_NO_RESPONSE;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_DS_NON_OPERATIONAL: case IO_DS_NON_OPERATIONAL:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2672,6 +2702,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2672,6 +2702,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
pm8001_printk(" IO_DS_IN_RECOVERY\n")); pm8001_printk(" IO_DS_IN_RECOVERY\n"));
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DEV_NO_RESPONSE; ts->stat = SAS_DEV_NO_RESPONSE;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_DS_IN_ERROR: case IO_DS_IN_ERROR:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2693,6 +2725,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2693,6 +2725,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
default: default:
PM8001_DEVIO_DBG(pm8001_ha, PM8001_DEVIO_DBG(pm8001_ha,
...@@ -2700,6 +2734,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2700,6 +2734,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
/* not allowed case. Therefore, return failed status */ /* not allowed case. Therefore, return failed status */
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DEV_NO_RESPONSE; ts->stat = SAS_DEV_NO_RESPONSE;
if (pm8001_dev)
atomic_dec(&pm8001_dev->running_req);
break; break;
} }
spin_lock_irqsave(&t->task_state_lock, flags); spin_lock_irqsave(&t->task_state_lock, flags);
...@@ -2776,7 +2812,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ...@@ -2776,7 +2812,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
ts->stat = SAS_DATA_OVERRUN; ts->stat = SAS_DATA_OVERRUN;
ts->residual = 0; ts->residual = 0;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_XFER_ERROR_BREAK: case IO_XFER_ERROR_BREAK:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2976,7 +3012,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2976,7 +3012,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAM_STAT_GOOD; ts->stat = SAM_STAT_GOOD;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_ABORTED: case IO_ABORTED:
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
...@@ -2984,7 +3020,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2984,7 +3020,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->resp = SAS_TASK_COMPLETE; ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_ABORTED_TASK; ts->stat = SAS_ABORTED_TASK;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_OVERFLOW: case IO_OVERFLOW:
PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n"));
...@@ -2992,7 +3028,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ...@@ -2992,7 +3028,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
ts->stat = SAS_DATA_OVERRUN; ts->stat = SAS_DATA_OVERRUN;
ts->residual = 0; ts->residual = 0;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
break; break;
case IO_NO_DEVICE: case IO_NO_DEVICE:
PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n"));
......
...@@ -412,7 +412,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, ...@@ -412,7 +412,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
pm8001_ha->devices[i].dev_type = SAS_PHY_UNUSED; pm8001_ha->devices[i].dev_type = SAS_PHY_UNUSED;
pm8001_ha->devices[i].id = i; pm8001_ha->devices[i].id = i;
pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES; pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES;
pm8001_ha->devices[i].running_req = 0; atomic_set(&pm8001_ha->devices[i].running_req, 0);
} }
pm8001_ha->flags = PM8001F_INIT_TIME; pm8001_ha->flags = PM8001F_INIT_TIME;
/* Initialize tags */ /* Initialize tags */
......
...@@ -456,9 +456,11 @@ static int pm8001_task_exec(struct sas_task *task, ...@@ -456,9 +456,11 @@ static int pm8001_task_exec(struct sas_task *task,
ccb->device = pm8001_dev; ccb->device = pm8001_dev;
switch (task_proto) { switch (task_proto) {
case SAS_PROTOCOL_SMP: case SAS_PROTOCOL_SMP:
atomic_inc(&pm8001_dev->running_req);
rc = pm8001_task_prep_smp(pm8001_ha, ccb); rc = pm8001_task_prep_smp(pm8001_ha, ccb);
break; break;
case SAS_PROTOCOL_SSP: case SAS_PROTOCOL_SSP:
atomic_inc(&pm8001_dev->running_req);
if (is_tmf) if (is_tmf)
rc = pm8001_task_prep_ssp_tm(pm8001_ha, rc = pm8001_task_prep_ssp_tm(pm8001_ha,
ccb, tmf); ccb, tmf);
...@@ -467,6 +469,7 @@ static int pm8001_task_exec(struct sas_task *task, ...@@ -467,6 +469,7 @@ static int pm8001_task_exec(struct sas_task *task,
break; break;
case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_SATA:
case SAS_PROTOCOL_STP: case SAS_PROTOCOL_STP:
atomic_inc(&pm8001_dev->running_req);
rc = pm8001_task_prep_ata(pm8001_ha, ccb); rc = pm8001_task_prep_ata(pm8001_ha, ccb);
break; break;
default: default:
...@@ -479,13 +482,13 @@ static int pm8001_task_exec(struct sas_task *task, ...@@ -479,13 +482,13 @@ static int pm8001_task_exec(struct sas_task *task,
if (rc) { if (rc) {
PM8001_IO_DBG(pm8001_ha, PM8001_IO_DBG(pm8001_ha,
pm8001_printk("rc is %x\n", rc)); pm8001_printk("rc is %x\n", rc));
atomic_dec(&pm8001_dev->running_req);
goto err_out_tag; goto err_out_tag;
} }
/* TODO: select normal or high priority */ /* TODO: select normal or high priority */
spin_lock(&t->task_state_lock); spin_lock(&t->task_state_lock);
t->task_state_flags |= SAS_TASK_AT_INITIATOR; t->task_state_flags |= SAS_TASK_AT_INITIATOR;
spin_unlock(&t->task_state_lock); spin_unlock(&t->task_state_lock);
pm8001_dev->running_req++;
} while (0); } while (0);
rc = 0; rc = 0;
goto out_done; goto out_done;
...@@ -886,11 +889,11 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) ...@@ -886,11 +889,11 @@ static void pm8001_dev_gone_notify(struct domain_device *dev)
PM8001_DISC_DBG(pm8001_ha, PM8001_DISC_DBG(pm8001_ha,
pm8001_printk("found dev[%d:%x] is gone.\n", pm8001_printk("found dev[%d:%x] is gone.\n",
pm8001_dev->device_id, pm8001_dev->dev_type)); pm8001_dev->device_id, pm8001_dev->dev_type));
if (pm8001_dev->running_req) { if (atomic_read(&pm8001_dev->running_req)) {
spin_unlock_irqrestore(&pm8001_ha->lock, flags); spin_unlock_irqrestore(&pm8001_ha->lock, flags);
pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
dev, 1, 0); dev, 1, 0);
while (pm8001_dev->running_req) while (atomic_read(&pm8001_dev->running_req))
msleep(20); msleep(20);
spin_lock_irqsave(&pm8001_ha->lock, flags); spin_lock_irqsave(&pm8001_ha->lock, flags);
} }
...@@ -968,7 +971,7 @@ void pm8001_open_reject_retry( ...@@ -968,7 +971,7 @@ void pm8001_open_reject_retry(
ts->stat = SAS_OPEN_REJECT; ts->stat = SAS_OPEN_REJECT;
ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
if (pm8001_dev) if (pm8001_dev)
pm8001_dev->running_req--; atomic_dec(&pm8001_dev->running_req);
spin_lock_irqsave(&task->task_state_lock, flags1); spin_lock_irqsave(&task->task_state_lock, flags1);
task->task_state_flags &= ~SAS_TASK_STATE_PENDING; task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
......
...@@ -293,7 +293,7 @@ struct pm8001_device { ...@@ -293,7 +293,7 @@ struct pm8001_device {
struct completion *dcompletion; struct completion *dcompletion;
struct completion *setds_completion; struct completion *setds_completion;
u32 device_id; u32 device_id;
u32 running_req; atomic_t running_req;
}; };
struct pm8001_prd_imt { struct pm8001_prd_imt {
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment