Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: pm8001: Introduce ccb alloc/free helpers

Introduce the pm8001_ccb_alloc() and pm8001_ccb_free() helpers to replace
the typical code patterns:

res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
if (res)
...
ccb = &pm8001_ha->ccb_info[ccb_tag];
ccb->device = pm8001_ha_dev;
ccb->ccb_tag = ccb_tag;
ccb->task = task;
ccb->n_elem = 0;

and

ccb->task = NULL;
ccb->ccb_tag = PM8001_INVALID_TAG;
pm8001_tag_free(pm8001_ha, tag);

With the simpler function calls:

ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
if (!ccb)
...

and

pm8001_ccb_free(pm8001_ha, ccb);

The pm8001_ccb_alloc() helper ensures that all fields of the ccb info
structure for the newly allocated tag are all initialized, except the
buf_prd field. The pm8001_ccb_free() helper clears the initialized fields
and the ccb tag to ensure that iteration over the adapter ccb_info array
detects ccbs that are in use.

All call site of the pm8001_tag_alloc() function that use a ccb info
associated with an allocated tag are converted to use the new helpers.

Link: https://lore.kernel.org/r/20220220031810.738362-27-damien.lemoal@opensource.wdc.com
Reviewed-by: John Garry <john.garry@huawei.com>
Reviewed-by: Jack Wang <jinpu.wang@ionos.com>
Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Damien Le Moal and committed by
Martin K. Petersen
99df0edb bf67e693

+166 -171
+76 -104
drivers/scsi/pm8001/pm8001_hwi.c
··· 1710 1710 pm8001_dev->dcompletion = NULL; 1711 1711 } 1712 1712 complete(pm8001_ha->nvmd_completion); 1713 - pm8001_tag_free(pm8001_ha, ccb->ccb_tag); 1713 + pm8001_ccb_free(pm8001_ha, ccb); 1714 1714 } 1715 1715 } 1716 1716 /* Deregister all the device ids */ ··· 1749 1749 static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, 1750 1750 struct pm8001_device *pm8001_ha_dev) 1751 1751 { 1752 - int res; 1753 - u32 ccb_tag; 1754 1752 struct pm8001_ccb_info *ccb; 1755 1753 struct sas_task *task = NULL; 1756 1754 struct task_abort_req task_abort; ··· 1769 1771 1770 1772 task->task_done = pm8001_task_done; 1771 1773 1772 - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); 1773 - if (res) { 1774 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task); 1775 + if (!ccb) { 1774 1776 sas_free_task(task); 1775 1777 return; 1776 1778 } 1777 - 1778 - ccb = &pm8001_ha->ccb_info[ccb_tag]; 1779 - ccb->device = pm8001_ha_dev; 1780 - ccb->ccb_tag = ccb_tag; 1781 - ccb->task = task; 1782 - ccb->n_elem = 0; 1783 1779 1784 1780 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 1785 1781 1786 1782 memset(&task_abort, 0, sizeof(task_abort)); 1787 1783 task_abort.abort_all = cpu_to_le32(1); 1788 1784 task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id); 1789 - task_abort.tag = cpu_to_le32(ccb_tag); 1785 + task_abort.tag = cpu_to_le32(ccb->ccb_tag); 1790 1786 1791 1787 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 1792 1788 sizeof(task_abort), 0); 1793 1789 if (ret) { 1794 1790 sas_free_task(task); 1795 - pm8001_tag_free(pm8001_ha, ccb_tag); 1791 + pm8001_ccb_free(pm8001_ha, ccb); 1796 1792 } 1797 - 1798 1793 } 1799 1794 1800 1795 static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, ··· 1795 1804 { 1796 1805 struct sata_start_req sata_cmd; 1797 1806 int res; 1798 - u32 ccb_tag; 1799 1807 struct pm8001_ccb_info *ccb; 1800 1808 struct sas_task *task = NULL; 1801 1809 struct host_to_dev_fis fis; ··· 1810 1820 } 1811 1821 task->task_done = pm8001_task_done; 1812 1822 1813 - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); 1814 - if (res) { 1815 - sas_free_task(task); 1816 - pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n"); 1817 - return; 1818 - } 1819 - 1820 - /* allocate domain device by ourselves as libsas 1821 - * is not going to provide any 1822 - */ 1823 + /* 1824 + * Allocate domain device by ourselves as libsas is not going to 1825 + * provide any. 1826 + */ 1823 1827 dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); 1824 1828 if (!dev) { 1825 1829 sas_free_task(task); 1826 - pm8001_tag_free(pm8001_ha, ccb_tag); 1827 1830 pm8001_dbg(pm8001_ha, FAIL, 1828 1831 "Domain device cannot be allocated\n"); 1829 1832 return; ··· 1824 1841 task->dev = dev; 1825 1842 task->dev->lldd_dev = pm8001_ha_dev; 1826 1843 1827 - ccb = &pm8001_ha->ccb_info[ccb_tag]; 1828 - ccb->device = pm8001_ha_dev; 1829 - ccb->ccb_tag = ccb_tag; 1830 - ccb->task = task; 1831 - ccb->n_elem = 0; 1844 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task); 1845 + if (!ccb) { 1846 + sas_free_task(task); 1847 + kfree(dev); 1848 + return; 1849 + } 1850 + 1832 1851 pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG; 1833 1852 pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG; 1834 1853 ··· 1845 1860 fis.lbal = 0x10; 1846 1861 fis.sector_count = 0x1; 1847 1862 1848 - sata_cmd.tag = cpu_to_le32(ccb_tag); 1863 + sata_cmd.tag = cpu_to_le32(ccb->ccb_tag); 1849 1864 sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); 1850 1865 sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9)); 1851 1866 memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); ··· 1854 1869 sizeof(sata_cmd), 0); 1855 1870 if (res) { 1856 1871 sas_free_task(task); 1857 - pm8001_tag_free(pm8001_ha, ccb_tag); 1872 + pm8001_ccb_free(pm8001_ha, ccb); 1858 1873 kfree(dev); 1859 1874 } 1860 1875 } ··· 3023 3038 u32 device_id = le32_to_cpu(pPayload->device_id); 3024 3039 u8 pds = le32_to_cpu(pPayload->pds_nds) & PDS_BITS; 3025 3040 u8 nds = le32_to_cpu(pPayload->pds_nds) & NDS_BITS; 3026 - pm8001_dbg(pm8001_ha, MSG, "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n", 3041 + 3042 + pm8001_dbg(pm8001_ha, MSG, 3043 + "Set device id = 0x%x state from 0x%x to 0x%x status = 0x%x!\n", 3027 3044 device_id, pds, nds, status); 3028 3045 complete(pm8001_dev->setds_completion); 3029 - ccb->task = NULL; 3030 - ccb->ccb_tag = PM8001_INVALID_TAG; 3031 - pm8001_tag_free(pm8001_ha, tag); 3046 + pm8001_ccb_free(pm8001_ha, ccb); 3032 3047 } 3033 3048 3034 3049 void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) ··· 3038 3053 u32 tag = le32_to_cpu(pPayload->tag); 3039 3054 struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; 3040 3055 u32 dlen_status = le32_to_cpu(pPayload->dlen_status); 3056 + 3041 3057 complete(pm8001_ha->nvmd_completion); 3042 3058 pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); 3043 3059 if ((dlen_status & NVMD_STAT) != 0) { 3044 3060 pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n", 3045 3061 dlen_status); 3046 3062 } 3047 - ccb->task = NULL; 3048 - ccb->ccb_tag = PM8001_INVALID_TAG; 3049 - pm8001_tag_free(pm8001_ha, tag); 3063 + pm8001_ccb_free(pm8001_ha, ccb); 3050 3064 } 3051 3065 3052 3066 void ··· 3070 3086 /* We should free tag during failure also, the tag is not being 3071 3087 * freed by requesting path anywhere. 3072 3088 */ 3073 - ccb->task = NULL; 3074 - ccb->ccb_tag = PM8001_INVALID_TAG; 3075 - pm8001_tag_free(pm8001_ha, tag); 3089 + pm8001_ccb_free(pm8001_ha, ccb); 3076 3090 return; 3077 3091 } 3078 3092 if (ir_tds_bn_dps_das_nvm & IPMode) { ··· 3114 3132 */ 3115 3133 complete(pm8001_ha->nvmd_completion); 3116 3134 pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n"); 3117 - ccb->task = NULL; 3118 - ccb->ccb_tag = PM8001_INVALID_TAG; 3119 - pm8001_tag_free(pm8001_ha, tag); 3135 + pm8001_ccb_free(pm8001_ha, ccb); 3120 3136 } 3121 3137 3122 3138 int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) ··· 3525 3545 break; 3526 3546 } 3527 3547 complete(pm8001_dev->dcompletion); 3528 - ccb->task = NULL; 3529 - ccb->ccb_tag = PM8001_INVALID_TAG; 3530 - pm8001_tag_free(pm8001_ha, htag); 3548 + pm8001_ccb_free(pm8001_ha, ccb); 3531 3549 return 0; 3532 3550 } 3533 3551 ··· 3558 3580 (struct fw_flash_Update_resp *)(piomb + 4); 3559 3581 u32 tag = le32_to_cpu(ppayload->tag); 3560 3582 struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; 3583 + 3561 3584 status = le32_to_cpu(ppayload->status); 3562 3585 switch (status) { 3563 3586 case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: ··· 3596 3617 break; 3597 3618 } 3598 3619 kfree(ccb->fw_control_context); 3599 - ccb->task = NULL; 3600 - ccb->ccb_tag = PM8001_INVALID_TAG; 3601 - pm8001_tag_free(pm8001_ha, tag); 3620 + pm8001_ccb_free(pm8001_ha, ccb); 3602 3621 complete(pm8001_ha->nvmd_completion); 3603 3622 return 0; 3604 3623 } ··· 4389 4412 u32 stp_sspsmp_sata = 0x4; 4390 4413 struct inbound_queue_table *circularQ; 4391 4414 u32 linkrate, phy_id; 4392 - int rc, tag = 0xdeadbeef; 4415 + int rc; 4393 4416 struct pm8001_ccb_info *ccb; 4394 4417 u8 retryFlag = 0x1; 4395 4418 u16 firstBurstSize = 0; ··· 4400 4423 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 4401 4424 4402 4425 memset(&payload, 0, sizeof(payload)); 4403 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4404 - if (rc) 4405 - return rc; 4406 - ccb = &pm8001_ha->ccb_info[tag]; 4407 - ccb->device = pm8001_dev; 4408 - ccb->ccb_tag = tag; 4409 - payload.tag = cpu_to_le32(tag); 4426 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL); 4427 + if (!ccb) 4428 + return -SAS_QUEUE_FULL; 4429 + 4430 + payload.tag = cpu_to_le32(ccb->ccb_tag); 4410 4431 if (flag == 1) 4411 4432 stp_sspsmp_sata = 0x02; /*direct attached sata */ 4412 4433 else { ··· 4434 4459 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 4435 4460 sizeof(payload), 0); 4436 4461 if (rc) 4437 - pm8001_tag_free(pm8001_ha, tag); 4462 + pm8001_ccb_free(pm8001_ha, ccb); 4438 4463 4439 4464 return rc; 4440 4465 } ··· 4599 4624 u32 opc = OPC_INB_GET_NVMD_DATA; 4600 4625 u32 nvmd_type; 4601 4626 int rc; 4602 - u32 tag; 4603 4627 struct pm8001_ccb_info *ccb; 4604 4628 struct inbound_queue_table *circularQ; 4605 4629 struct get_nvm_data_req nvmd_req; ··· 4613 4639 fw_control_context->len = ioctl_payload->rd_length; 4614 4640 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 4615 4641 memset(&nvmd_req, 0, sizeof(nvmd_req)); 4616 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4617 - if (rc) { 4642 + 4643 + ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL); 4644 + if (!ccb) { 4618 4645 kfree(fw_control_context); 4619 - return rc; 4646 + return -SAS_QUEUE_FULL; 4620 4647 } 4621 - ccb = &pm8001_ha->ccb_info[tag]; 4622 - ccb->ccb_tag = tag; 4623 4648 ccb->fw_control_context = fw_control_context; 4624 - nvmd_req.tag = cpu_to_le32(tag); 4649 + 4650 + nvmd_req.tag = cpu_to_le32(ccb->ccb_tag); 4625 4651 4626 4652 switch (nvmd_type) { 4627 4653 case TWI_DEVICE: { ··· 4682 4708 sizeof(nvmd_req), 0); 4683 4709 if (rc) { 4684 4710 kfree(fw_control_context); 4685 - pm8001_tag_free(pm8001_ha, tag); 4711 + pm8001_ccb_free(pm8001_ha, ccb); 4686 4712 } 4687 4713 return rc; 4688 4714 } ··· 4693 4719 u32 opc = OPC_INB_SET_NVMD_DATA; 4694 4720 u32 nvmd_type; 4695 4721 int rc; 4696 - u32 tag; 4697 4722 struct pm8001_ccb_info *ccb; 4698 4723 struct inbound_queue_table *circularQ; 4699 4724 struct set_nvm_data_req nvmd_req; ··· 4708 4735 &ioctl_payload->func_specific, 4709 4736 ioctl_payload->wr_length); 4710 4737 memset(&nvmd_req, 0, sizeof(nvmd_req)); 4711 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4712 - if (rc) { 4738 + 4739 + ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL); 4740 + if (!ccb) { 4713 4741 kfree(fw_control_context); 4714 - return -EBUSY; 4742 + return -SAS_QUEUE_FULL; 4715 4743 } 4716 - ccb = &pm8001_ha->ccb_info[tag]; 4717 4744 ccb->fw_control_context = fw_control_context; 4718 - ccb->ccb_tag = tag; 4719 - nvmd_req.tag = cpu_to_le32(tag); 4745 + 4746 + nvmd_req.tag = cpu_to_le32(ccb->ccb_tag); 4720 4747 switch (nvmd_type) { 4721 4748 case TWI_DEVICE: { 4722 4749 u32 twi_addr, twi_page_size; ··· 4766 4793 sizeof(nvmd_req), 0); 4767 4794 if (rc) { 4768 4795 kfree(fw_control_context); 4769 - pm8001_tag_free(pm8001_ha, tag); 4796 + pm8001_ccb_free(pm8001_ha, ccb); 4770 4797 } 4771 4798 return rc; 4772 4799 } ··· 4812 4839 struct fw_control_info *fw_control; 4813 4840 struct fw_control_ex *fw_control_context; 4814 4841 int rc; 4815 - u32 tag; 4816 4842 struct pm8001_ccb_info *ccb; 4817 4843 void *buffer = pm8001_ha->memoryMap.region[FW_FLASH].virt_ptr; 4818 4844 dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr; ··· 4835 4863 fw_control_context->virtAddr = buffer; 4836 4864 fw_control_context->phys_addr = phys_addr; 4837 4865 fw_control_context->len = fw_control->len; 4838 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4839 - if (rc) { 4866 + 4867 + ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL); 4868 + if (!ccb) { 4840 4869 kfree(fw_control_context); 4841 - return -EBUSY; 4870 + return -SAS_QUEUE_FULL; 4842 4871 } 4843 - ccb = &pm8001_ha->ccb_info[tag]; 4844 4872 ccb->fw_control_context = fw_control_context; 4845 - ccb->ccb_tag = tag; 4873 + 4846 4874 rc = pm8001_chip_fw_flash_update_build(pm8001_ha, &flash_update_info, 4847 - tag); 4875 + ccb->ccb_tag); 4848 4876 if (rc) { 4849 4877 kfree(fw_control_context); 4850 - pm8001_tag_free(pm8001_ha, tag); 4878 + pm8001_ccb_free(pm8001_ha, ccb); 4851 4879 } 4852 4880 4853 4881 return rc; ··· 4939 4967 struct inbound_queue_table *circularQ; 4940 4968 struct pm8001_ccb_info *ccb; 4941 4969 int rc; 4942 - u32 tag; 4943 4970 u32 opc = OPC_INB_SET_DEVICE_STATE; 4971 + 4944 4972 memset(&payload, 0, sizeof(payload)); 4945 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4946 - if (rc) 4947 - return -1; 4948 - ccb = &pm8001_ha->ccb_info[tag]; 4949 - ccb->ccb_tag = tag; 4950 - ccb->device = pm8001_dev; 4973 + 4974 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL); 4975 + if (!ccb) 4976 + return -SAS_QUEUE_FULL; 4977 + 4951 4978 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 4952 - payload.tag = cpu_to_le32(tag); 4979 + payload.tag = cpu_to_le32(ccb->ccb_tag); 4953 4980 payload.device_id = cpu_to_le32(pm8001_dev->device_id); 4954 4981 payload.nds = cpu_to_le32(state); 4982 + 4955 4983 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 4956 4984 sizeof(payload), 0); 4957 4985 if (rc) 4958 - pm8001_tag_free(pm8001_ha, tag); 4986 + pm8001_ccb_free(pm8001_ha, ccb); 4959 4987 4960 4988 return rc; 4961 - 4962 4989 } 4963 4990 4964 4991 static int ··· 4967 4996 struct inbound_queue_table *circularQ; 4968 4997 struct pm8001_ccb_info *ccb; 4969 4998 int rc; 4970 - u32 tag; 4971 4999 u32 opc = OPC_INB_SAS_RE_INITIALIZE; 5000 + 4972 5001 memset(&payload, 0, sizeof(payload)); 4973 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4974 - if (rc) 4975 - return -ENOMEM; 4976 - ccb = &pm8001_ha->ccb_info[tag]; 4977 - ccb->ccb_tag = tag; 5002 + 5003 + ccb = pm8001_ccb_alloc(pm8001_ha, NULL, NULL); 5004 + if (!ccb) 5005 + return -SAS_QUEUE_FULL; 5006 + 4978 5007 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 4979 - payload.tag = cpu_to_le32(tag); 5008 + payload.tag = cpu_to_le32(ccb->ccb_tag); 4980 5009 payload.SSAHOLT = cpu_to_le32(0xd << 25); 4981 5010 payload.sata_hol_tmo = cpu_to_le32(80); 4982 5011 payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff); 5012 + 4983 5013 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 4984 5014 sizeof(payload), 0); 4985 5015 if (rc) 4986 - pm8001_tag_free(pm8001_ha, tag); 4987 - return rc; 5016 + pm8001_ccb_free(pm8001_ha, ccb); 4988 5017 5018 + return rc; 4989 5019 } 4990 5020 4991 5021 const struct pm8001_dispatch pm8001_8001_dispatch = {
+19 -27
drivers/scsi/pm8001/pm8001_sas.c
··· 74 74 * @pm8001_ha: our hba struct 75 75 * @tag_out: the found empty tag . 76 76 */ 77 - inline int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out) 77 + int pm8001_tag_alloc(struct pm8001_hba_info *pm8001_ha, u32 *tag_out) 78 78 { 79 79 unsigned int tag; 80 80 void *bitmap = pm8001_ha->tags; ··· 381 381 struct pm8001_port *port = NULL; 382 382 struct sas_task *t = task; 383 383 struct pm8001_ccb_info *ccb; 384 - u32 tag = 0xdeadbeef, rc = 0, n_elem = 0; 384 + u32 rc = 0, n_elem = 0; 385 385 unsigned long flags = 0; 386 386 enum sas_protocol task_proto = t->task_proto; 387 387 struct sas_tmf_task *tmf = task->tmf; ··· 427 427 continue; 428 428 } 429 429 } 430 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 431 - if (rc) 430 + 431 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, t); 432 + if (!ccb) { 433 + rc = -SAS_QUEUE_FULL; 432 434 goto err_out; 433 - ccb = &pm8001_ha->ccb_info[tag]; 435 + } 434 436 435 437 if (!sas_protocol_ata(task_proto)) { 436 438 if (t->num_scatter) { ··· 442 440 t->data_dir); 443 441 if (!n_elem) { 444 442 rc = -ENOMEM; 445 - goto err_out_tag; 443 + goto err_out_ccb; 446 444 } 447 445 } 448 446 } else { ··· 451 449 452 450 t->lldd_task = ccb; 453 451 ccb->n_elem = n_elem; 454 - ccb->ccb_tag = tag; 455 - ccb->task = t; 456 - ccb->device = pm8001_dev; 452 + 457 453 switch (task_proto) { 458 454 case SAS_PROTOCOL_SMP: 459 455 atomic_inc(&pm8001_dev->running_req); ··· 480 480 if (rc) { 481 481 pm8001_dbg(pm8001_ha, IO, "rc is %x\n", rc); 482 482 atomic_dec(&pm8001_dev->running_req); 483 - goto err_out_tag; 483 + goto err_out_ccb; 484 484 } 485 485 /* TODO: select normal or high priority */ 486 486 } while (0); 487 487 rc = 0; 488 488 goto out_done; 489 489 490 - err_out_tag: 491 - pm8001_tag_free(pm8001_ha, tag); 490 + err_out_ccb: 491 + pm8001_ccb_free(pm8001_ha, ccb); 492 492 err_out: 493 493 dev_printk(KERN_ERR, pm8001_ha->dev, "pm8001 exec failed[%d]!\n", rc); 494 494 if (!sas_protocol_ata(task_proto)) ··· 548 548 } 549 549 550 550 task->lldd_task = NULL; 551 - ccb->task = NULL; 552 - ccb->ccb_tag = PM8001_INVALID_TAG; 553 - ccb->open_retry = 0; 554 - pm8001_tag_free(pm8001_ha, ccb_idx); 551 + pm8001_ccb_free(pm8001_ha, ccb); 555 552 } 556 553 557 554 /** ··· 704 707 u32 task_tag) 705 708 { 706 709 int res, retry; 707 - u32 ccb_tag; 708 710 struct pm8001_ccb_info *ccb; 709 711 struct sas_task *task = NULL; 710 712 ··· 720 724 jiffies + PM8001_TASK_TIMEOUT * HZ; 721 725 add_timer(&task->slow_task->timer); 722 726 723 - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); 724 - if (res) 727 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task); 728 + if (!ccb) { 729 + res = -SAS_QUEUE_FULL; 725 730 break; 726 - 727 - ccb = &pm8001_ha->ccb_info[ccb_tag]; 728 - ccb->device = pm8001_dev; 729 - ccb->ccb_tag = ccb_tag; 730 - ccb->task = task; 731 - ccb->n_elem = 0; 731 + } 732 732 733 733 res = PM8001_CHIP_DISP->task_abort(pm8001_ha, pm8001_dev, flag, 734 - task_tag, ccb_tag); 734 + task_tag, ccb->ccb_tag); 735 735 if (res) { 736 736 del_timer(&task->slow_task->timer); 737 737 pm8001_dbg(pm8001_ha, FAIL, 738 738 "Executing internal task failed\n"); 739 - pm8001_tag_free(pm8001_ha, ccb_tag); 739 + pm8001_ccb_free(pm8001_ha, ccb); 740 740 break; 741 741 } 742 742
+47
drivers/scsi/pm8001/pm8001_sas.h
··· 734 734 735 735 #define PM8001_INVALID_TAG ((u32)-1) 736 736 737 + /* 738 + * Allocate a new tag and return the corresponding ccb after initializing it. 739 + */ 740 + static inline struct pm8001_ccb_info * 741 + pm8001_ccb_alloc(struct pm8001_hba_info *pm8001_ha, 742 + struct pm8001_device *dev, struct sas_task *task) 743 + { 744 + struct pm8001_ccb_info *ccb; 745 + u32 tag; 746 + 747 + if (pm8001_tag_alloc(pm8001_ha, &tag)) { 748 + pm8001_dbg(pm8001_ha, FAIL, "Failed to allocate a tag\n"); 749 + return NULL; 750 + } 751 + 752 + ccb = &pm8001_ha->ccb_info[tag]; 753 + ccb->task = task; 754 + ccb->n_elem = 0; 755 + ccb->ccb_tag = tag; 756 + ccb->device = dev; 757 + ccb->fw_control_context = NULL; 758 + ccb->open_retry = 0; 759 + 760 + return ccb; 761 + } 762 + 763 + /* 764 + * Free the tag of an initialized ccb. 765 + */ 766 + static inline void pm8001_ccb_free(struct pm8001_hba_info *pm8001_ha, 767 + struct pm8001_ccb_info *ccb) 768 + { 769 + u32 tag = ccb->ccb_tag; 770 + 771 + /* 772 + * Cleanup the ccb to make sure that a manual scan of the adapter 773 + * ccb_info array can detect ccb's that are in use. 774 + * C.f. pm8001_open_reject_retry() 775 + */ 776 + ccb->task = NULL; 777 + ccb->ccb_tag = PM8001_INVALID_TAG; 778 + ccb->device = NULL; 779 + ccb->fw_control_context = NULL; 780 + 781 + pm8001_tag_free(pm8001_ha, tag); 782 + } 783 + 737 784 static inline void 738 785 pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, 739 786 struct sas_task *task, struct pm8001_ccb_info *ccb,
+24 -40
drivers/scsi/pm8001/pm80xx_hwi.c
··· 1767 1767 static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha, 1768 1768 struct pm8001_device *pm8001_ha_dev) 1769 1769 { 1770 - int res; 1771 - u32 ccb_tag; 1772 1770 struct pm8001_ccb_info *ccb; 1773 1771 struct sas_task *task = NULL; 1774 1772 struct task_abort_req task_abort; ··· 1788 1790 1789 1791 task->task_done = pm8001_task_done; 1790 1792 1791 - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); 1792 - if (res) { 1793 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task); 1794 + if (!ccb) { 1793 1795 sas_free_task(task); 1794 1796 return; 1795 1797 } 1796 - 1797 - ccb = &pm8001_ha->ccb_info[ccb_tag]; 1798 - ccb->device = pm8001_ha_dev; 1799 - ccb->ccb_tag = ccb_tag; 1800 - ccb->task = task; 1801 - ccb->n_elem = 0; 1802 1798 1803 1799 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 1804 1800 1805 1801 memset(&task_abort, 0, sizeof(task_abort)); 1806 1802 task_abort.abort_all = cpu_to_le32(1); 1807 1803 task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id); 1808 - task_abort.tag = cpu_to_le32(ccb_tag); 1804 + task_abort.tag = cpu_to_le32(ccb->ccb_tag); 1809 1805 1810 1806 ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 1811 1807 sizeof(task_abort), 0); 1812 1808 pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n"); 1813 1809 if (ret) { 1814 1810 sas_free_task(task); 1815 - pm8001_tag_free(pm8001_ha, ccb_tag); 1811 + pm8001_ccb_free(pm8001_ha, ccb); 1816 1812 } 1817 1813 } 1818 1814 ··· 1815 1823 { 1816 1824 struct sata_start_req sata_cmd; 1817 1825 int res; 1818 - u32 ccb_tag; 1819 1826 struct pm8001_ccb_info *ccb; 1820 1827 struct sas_task *task = NULL; 1821 1828 struct host_to_dev_fis fis; ··· 1830 1839 } 1831 1840 task->task_done = pm8001_task_done; 1832 1841 1833 - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); 1834 - if (res) { 1835 - sas_free_task(task); 1836 - pm8001_dbg(pm8001_ha, FAIL, "cannot allocate tag !!!\n"); 1837 - return; 1838 - } 1839 - 1840 - /* allocate domain device by ourselves as libsas 1841 - * is not going to provide any 1842 - */ 1842 + /* 1843 + * Allocate domain device by ourselves as libsas is not going to 1844 + * provide any. 1845 + */ 1843 1846 dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); 1844 1847 if (!dev) { 1845 1848 sas_free_task(task); 1846 - pm8001_tag_free(pm8001_ha, ccb_tag); 1847 1849 pm8001_dbg(pm8001_ha, FAIL, 1848 1850 "Domain device cannot be allocated\n"); 1849 1851 return; ··· 1845 1861 task->dev = dev; 1846 1862 task->dev->lldd_dev = pm8001_ha_dev; 1847 1863 1848 - ccb = &pm8001_ha->ccb_info[ccb_tag]; 1849 - ccb->device = pm8001_ha_dev; 1850 - ccb->ccb_tag = ccb_tag; 1851 - ccb->task = task; 1852 - ccb->n_elem = 0; 1864 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task); 1865 + if (!ccb) { 1866 + sas_free_task(task); 1867 + kfree(dev); 1868 + return; 1869 + } 1870 + 1853 1871 pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG; 1854 1872 pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG; 1855 1873 ··· 1866 1880 fis.lbal = 0x10; 1867 1881 fis.sector_count = 0x1; 1868 1882 1869 - sata_cmd.tag = cpu_to_le32(ccb_tag); 1883 + sata_cmd.tag = cpu_to_le32(ccb->ccb_tag); 1870 1884 sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); 1871 1885 sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9))); 1872 1886 memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); ··· 1876 1890 pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n"); 1877 1891 if (res) { 1878 1892 sas_free_task(task); 1879 - pm8001_tag_free(pm8001_ha, ccb_tag); 1893 + pm8001_ccb_free(pm8001_ha, ccb); 1880 1894 kfree(dev); 1881 1895 } 1882 1896 } ··· 4820 4834 u32 stp_sspsmp_sata = 0x4; 4821 4835 struct inbound_queue_table *circularQ; 4822 4836 u32 linkrate, phy_id; 4823 - int rc, tag = 0xdeadbeef; 4837 + int rc; 4824 4838 struct pm8001_ccb_info *ccb; 4825 4839 u8 retryFlag = 0x1; 4826 4840 u16 firstBurstSize = 0; ··· 4831 4845 circularQ = &pm8001_ha->inbnd_q_tbl[0]; 4832 4846 4833 4847 memset(&payload, 0, sizeof(payload)); 4834 - rc = pm8001_tag_alloc(pm8001_ha, &tag); 4835 - if (rc) 4836 - return rc; 4837 - ccb = &pm8001_ha->ccb_info[tag]; 4838 - ccb->device = pm8001_dev; 4839 - ccb->ccb_tag = tag; 4840 - payload.tag = cpu_to_le32(tag); 4848 + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL); 4849 + if (!ccb) 4850 + return -SAS_QUEUE_FULL; 4851 + 4852 + payload.tag = cpu_to_le32(ccb->ccb_tag); 4841 4853 4842 4854 if (flag == 1) { 4843 4855 stp_sspsmp_sata = 0x02; /*direct attached sata */ ··· 4872 4888 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 4873 4889 sizeof(payload), 0); 4874 4890 if (rc) 4875 - pm8001_tag_free(pm8001_ha, tag); 4891 + pm8001_ccb_free(pm8001_ha, ccb); 4876 4892 4877 4893 return rc; 4878 4894 }