diff options
Diffstat (limited to 'drivers/scsi/pm8001')
-rw-r--r-- | drivers/scsi/pm8001/pm8001_ctl.c | 7 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_defs.h | 9 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 5 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_init.c | 41 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.c | 100 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_sas.h | 6 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 70 |
7 files changed, 158 insertions, 80 deletions
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 7b27618fd7b2..7618f9cc9986 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -644,7 +644,7 @@ static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); #define FLASH_CMD_SET_NVMD 0x02 struct flash_command { - u8 command[8]; + u8 command[8] __nonstring; int code; }; @@ -1039,3 +1039,8 @@ const struct attribute_group *pm8001_host_groups[] = { &pm8001_host_attr_group, NULL }; + +const struct attribute_group *pm8001_sdev_groups[] = { + &sas_ata_sdev_attr_group, + NULL +}; diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h index 501b574239e8..4e19d61dffbb 100644 --- a/drivers/scsi/pm8001/pm8001_defs.h +++ b/drivers/scsi/pm8001/pm8001_defs.h @@ -90,10 +90,13 @@ enum port_type { #define PM8001_MAX_PORTS 16 /* max. possible ports */ #define PM8001_MAX_DEVICES 2048 /* max supported device */ #define PM8001_MAX_MSIX_VEC 64 /* max msi-x int for spcv/ve */ -#define PM8001_RESERVE_SLOT 8 +#define PM8001_RESERVE_SLOT 128 -#define CONFIG_SCSI_PM8001_MAX_DMA_SG 528 -#define PM8001_MAX_DMA_SG CONFIG_SCSI_PM8001_MAX_DMA_SG +#define PM8001_SECTOR_SIZE 512 +#define PM8001_PAGE_SIZE_4K 4096 +#define PM8001_MAX_IO_SIZE (4 * 1024 * 1024) +#define PM8001_MAX_DMA_SG (PM8001_MAX_IO_SIZE / PM8001_PAGE_SIZE_4K) +#define PM8001_MAX_SECTORS (PM8001_MAX_IO_SIZE / PM8001_SECTOR_SIZE) enum memory_region_num { AAP1 = 0x0, /* application acceleration processor */ diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index dec1e2d380f1..42a4eeac24c9 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3472,12 +3472,13 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) status, tag, scp); switch (status) { case IO_SUCCESS: - pm8001_dbg(pm8001_ha, EH, "IO_SUCCESS\n"); + pm8001_dbg(pm8001_ha, FAIL, "ABORT IO_SUCCESS for tag %#x\n", + tag); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_SAM_STAT_GOOD; break; case IO_NOT_VALID: - pm8001_dbg(pm8001_ha, EH, "IO_NOT_VALID\n"); + pm8001_dbg(pm8001_ha, FAIL, "IO_NOT_VALID for tag %#x\n", tag); ts->resp = TMF_RESP_FUNC_FAILED; break; } diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index ed6b7d954dda..599410bcdfea 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -68,6 +68,10 @@ static bool pm8001_read_wwn = true; module_param_named(read_wwn, pm8001_read_wwn, bool, 0444); MODULE_PARM_DESC(zoned, "Get WWN from the controller. Default: true"); +uint pcs_event_log_severity = 0x03; +module_param(pcs_event_log_severity, int, 0644); +MODULE_PARM_DESC(pcs_event_log_severity, "PCS event log severity level"); + static struct scsi_transport_template *pm8001_stt; static int pm8001_init_ccb_tag(struct pm8001_hba_info *); @@ -100,40 +104,26 @@ static void pm8001_map_queues(struct Scsi_Host *shost) struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; - if (pm8001_ha->number_of_intr > 1) - blk_mq_pci_map_queues(qmap, pm8001_ha->pdev, 1); + if (pm8001_ha->number_of_intr > 1) { + blk_mq_map_hw_queues(qmap, &pm8001_ha->pdev->dev, 1); + return; + } - return blk_mq_map_queues(qmap); + blk_mq_map_queues(qmap); } /* * The main structure which LLDD must register for scsi core. */ static const struct scsi_host_template pm8001_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .proc_name = DRV_NAME, - .queuecommand = sas_queuecommand, - .dma_need_drain = ata_scsi_dma_need_drain, - .target_alloc = sas_target_alloc, - .slave_configure = sas_slave_configure, + LIBSAS_SHT_BASE .scan_finished = pm8001_scan_finished, .scan_start = pm8001_scan_start, - .change_queue_depth = sas_change_queue_depth, - .bios_param = sas_bios_param, .can_queue = 1, - .this_id = -1, .sg_tablesize = PM8001_MAX_DMA_SG, - .max_sectors = SCSI_DEFAULT_MAX_SECTORS, - .eh_device_reset_handler = sas_eh_device_reset_handler, - .eh_target_reset_handler = sas_eh_target_reset_handler, - .slave_alloc = sas_slave_alloc, - .target_destroy = sas_target_destroy, - .ioctl = sas_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sas_ioctl, -#endif + .max_sectors = PM8001_MAX_SECTORS, .shost_groups = pm8001_host_groups, + .sdev_groups = pm8001_sdev_groups, .track_queue_depth = 1, .cmd_per_lun = 32, .map_queues = pm8001_map_queues, @@ -462,9 +452,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, } for (i = 0; i < PM8001_MAX_DEVICES; i++) { pm8001_ha->devices[i].dev_type = SAS_PHY_UNUSED; - pm8001_ha->devices[i].id = i; - pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES; - atomic_set(&pm8001_ha->devices[i].running_req, 0); } pm8001_ha->flags = PM8001F_INIT_TIME; return 0; @@ -749,7 +736,7 @@ static int pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) return -EIO; } time_remaining = wait_for_completion_timeout(&completion, - msecs_to_jiffies(60*1000)); // 1 min + secs_to_jiffies(60)); // 1 min if (!time_remaining) { kfree(payload.func_specific); pm8001_dbg(pm8001_ha, FAIL, "get_nvmd_req timeout\n"); @@ -1448,7 +1435,7 @@ err_out_disable: /* update of pci device, vendor id and driver data with * unique value for each of the controller */ -static struct pci_device_id pm8001_pci_table[] = { +static const struct pci_device_id pm8001_pci_table[] = { { PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001 }, { PCI_VDEVICE(PMC_Sierra, 0x8006), chip_8006 }, { PCI_VDEVICE(ADAPTEC2, 0x8006), chip_8006 }, diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a5a31dfa4512..f7067878b34f 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -101,6 +101,63 @@ int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out) return 0; } +static void pm80xx_get_tag_opcodes(struct sas_task *task, int *ata_op, + int *ata_tag, bool *task_aborted) +{ + unsigned long flags; + struct ata_queued_cmd *qc = NULL; + + *ata_op = 0; + *ata_tag = -1; + *task_aborted = false; + + if (!task) + return; + + spin_lock_irqsave(&task->task_state_lock, flags); + if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) + *task_aborted = true; + spin_unlock_irqrestore(&task->task_state_lock, flags); + + if (task->task_proto == SAS_PROTOCOL_STP) { + // sas_ata_qc_issue path uses SAS_PROTOCOL_STP. + // This only works for scsi + libsas + libata users. + qc = task->uldd_task; + if (qc) { + *ata_op = qc->tf.command; + *ata_tag = qc->tag; + } + } +} + +void pm80xx_show_pending_commands(struct pm8001_hba_info *pm8001_ha, + struct pm8001_device *target_pm8001_dev) +{ + int i = 0, ata_op = 0, ata_tag = -1; + struct pm8001_ccb_info *ccb = NULL; + struct sas_task *task = NULL; + struct pm8001_device *pm8001_dev = NULL; + bool task_aborted; + + for (i = 0; i < pm8001_ha->ccb_count; i++) { + ccb = &pm8001_ha->ccb_info[i]; + if (ccb->ccb_tag == PM8001_INVALID_TAG) + continue; + pm8001_dev = ccb->device; + if (target_pm8001_dev && pm8001_dev && + target_pm8001_dev != pm8001_dev) + continue; + task = ccb->task; + pm80xx_get_tag_opcodes(task, &ata_op, &ata_tag, &task_aborted); + pm8001_dbg(pm8001_ha, FAIL, + "tag %#x, device %#x task %p task aborted %d ata opcode %#x ata tag %d\n", + ccb->ccb_tag, + (pm8001_dev ? pm8001_dev->device_id : 0), + task, task_aborted, + ata_op, ata_tag); + } +} + /** * pm8001_mem_alloc - allocate memory for pm8001. * @pdev: pci device. @@ -166,7 +223,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, unsigned long flags; pm8001_ha = sas_phy->ha->lldd_ha; phy = &pm8001_ha->phy[phy_id]; - pm8001_ha->phy[phy_id].enable_completion = &completion; if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) { /* @@ -190,6 +246,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, rates->maximum_linkrate; } if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); } @@ -198,6 +255,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_HARD_RESET: if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); } @@ -206,6 +264,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_LINK_RESET: if (pm8001_ha->phy[phy_id].phy_state == PHY_LINK_DISABLE) { + pm8001_ha->phy[phy_id].enable_completion = &completion; PM8001_CHIP_DISP->phy_start_req(pm8001_ha, phy_id); wait_for_completion(&completion); } @@ -372,23 +431,6 @@ static int pm8001_task_prep_ssp(struct pm8001_hba_info *pm8001_ha, return PM8001_CHIP_DISP->ssp_io_req(pm8001_ha, ccb); } - /* Find the local port id that's attached to this device */ -static int sas_find_local_port_id(struct domain_device *dev) -{ - struct domain_device *pdev = dev->parent; - - /* Directly attached device */ - if (!pdev) - return dev->port->id; - while (pdev) { - struct domain_device *pdev_p = pdev->parent; - if (!pdev_p) - return pdev->port->id; - pdev = pdev->parent; - } - return 0; -} - #define DEV_IS_GONE(pm8001_dev) \ ((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))) @@ -461,10 +503,10 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) spin_lock_irqsave(&pm8001_ha->lock, flags); pm8001_dev = dev->lldd_dev; - port = &pm8001_ha->port[sas_find_local_port_id(dev)]; + port = pm8001_ha->phy[pm8001_dev->attached_phy].port; if (!internal_abort && - (DEV_IS_GONE(pm8001_dev) || !port->port_attached)) { + (DEV_IS_GONE(pm8001_dev) || !port || !port->port_attached)) { ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_PHY_DOWN; if (sas_protocol_ata(task_proto)) { @@ -570,6 +612,13 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha, pm8001_ccb_free(pm8001_ha, ccb); } +static void pm8001_init_dev(struct pm8001_device *pm8001_dev, int id) +{ + pm8001_dev->id = id; + pm8001_dev->device_id = PM8001_MAX_DEVICES; + atomic_set(&pm8001_dev->running_req, 0); +} + /** * pm8001_alloc_dev - find a empty pm8001_device * @pm8001_ha: our hba card information @@ -578,9 +627,11 @@ static struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha) { u32 dev; for (dev = 0; dev < PM8001_MAX_DEVICES; dev++) { - if (pm8001_ha->devices[dev].dev_type == SAS_PHY_UNUSED) { - pm8001_ha->devices[dev].id = dev; - return &pm8001_ha->devices[dev]; + struct pm8001_device *pm8001_dev = &pm8001_ha->devices[dev]; + + if (pm8001_dev->dev_type == SAS_PHY_UNUSED) { + pm8001_init_dev(pm8001_dev, dev); + return pm8001_dev; } } if (dev == PM8001_MAX_DEVICES) { @@ -611,9 +662,7 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, void pm8001_free_dev(struct pm8001_device *pm8001_dev) { - u32 id = pm8001_dev->id; memset(pm8001_dev, 0, sizeof(*pm8001_dev)); - pm8001_dev->id = id; pm8001_dev->dev_type = SAS_PHY_UNUSED; pm8001_dev->device_id = PM8001_MAX_DEVICES; pm8001_dev->sas_device = NULL; @@ -717,6 +766,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) spin_lock_irqsave(&pm8001_ha->lock, flags); } PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); + pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; pm8001_free_dev(pm8001_dev); } else { pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n"); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 3ccb7371902f..315f6a7523f0 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -56,7 +56,6 @@ #include <scsi/sas_ata.h> #include <linux/atomic.h> #include <linux/blk-mq.h> -#include <linux/blk-mq-pci.h> #include "pm8001_defs.h" #define DRV_NAME "pm80xx" @@ -96,6 +95,8 @@ extern struct list_head hba_list; extern const struct pm8001_dispatch pm8001_8001_dispatch; extern const struct pm8001_dispatch pm8001_80xx_dispatch; +extern uint pcs_event_log_severity; + struct pm8001_hba_info; struct pm8001_ccb_info; struct pm8001_device; @@ -717,6 +718,7 @@ int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha); void pm8001_free_dev(struct pm8001_device *pm8001_dev); /* ctl shared API */ extern const struct attribute_group *pm8001_host_groups[]; +extern const struct attribute_group *pm8001_sdev_groups[]; #define PM8001_INVALID_TAG ((u32)-1) @@ -784,6 +786,8 @@ static inline void pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, } void pm8001_setds_completion(struct domain_device *dev); void pm8001_tmf_aborted(struct sas_task *task); +void pm80xx_show_pending_commands(struct pm8001_hba_info *pm8001_ha, + struct pm8001_device *dev); #endif diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index a52ae6841939..5b373c53c036 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -568,13 +568,13 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version = pm8001_mr32(address, MAIN_MPI_INACTIVE_FW_VERSION); - pm8001_dbg(pm8001_ha, DEV, + pm8001_dbg(pm8001_ha, INIT, "Main cfg table: sign:%x interface rev:%x fw_rev:%x\n", pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature, pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev, pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev); - pm8001_dbg(pm8001_ha, DEV, + pm8001_dbg(pm8001_ha, INIT, "table offset: gst:%x iq:%x oq:%x int vec:%x phy attr:%x\n", pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset, pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset, @@ -582,7 +582,7 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset, pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset); - pm8001_dbg(pm8001_ha, DEV, + pm8001_dbg(pm8001_ha, INIT, "Main cfg table; ila rev:%x Inactive fw rev:%x\n", pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version, pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version); @@ -763,7 +763,8 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->memoryMap.region[IOP].phys_addr_lo; pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_size = PM8001_EVENT_LOG_SIZE; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity = 0x01; + pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity = + pcs_event_log_severity; pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt = 0x01; /* Enable higher IQs and OQs, 32 to 63, bit 16 */ @@ -2037,7 +2038,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) atomic_dec(&pm8001_dev->running_req); break; } - pm8001_dbg(pm8001_ha, IO, "scsi_status = 0x%x\n ", + pm8001_dbg(pm8001_ha, IO, "scsi_status = 0x%x\n", psspPayload->ssp_resp_iu.status); spin_lock_irqsave(&t->task_state_lock, flags); t->task_state_flags &= ~SAS_TASK_STATE_PENDING; @@ -2245,7 +2246,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, u32 param; u32 status; u32 tag; - int i, j; + int i, j, ata_tag = -1; u8 sata_addr_low[4]; u32 temp_sata_addr_low, temp_sata_addr_hi; u8 sata_addr_hi[4]; @@ -2255,6 +2256,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, u32 *sata_resp; struct pm8001_device *pm8001_dev; unsigned long flags; + struct ata_queued_cmd *qc; psataPayload = (struct sata_completion_resp *)(piomb + 4); status = le32_to_cpu(psataPayload->status); @@ -2266,8 +2268,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, pm8001_dev = ccb->device; if (t) { - if (t->dev && (t->dev->lldd_dev)) + if (t->dev && (t->dev->lldd_dev)) { pm8001_dev = t->dev->lldd_dev; + qc = t->uldd_task; + ata_tag = qc ? qc->tag : -1; + } } else { pm8001_dbg(pm8001_ha, FAIL, "task null, freeing CCB tag %d\n", ccb->ccb_tag); @@ -2275,16 +2280,14 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, return; } - if (pm8001_dev && unlikely(!t->lldd_task || !t->dev)) return; ts = &t->task_status; - if (status != IO_SUCCESS) { pm8001_dbg(pm8001_ha, FAIL, - "IO failed device_id %u status 0x%x tag %d\n", - pm8001_dev->device_id, status, tag); + "IO failed status %#x pm80xx tag %#x ata tag %d\n", + status, tag, ata_tag); } /* Print sas address of IO failed device */ @@ -2666,13 +2669,19 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, /* Check if this is NCQ error */ if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) { + /* tag value is invalid with this event */ + pm8001_dbg(pm8001_ha, FAIL, "NCQ ERROR for device %#x tag %#x\n", + dev_id, tag); + /* find device using device id */ pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id); /* send read log extension by aborting the link - libata does what we want */ - if (pm8001_dev) + if (pm8001_dev) { + pm80xx_show_pending_commands(pm8001_ha, pm8001_dev); pm8001_handle_event(pm8001_ha, pm8001_dev, IO_XFER_ERROR_ABORTED_NCQ_MODE); + } return; } @@ -3335,10 +3344,11 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 phy_id = le32_to_cpu(pPayload->phyid) & 0xFF; struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; + u32 tag = le32_to_cpu(pPayload->tag); pm8001_dbg(pm8001_ha, INIT, - "phy start resp status:0x%x, phyid:0x%x\n", - status, phy_id); + "phy start resp status:0x%x, phyid:0x%x, tag 0x%x\n", + status, phy_id, tag); if (status == 0) phy->phy_state = PHY_LINK_DOWN; @@ -3347,6 +3357,8 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) complete(phy->enable_completion); phy->enable_completion = NULL; } + + pm8001_tag_free(pm8001_ha, tag); return 0; } @@ -3627,8 +3639,10 @@ static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 phyid = le32_to_cpu(pPayload->phyid) & 0xFF; struct pm8001_phy *phy = &pm8001_ha->phy[phyid]; - pm8001_dbg(pm8001_ha, MSG, "phy:0x%x status:0x%x\n", - phyid, status); + u32 tag = le32_to_cpu(pPayload->tag); + + pm8001_dbg(pm8001_ha, MSG, "phy:0x%x status:0x%x tag 0x%x\n", phyid, + status, tag); if (status == PHY_STOP_SUCCESS || status == PHY_STOP_ERR_DEVICE_ATTACHED) { phy->phy_state = PHY_LINK_DISABLE; @@ -3636,6 +3650,7 @@ static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) phy->sas_phy.linkrate = SAS_PHY_DISABLED; } + pm8001_tag_free(pm8001_ha, tag); return 0; } @@ -3654,10 +3669,9 @@ static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, u32 tag = le32_to_cpu(pPayload->tag); pm8001_dbg(pm8001_ha, MSG, - "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", - status, err_qlfr_pgcd); + "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x tag 0x%x\n", + status, err_qlfr_pgcd, tag); pm8001_tag_free(pm8001_ha, tag); - return 0; } @@ -4631,9 +4645,16 @@ static int pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) { struct phy_start_req payload; - u32 tag = 0x01; + int ret; + u32 tag; u32 opcode = OPC_INB_PHYSTART; + ret = pm8001_tag_alloc(pm8001_ha, &tag); + if (ret) { + pm8001_dbg(pm8001_ha, FAIL, "Tag allocation failed\n"); + return ret; + } + memset(&payload, 0, sizeof(payload)); payload.tag = cpu_to_le32(tag); @@ -4669,9 +4690,16 @@ static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) { struct phy_stop_req payload; - u32 tag = 0x01; + int ret; + u32 tag; u32 opcode = OPC_INB_PHYSTOP; + ret = pm8001_tag_alloc(pm8001_ha, &tag); + if (ret) { + pm8001_dbg(pm8001_ha, FAIL, "Tag allocation failed\n"); + return ret; + } + memset(&payload, 0, sizeof(payload)); payload.tag = cpu_to_le32(tag); payload.phy_id = cpu_to_le32(phy_id); |