diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 9410335caf41a5506ace830bbd356751f08d0928..72c98522bd260eda9439d7a5c7cbb400f643b289 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -98,6 +98,12 @@ struct hisi_sas_cq { int id; }; +struct hisi_sas_dq { + struct hisi_hba *hisi_hba; + int wr_point; + int id; +}; + struct hisi_sas_device { enum sas_device_type dev_type; struct hisi_hba *hisi_hba; @@ -194,6 +200,7 @@ struct hisi_hba { struct Scsi_Host *shost; struct hisi_sas_cq cq[HISI_SAS_MAX_QUEUES]; + struct hisi_sas_dq dq[HISI_SAS_MAX_QUEUES]; struct hisi_sas_phy phy[HISI_SAS_MAX_PHYS]; struct hisi_sas_port port[HISI_SAS_MAX_PHYS]; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 85c73d311e4d75669841be26e2be1ffd9a233d7e..5d5657670d4c1b1edeac076a4e85dd83b7dce91a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1239,11 +1239,16 @@ static int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) for (i = 0; i < hisi_hba->queue_count; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + struct hisi_sas_dq *dq = &hisi_hba->dq[i]; /* Completion queue structure */ cq->id = i; cq->hisi_hba = hisi_hba; + /* Delivery queue structure */ + dq->id = i; + dq->hisi_hba = hisi_hba; + /* Delivery queue */ s = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; hisi_hba->cmd_hdr[i] = dma_alloc_coherent(dev, s, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 3b31b204655960ff0b3fc5883c599ca29b560354..b5374641bdb087f692d1a60558c8f27c25194010 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -875,12 +875,13 @@ static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s) { struct device *dev = &hisi_hba->pdev->dev; + struct hisi_sas_dq *dq; u32 r, w; int queue = hisi_hba->queue; while (1) { - w = hisi_sas_read32_relaxed(hisi_hba, - DLVRY_Q_0_WR_PTR + (queue * 0x14)); + dq = &hisi_hba->dq[queue]; + w = dq->wr_point; r = hisi_sas_read32_relaxed(hisi_hba, DLVRY_Q_0_RD_PTR + (queue * 0x14)); if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { @@ -903,10 +904,11 @@ static void start_delivery_v1_hw(struct hisi_hba *hisi_hba) { int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; + struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue]; - hisi_sas_write32(hisi_hba, - DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), - ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); + dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS; + hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), + dq->wr_point); } static int prep_prd_sge_v1_hw(struct hisi_hba *hisi_hba, diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 11006c99de540b3dae5ef4ffee789ff975ddd1c0..e0c124b6428e519df5ea2ca4833a7c6343e54a96 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -1023,12 +1023,13 @@ static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) static int get_free_slot_v2_hw(struct hisi_hba *hisi_hba, int *q, int *s) { struct device *dev = &hisi_hba->pdev->dev; + struct hisi_sas_dq *dq; u32 r, w; int queue = hisi_hba->queue; while (1) { - w = hisi_sas_read32_relaxed(hisi_hba, - DLVRY_Q_0_WR_PTR + (queue * 0x14)); + dq = &hisi_hba->dq[queue]; + w = dq->wr_point; r = hisi_sas_read32_relaxed(hisi_hba, DLVRY_Q_0_RD_PTR + (queue * 0x14)); if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) { @@ -1051,9 +1052,11 @@ static void start_delivery_v2_hw(struct hisi_hba *hisi_hba) { int dlvry_queue = hisi_hba->slot_prep->dlvry_queue; int dlvry_queue_slot = hisi_hba->slot_prep->dlvry_queue_slot; + struct hisi_sas_dq *dq = &hisi_hba->dq[dlvry_queue]; + dq->wr_point = ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS; hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), - ++dlvry_queue_slot % HISI_SAS_QUEUE_SLOTS); + dq->wr_point); } static int prep_prd_sge_v2_hw(struct hisi_hba *hisi_hba,