diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-04-06 18:48:10 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-27 10:42:47 -0400 |
commit | a257bf905efd22fd2c055580b0ab2e8e7ed1b6a1 (patch) | |
tree | e0f2ef6b9627d86456c92d56fa2c088c6d6544bf /drivers/scsi/lpfc/lpfc_scsi.c | |
parent | 3621a710a7dbb2d22a8e95d94bcf0c2d13ef57fc (diff) |
[SCSI] lpfc 8.3.1: misc fixes/changes
8.3.1 Fixes/Changes :
- Fix incorrect byte-swapping on word 4 of IOCB (data length) which
caused LUNs to not be discovered on big-endian (e.g. PPC)
- Remove a bad cast of MBslimaddr which loses the __iomem (sparse)
- Make lpfc_debugfs_mask_disc_trc static (sparse)
- Correct misspelled word BlockGuard in lpfc_logmsg.h comment
- Replaced repeated code segment for canceling IOCBs from a list with
a function call, lpfc_sli_cancel_iocbs().
- Increased HBQ buffers to support 40KB SSC sequences.
- Added sysfs interface to update speed and topology parameter without
link bounce.
- Fixed bug with sysfs fc_host WWNs not being updated after changing
the WWNs.
- Check if the active mailbox is NULL in the beginning of the mailbox
timeout handler - fixes panic in the mailbox timeout handler while
running IO stress test
- Fixed system panic in lpfc_pci_remove_one() due to ndlp indirect
reference to phba through vport
- Removed de-reference of scsi device after call to scsi_done() to fix
panic in scsi completion path while accessing scsi device after
scsi_done is called.
- Fixed "Nodelist not empty" message when unloading the driver after
target reboot test
- Added LP2105 HBA model description
- Added code to print all 16 words of unrecognized ASYNC events
- Fixed memory leak in vport create + delete loop
- Added support for handling dual error bit from HBA
- Fixed a driver NULL pointer dereference in lpfc_sli_process_sol_iocb
- Fixed a discovery bug with FC switch reboot in lpfc_setup_disc_node
- Take NULL termintator into account when calculating available buffer space
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 6eedb23980d6..167b66dd34c7 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -272,14 +272,14 @@ lpfc_rampdown_queue_depth(struct lpfc_hba *phba) | |||
272 | **/ | 272 | **/ |
273 | static inline void | 273 | static inline void |
274 | lpfc_rampup_queue_depth(struct lpfc_vport *vport, | 274 | lpfc_rampup_queue_depth(struct lpfc_vport *vport, |
275 | struct scsi_device *sdev) | 275 | uint32_t queue_depth) |
276 | { | 276 | { |
277 | unsigned long flags; | 277 | unsigned long flags; |
278 | struct lpfc_hba *phba = vport->phba; | 278 | struct lpfc_hba *phba = vport->phba; |
279 | uint32_t evt_posted; | 279 | uint32_t evt_posted; |
280 | atomic_inc(&phba->num_cmd_success); | 280 | atomic_inc(&phba->num_cmd_success); |
281 | 281 | ||
282 | if (vport->cfg_lun_queue_depth <= sdev->queue_depth) | 282 | if (vport->cfg_lun_queue_depth <= queue_depth) |
283 | return; | 283 | return; |
284 | spin_lock_irqsave(&phba->hbalock, flags); | 284 | spin_lock_irqsave(&phba->hbalock, flags); |
285 | if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) || | 285 | if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) || |
@@ -737,7 +737,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
737 | * Due to difference in data length between DIF/non-DIF paths, | 737 | * Due to difference in data length between DIF/non-DIF paths, |
738 | * we need to set word 4 of IOCB here | 738 | * we need to set word 4 of IOCB here |
739 | */ | 739 | */ |
740 | iocb_cmd->un.fcpi.fcpi_parm = le32_to_cpu(scsi_bufflen(scsi_cmnd)); | 740 | iocb_cmd->un.fcpi.fcpi_parm = scsi_bufflen(scsi_cmnd); |
741 | return 0; | 741 | return 0; |
742 | } | 742 | } |
743 | 743 | ||
@@ -1693,10 +1693,12 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1693 | struct lpfc_nodelist *pnode = rdata->pnode; | 1693 | struct lpfc_nodelist *pnode = rdata->pnode; |
1694 | struct scsi_cmnd *cmd = lpfc_cmd->pCmd; | 1694 | struct scsi_cmnd *cmd = lpfc_cmd->pCmd; |
1695 | int result; | 1695 | int result; |
1696 | struct scsi_device *sdev, *tmp_sdev; | 1696 | struct scsi_device *tmp_sdev; |
1697 | int depth = 0; | 1697 | int depth = 0; |
1698 | unsigned long flags; | 1698 | unsigned long flags; |
1699 | struct lpfc_fast_path_event *fast_path_evt; | 1699 | struct lpfc_fast_path_event *fast_path_evt; |
1700 | struct Scsi_Host *shost = cmd->device->host; | ||
1701 | uint32_t queue_depth, scsi_id; | ||
1700 | 1702 | ||
1701 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; | 1703 | lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4]; |
1702 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; | 1704 | lpfc_cmd->status = pIocbOut->iocb.ulpStatus; |
@@ -1807,11 +1809,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1807 | 1809 | ||
1808 | lpfc_update_stats(phba, lpfc_cmd); | 1810 | lpfc_update_stats(phba, lpfc_cmd); |
1809 | result = cmd->result; | 1811 | result = cmd->result; |
1810 | sdev = cmd->device; | ||
1811 | if (vport->cfg_max_scsicmpl_time && | 1812 | if (vport->cfg_max_scsicmpl_time && |
1812 | time_after(jiffies, lpfc_cmd->start_time + | 1813 | time_after(jiffies, lpfc_cmd->start_time + |
1813 | msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { | 1814 | msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { |
1814 | spin_lock_irqsave(sdev->host->host_lock, flags); | 1815 | spin_lock_irqsave(shost->host_lock, flags); |
1815 | if (pnode && NLP_CHK_NODE_ACT(pnode)) { | 1816 | if (pnode && NLP_CHK_NODE_ACT(pnode)) { |
1816 | if (pnode->cmd_qdepth > | 1817 | if (pnode->cmd_qdepth > |
1817 | atomic_read(&pnode->cmd_pending) && | 1818 | atomic_read(&pnode->cmd_pending) && |
@@ -1824,22 +1825,26 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1824 | 1825 | ||
1825 | pnode->last_change_time = jiffies; | 1826 | pnode->last_change_time = jiffies; |
1826 | } | 1827 | } |
1827 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 1828 | spin_unlock_irqrestore(shost->host_lock, flags); |
1828 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { | 1829 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { |
1829 | if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) && | 1830 | if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) && |
1830 | time_after(jiffies, pnode->last_change_time + | 1831 | time_after(jiffies, pnode->last_change_time + |
1831 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { | 1832 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { |
1832 | spin_lock_irqsave(sdev->host->host_lock, flags); | 1833 | spin_lock_irqsave(shost->host_lock, flags); |
1833 | pnode->cmd_qdepth += pnode->cmd_qdepth * | 1834 | pnode->cmd_qdepth += pnode->cmd_qdepth * |
1834 | LPFC_TGTQ_RAMPUP_PCENT / 100; | 1835 | LPFC_TGTQ_RAMPUP_PCENT / 100; |
1835 | if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH) | 1836 | if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH) |
1836 | pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; | 1837 | pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH; |
1837 | pnode->last_change_time = jiffies; | 1838 | pnode->last_change_time = jiffies; |
1838 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 1839 | spin_unlock_irqrestore(shost->host_lock, flags); |
1839 | } | 1840 | } |
1840 | } | 1841 | } |
1841 | 1842 | ||
1842 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | 1843 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); |
1844 | |||
1845 | /* The sdev is not guaranteed to be valid post scsi_done upcall. */ | ||
1846 | queue_depth = cmd->device->queue_depth; | ||
1847 | scsi_id = cmd->device->id; | ||
1843 | cmd->scsi_done(cmd); | 1848 | cmd->scsi_done(cmd); |
1844 | 1849 | ||
1845 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 1850 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
@@ -1847,28 +1852,28 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1847 | * If there is a thread waiting for command completion | 1852 | * If there is a thread waiting for command completion |
1848 | * wake up the thread. | 1853 | * wake up the thread. |
1849 | */ | 1854 | */ |
1850 | spin_lock_irqsave(sdev->host->host_lock, flags); | 1855 | spin_lock_irqsave(shost->host_lock, flags); |
1851 | lpfc_cmd->pCmd = NULL; | 1856 | lpfc_cmd->pCmd = NULL; |
1852 | if (lpfc_cmd->waitq) | 1857 | if (lpfc_cmd->waitq) |
1853 | wake_up(lpfc_cmd->waitq); | 1858 | wake_up(lpfc_cmd->waitq); |
1854 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 1859 | spin_unlock_irqrestore(shost->host_lock, flags); |
1855 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 1860 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
1856 | return; | 1861 | return; |
1857 | } | 1862 | } |
1858 | 1863 | ||
1859 | 1864 | ||
1860 | if (!result) | 1865 | if (!result) |
1861 | lpfc_rampup_queue_depth(vport, sdev); | 1866 | lpfc_rampup_queue_depth(vport, queue_depth); |
1862 | 1867 | ||
1863 | if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && | 1868 | if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && |
1864 | ((jiffies - pnode->last_ramp_up_time) > | 1869 | ((jiffies - pnode->last_ramp_up_time) > |
1865 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 1870 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
1866 | ((jiffies - pnode->last_q_full_time) > | 1871 | ((jiffies - pnode->last_q_full_time) > |
1867 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 1872 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
1868 | (vport->cfg_lun_queue_depth > sdev->queue_depth)) { | 1873 | (vport->cfg_lun_queue_depth > queue_depth)) { |
1869 | shost_for_each_device(tmp_sdev, sdev->host) { | 1874 | shost_for_each_device(tmp_sdev, shost) { |
1870 | if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){ | 1875 | if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){ |
1871 | if (tmp_sdev->id != sdev->id) | 1876 | if (tmp_sdev->id != scsi_id) |
1872 | continue; | 1877 | continue; |
1873 | if (tmp_sdev->ordered_tags) | 1878 | if (tmp_sdev->ordered_tags) |
1874 | scsi_adjust_queue_depth(tmp_sdev, | 1879 | scsi_adjust_queue_depth(tmp_sdev, |
@@ -1884,7 +1889,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1884 | } | 1889 | } |
1885 | lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode, | 1890 | lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode, |
1886 | 0xFFFFFFFF, | 1891 | 0xFFFFFFFF, |
1887 | sdev->queue_depth - 1, sdev->queue_depth); | 1892 | queue_depth , queue_depth + 1); |
1888 | } | 1893 | } |
1889 | 1894 | ||
1890 | /* | 1895 | /* |
@@ -1895,8 +1900,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1895 | NLP_CHK_NODE_ACT(pnode)) { | 1900 | NLP_CHK_NODE_ACT(pnode)) { |
1896 | pnode->last_q_full_time = jiffies; | 1901 | pnode->last_q_full_time = jiffies; |
1897 | 1902 | ||
1898 | shost_for_each_device(tmp_sdev, sdev->host) { | 1903 | shost_for_each_device(tmp_sdev, shost) { |
1899 | if (tmp_sdev->id != sdev->id) | 1904 | if (tmp_sdev->id != scsi_id) |
1900 | continue; | 1905 | continue; |
1901 | depth = scsi_track_queue_full(tmp_sdev, | 1906 | depth = scsi_track_queue_full(tmp_sdev, |
1902 | tmp_sdev->queue_depth - 1); | 1907 | tmp_sdev->queue_depth - 1); |
@@ -1908,7 +1913,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1908 | * scsi_track_queue_full. | 1913 | * scsi_track_queue_full. |
1909 | */ | 1914 | */ |
1910 | if (depth == -1) | 1915 | if (depth == -1) |
1911 | depth = sdev->host->cmd_per_lun; | 1916 | depth = shost->cmd_per_lun; |
1912 | 1917 | ||
1913 | if (depth) { | 1918 | if (depth) { |
1914 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, | 1919 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, |
@@ -1924,11 +1929,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
1924 | * If there is a thread waiting for command completion | 1929 | * If there is a thread waiting for command completion |
1925 | * wake up the thread. | 1930 | * wake up the thread. |
1926 | */ | 1931 | */ |
1927 | spin_lock_irqsave(sdev->host->host_lock, flags); | 1932 | spin_lock_irqsave(shost->host_lock, flags); |
1928 | lpfc_cmd->pCmd = NULL; | 1933 | lpfc_cmd->pCmd = NULL; |
1929 | if (lpfc_cmd->waitq) | 1934 | if (lpfc_cmd->waitq) |
1930 | wake_up(lpfc_cmd->waitq); | 1935 | wake_up(lpfc_cmd->waitq); |
1931 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 1936 | spin_unlock_irqrestore(shost->host_lock, flags); |
1932 | 1937 | ||
1933 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 1938 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
1934 | } | 1939 | } |