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

scsi: csiostor: fix incorrect port capabilities

- use be32_to_cpu() instead of ntohs() for 32 bit port capabilities.

- add a new function fwcaps32_to_caps16() to convert 32 bit port
capabilities to 16 bit port capabilities.

Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Varun Prakash and committed by
Martin K. Petersen
68bdc630 89809b02

+48 -14
+44 -11
drivers/scsi/csiostor/csio_hw.c
··· 1602 1602 } 1603 1603 1604 1604 /** 1605 + * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits 1606 + * @caps32: a 32-bit Port Capabilities value 1607 + * 1608 + * Returns the equivalent 16-bit Port Capabilities value. Note that 1609 + * not all 32-bit Port Capabilities can be represented in the 16-bit 1610 + * Port Capabilities and some fields/values may not make it. 1611 + */ 1612 + fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32) 1613 + { 1614 + fw_port_cap16_t caps16 = 0; 1615 + 1616 + #define CAP32_TO_CAP16(__cap) \ 1617 + do { \ 1618 + if (caps32 & FW_PORT_CAP32_##__cap) \ 1619 + caps16 |= FW_PORT_CAP_##__cap; \ 1620 + } while (0) 1621 + 1622 + CAP32_TO_CAP16(SPEED_100M); 1623 + CAP32_TO_CAP16(SPEED_1G); 1624 + CAP32_TO_CAP16(SPEED_10G); 1625 + CAP32_TO_CAP16(SPEED_25G); 1626 + CAP32_TO_CAP16(SPEED_40G); 1627 + CAP32_TO_CAP16(SPEED_100G); 1628 + CAP32_TO_CAP16(FC_RX); 1629 + CAP32_TO_CAP16(FC_TX); 1630 + CAP32_TO_CAP16(802_3_PAUSE); 1631 + CAP32_TO_CAP16(802_3_ASM_DIR); 1632 + CAP32_TO_CAP16(ANEG); 1633 + CAP32_TO_CAP16(FORCE_PAUSE); 1634 + CAP32_TO_CAP16(MDIAUTO); 1635 + CAP32_TO_CAP16(MDISTRAIGHT); 1636 + CAP32_TO_CAP16(FEC_RS); 1637 + CAP32_TO_CAP16(FEC_BASER_RS); 1638 + 1639 + #undef CAP32_TO_CAP16 1640 + 1641 + return caps16; 1642 + } 1643 + 1644 + /** 1605 1645 * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities 1606 1646 * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value 1607 1647 * ··· 1799 1759 val = 1; 1800 1760 1801 1761 csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO, 1802 - hw->pfn, 0, 1, &param, &val, false, 1762 + hw->pfn, 0, 1, &param, &val, true, 1803 1763 NULL); 1804 1764 1805 1765 if (csio_mb_issue(hw, mbp)) { ··· 1809 1769 return -EINVAL; 1810 1770 } 1811 1771 1812 - csio_mb_process_read_params_rsp(hw, mbp, &retval, 1, 1813 - &val); 1814 - if (retval != FW_SUCCESS) { 1815 - csio_err(hw, "FW_PARAMS_CMD(r) port:%d failed: 0x%x\n", 1816 - portid, retval); 1817 - mempool_free(mbp, hw->mb_mempool); 1818 - return -EINVAL; 1819 - } 1820 - 1821 - fw_caps = val; 1772 + csio_mb_process_read_params_rsp(hw, mbp, &retval, 1773 + 0, NULL); 1774 + fw_caps = retval ? FW_CAPS16 : FW_CAPS32; 1822 1775 } 1823 1776 1824 1777 /* Read PORT information */
+1
drivers/scsi/csiostor/csio_hw.h
··· 639 639 640 640 fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps); 641 641 fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16); 642 + fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32); 642 643 fw_port_cap32_t lstatus_to_fwcap(u32 lstatus); 643 644 644 645 int csio_hw_start(struct csio_hw *);
+3 -3
drivers/scsi/csiostor/csio_mb.c
··· 368 368 FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); 369 369 370 370 if (fw_caps == FW_CAPS16) 371 - cmdp->u.l1cfg.rcap = cpu_to_be32(fc); 371 + cmdp->u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(fc)); 372 372 else 373 373 cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc); 374 374 } ··· 395 395 *pcaps = fwcaps16_to_caps32(ntohs(rsp->u.info.pcap)); 396 396 *acaps = fwcaps16_to_caps32(ntohs(rsp->u.info.acap)); 397 397 } else { 398 - *pcaps = ntohs(rsp->u.info32.pcaps32); 399 - *acaps = ntohs(rsp->u.info32.acaps32); 398 + *pcaps = be32_to_cpu(rsp->u.info32.pcaps32); 399 + *acaps = be32_to_cpu(rsp->u.info32.acaps32); 400 400 } 401 401 } 402 402 }