summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pm8001/pm8001_hwi.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime@cerno.tech>2021-05-11 13:35:52 +0200
committerMaxime Ripard <maxime@cerno.tech>2021-05-11 13:35:52 +0200
commitc55b44c9386f3ee1b08752638559f19deaf6040d (patch)
treec843a21f45180387fcd9eb2625cc9d1f166a3156 /drivers/scsi/pm8001/pm8001_hwi.c
parentMAINTAINERS: Update my e-mail (diff)
parentLinux 5.13-rc1 (diff)
downloadlinux-c55b44c9386f3ee1b08752638559f19deaf6040d.tar.xz
linux-c55b44c9386f3ee1b08752638559f19deaf6040d.zip
Merge drm/drm-fixes into drm-misc-fixes
Start this new release drm-misc-fixes branch Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/scsi/pm8001/pm8001_hwi.c')
-rw-r--r--drivers/scsi/pm8001/pm8001_hwi.c92
1 files changed, 74 insertions, 18 deletions
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 31e5455d280c..ecd06d2d7e81 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -240,6 +240,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
pm8001_ha->memoryMap.region[ci_offset + i].phys_addr_lo;
pm8001_ha->inbnd_q_tbl[i].ci_virt =
pm8001_ha->memoryMap.region[ci_offset + i].virt_ptr;
+ pm8001_write_32(pm8001_ha->inbnd_q_tbl[i].ci_virt, 0, 0);
offsetib = i * 0x20;
pm8001_ha->inbnd_q_tbl[i].pi_pci_bar =
get_pci_bar_index(pm8001_mr32(addressib,
@@ -268,6 +269,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)
0 | (10 << 16) | (i << 24);
pm8001_ha->outbnd_q_tbl[i].pi_virt =
pm8001_ha->memoryMap.region[pi_offset + i].virt_ptr;
+ pm8001_write_32(pm8001_ha->outbnd_q_tbl[i].pi_virt, 0, 0);
offsetob = i * 0x24;
pm8001_ha->outbnd_q_tbl[i].ci_pci_bar =
get_pci_bar_index(pm8001_mr32(addressob,
@@ -643,7 +645,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
*/
static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
{
- u8 i = 0;
+ u32 i = 0;
u16 deviceid;
pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid);
/* 8081 controllers need BAR shift to access MPI space
@@ -1175,7 +1177,7 @@ void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)
#ifndef PM8001_USE_MSIX
/**
- * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
+ * pm8001_chip_intx_interrupt_enable - enable PM8001 chip interrupt
* @pm8001_ha: our hba card information
*/
static void
@@ -1248,7 +1250,7 @@ pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec)
}
/**
- * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt
+ * pm8001_chip_interrupt_disable - disable PM8001 chip interrupt
* @pm8001_ha: our hba card information
* @vec: unused
*/
@@ -1499,12 +1501,14 @@ void pm8001_work_fn(struct work_struct *work)
* was cancelled. This nullification happens when the device
* goes away.
*/
- pm8001_dev = pw->data; /* Most stash device structure */
- if ((pm8001_dev == NULL)
- || ((pw->handler != IO_XFER_ERROR_BREAK)
- && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) {
- kfree(pw);
- return;
+ if (pw->handler != IO_FATAL_ERROR) {
+ pm8001_dev = pw->data; /* Most stash device structure */
+ if ((pm8001_dev == NULL)
+ || ((pw->handler != IO_XFER_ERROR_BREAK)
+ && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) {
+ kfree(pw);
+ return;
+ }
}
switch (pw->handler) {
@@ -1668,6 +1672,58 @@ void pm8001_work_fn(struct work_struct *work)
dev = pm8001_dev->sas_device;
pm8001_I_T_nexus_reset(dev);
break;
+ case IO_FATAL_ERROR:
+ {
+ struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
+ struct pm8001_ccb_info *ccb;
+ struct task_status_struct *ts;
+ struct sas_task *task;
+ int i;
+ u32 tag, device_id;
+
+ for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+ ccb = &pm8001_ha->ccb_info[i];
+ task = ccb->task;
+ ts = &task->task_status;
+ tag = ccb->ccb_tag;
+ /* check if tag is NULL */
+ if (!tag) {
+ pm8001_dbg(pm8001_ha, FAIL,
+ "tag Null\n");
+ continue;
+ }
+ if (task != NULL) {
+ dev = task->dev;
+ if (!dev) {
+ pm8001_dbg(pm8001_ha, FAIL,
+ "dev is NULL\n");
+ continue;
+ }
+ /*complete sas task and update to top layer */
+ pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+ ts->resp = SAS_TASK_COMPLETE;
+ task->task_done(task);
+ } else if (tag != 0xFFFFFFFF) {
+ /* complete the internal commands/non-sas task */
+ pm8001_dev = ccb->device;
+ if (pm8001_dev->dcompletion) {
+ complete(pm8001_dev->dcompletion);
+ pm8001_dev->dcompletion = NULL;
+ }
+ complete(pm8001_ha->nvmd_completion);
+ pm8001_tag_free(pm8001_ha, tag);
+ }
+ }
+ /* Deregister all the device ids */
+ for (i = 0; i < PM8001_MAX_DEVICES; i++) {
+ pm8001_dev = &pm8001_ha->devices[i];
+ device_id = pm8001_dev->device_id;
+ if (device_id) {
+ PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
+ pm8001_free_dev(pm8001_dev);
+ }
+ }
+ } break;
}
kfree(pw);
}
@@ -1826,7 +1882,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
* that the task has been finished.
*/
static void
-mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
+mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
struct sas_task *t;
struct pm8001_ccb_info *ccb;
@@ -2058,7 +2114,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
}
/*See the comments for mpi_ssp_completion */
-static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
struct sas_task *t;
unsigned long flags;
@@ -2294,9 +2350,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
(status != IO_UNDERFLOW)) {
if (!((t->dev->parent) &&
(dev_is_expander(t->dev->parent->dev_type)))) {
- for (i = 0 , j = 4; j <= 7 && i <= 3; i++ , j++)
+ for (i = 0, j = 4; j <= 7 && i <= 3; i++, j++)
sata_addr_low[i] = pm8001_ha->sas_addr[j];
- for (i = 0 , j = 0; j <= 3 && i <= 3; i++ , j++)
+ for (i = 0, j = 0; j <= 3 && i <= 3; i++, j++)
sata_addr_hi[i] = pm8001_ha->sas_addr[j];
memcpy(&temp_sata_addr_low, sata_addr_low,
sizeof(sata_addr_low));
@@ -2625,7 +2681,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
}
/*See the comments for mpi_ssp_completion */
-static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
struct sas_task *t;
struct task_status_struct *ts;
@@ -3219,7 +3275,7 @@ void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate)
}
/**
- * asd_get_attached_sas_addr -- extract/generate attached SAS address
+ * pm8001_get_attached_sas_addr - extract/generate attached SAS address
* @phy: pointer to asd_phy
* @sas_addr: pointer to buffer where the SAS address is to be written
*
@@ -3546,7 +3602,7 @@ int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
}
/**
- * fw_flash_update_resp - Response from FW for flash update command.
+ * pm8001_mpi_fw_flash_update_resp - Response from FW for flash update command.
* @pm8001_ha: our hba card information
* @piomb: IO message buffer
*/
@@ -3602,7 +3658,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
return 0;
}
-int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
+int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
u32 status;
int i;
@@ -3685,7 +3741,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
* @pm8001_ha: our hba card information
* @piomb: IO message buffer
*/
-static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
+static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
unsigned long flags;
struct hw_event_resp *pPayload =