aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi/ibmvfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ibmvscsi/ibmvfc.c')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c335
1 files changed, 319 insertions, 16 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index bb2c696c006a..87b536a97cb4 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -39,6 +39,7 @@
39#include <scsi/scsi_device.h> 39#include <scsi/scsi_device.h>
40#include <scsi/scsi_tcq.h> 40#include <scsi/scsi_tcq.h>
41#include <scsi/scsi_transport_fc.h> 41#include <scsi/scsi_transport_fc.h>
42#include <scsi/scsi_bsg_fc.h>
42#include "ibmvfc.h" 43#include "ibmvfc.h"
43 44
44static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT; 45static unsigned int init_timeout = IBMVFC_INIT_TIMEOUT;
@@ -558,12 +559,11 @@ static void ibmvfc_link_down(struct ibmvfc_host *vhost,
558/** 559/**
559 * ibmvfc_init_host - Start host initialization 560 * ibmvfc_init_host - Start host initialization
560 * @vhost: ibmvfc host struct 561 * @vhost: ibmvfc host struct
561 * @relogin: is this a re-login?
562 * 562 *
563 * Return value: 563 * Return value:
564 * nothing 564 * nothing
565 **/ 565 **/
566static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin) 566static void ibmvfc_init_host(struct ibmvfc_host *vhost)
567{ 567{
568 struct ibmvfc_target *tgt; 568 struct ibmvfc_target *tgt;
569 569
@@ -577,10 +577,8 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin)
577 } 577 }
578 578
579 if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) { 579 if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
580 if (!relogin) { 580 memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
581 memset(vhost->async_crq.msgs, 0, PAGE_SIZE); 581 vhost->async_crq.cur = 0;
582 vhost->async_crq.cur = 0;
583 }
584 582
585 list_for_each_entry(tgt, &vhost->targets, queue) 583 list_for_each_entry(tgt, &vhost->targets, queue)
586 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); 584 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
@@ -1678,6 +1676,276 @@ static void ibmvfc_sync_completion(struct ibmvfc_event *evt)
1678} 1676}
1679 1677
1680/** 1678/**
1679 * ibmvfc_bsg_timeout_done - Completion handler for cancelling BSG commands
1680 * @evt: struct ibmvfc_event
1681 *
1682 **/
1683static void ibmvfc_bsg_timeout_done(struct ibmvfc_event *evt)
1684{
1685 struct ibmvfc_host *vhost = evt->vhost;
1686
1687 ibmvfc_free_event(evt);
1688 vhost->aborting_passthru = 0;
1689 dev_info(vhost->dev, "Passthru command cancelled\n");
1690}
1691
1692/**
1693 * ibmvfc_bsg_timeout - Handle a BSG timeout
1694 * @job: struct fc_bsg_job that timed out
1695 *
1696 * Returns:
1697 * 0 on success / other on failure
1698 **/
1699static int ibmvfc_bsg_timeout(struct fc_bsg_job *job)
1700{
1701 struct ibmvfc_host *vhost = shost_priv(job->shost);
1702 unsigned long port_id = (unsigned long)job->dd_data;
1703 struct ibmvfc_event *evt;
1704 struct ibmvfc_tmf *tmf;
1705 unsigned long flags;
1706 int rc;
1707
1708 ENTER;
1709 spin_lock_irqsave(vhost->host->host_lock, flags);
1710 if (vhost->aborting_passthru || vhost->state != IBMVFC_ACTIVE) {
1711 __ibmvfc_reset_host(vhost);
1712 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1713 return 0;
1714 }
1715
1716 vhost->aborting_passthru = 1;
1717 evt = ibmvfc_get_event(vhost);
1718 ibmvfc_init_event(evt, ibmvfc_bsg_timeout_done, IBMVFC_MAD_FORMAT);
1719
1720 tmf = &evt->iu.tmf;
1721 memset(tmf, 0, sizeof(*tmf));
1722 tmf->common.version = 1;
1723 tmf->common.opcode = IBMVFC_TMF_MAD;
1724 tmf->common.length = sizeof(*tmf);
1725 tmf->scsi_id = port_id;
1726 tmf->cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
1727 tmf->my_cancel_key = IBMVFC_INTERNAL_CANCEL_KEY;
1728 rc = ibmvfc_send_event(evt, vhost, default_timeout);
1729
1730 if (rc != 0) {
1731 vhost->aborting_passthru = 0;
1732 dev_err(vhost->dev, "Failed to send cancel event. rc=%d\n", rc);
1733 rc = -EIO;
1734 } else
1735 dev_info(vhost->dev, "Cancelling passthru command to port id 0x%lx\n",
1736 port_id);
1737
1738 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1739
1740 LEAVE;
1741 return rc;
1742}
1743
1744/**
1745 * ibmvfc_bsg_plogi - PLOGI into a target to handle a BSG command
1746 * @vhost: struct ibmvfc_host to send command
1747 * @port_id: port ID to send command
1748 *
1749 * Returns:
1750 * 0 on success / other on failure
1751 **/
1752static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id)
1753{
1754 struct ibmvfc_port_login *plogi;
1755 struct ibmvfc_target *tgt;
1756 struct ibmvfc_event *evt;
1757 union ibmvfc_iu rsp_iu;
1758 unsigned long flags;
1759 int rc = 0, issue_login = 1;
1760
1761 ENTER;
1762 spin_lock_irqsave(vhost->host->host_lock, flags);
1763 list_for_each_entry(tgt, &vhost->targets, queue) {
1764 if (tgt->scsi_id == port_id) {
1765 issue_login = 0;
1766 break;
1767 }
1768 }
1769
1770 if (!issue_login)
1771 goto unlock_out;
1772 if (unlikely((rc = ibmvfc_host_chkready(vhost))))
1773 goto unlock_out;
1774
1775 evt = ibmvfc_get_event(vhost);
1776 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
1777 plogi = &evt->iu.plogi;
1778 memset(plogi, 0, sizeof(*plogi));
1779 plogi->common.version = 1;
1780 plogi->common.opcode = IBMVFC_PORT_LOGIN;
1781 plogi->common.length = sizeof(*plogi);
1782 plogi->scsi_id = port_id;
1783 evt->sync_iu = &rsp_iu;
1784 init_completion(&evt->comp);
1785
1786 rc = ibmvfc_send_event(evt, vhost, default_timeout);
1787 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1788
1789 if (rc)
1790 return -EIO;
1791
1792 wait_for_completion(&evt->comp);
1793
1794 if (rsp_iu.plogi.common.status)
1795 rc = -EIO;
1796
1797 spin_lock_irqsave(vhost->host->host_lock, flags);
1798 ibmvfc_free_event(evt);
1799unlock_out:
1800 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1801 LEAVE;
1802 return rc;
1803}
1804
1805/**
1806 * ibmvfc_bsg_request - Handle a BSG request
1807 * @job: struct fc_bsg_job to be executed
1808 *
1809 * Returns:
1810 * 0 on success / other on failure
1811 **/
1812static int ibmvfc_bsg_request(struct fc_bsg_job *job)
1813{
1814 struct ibmvfc_host *vhost = shost_priv(job->shost);
1815 struct fc_rport *rport = job->rport;
1816 struct ibmvfc_passthru_mad *mad;
1817 struct ibmvfc_event *evt;
1818 union ibmvfc_iu rsp_iu;
1819 unsigned long flags, port_id = -1;
1820 unsigned int code = job->request->msgcode;
1821 int rc = 0, req_seg, rsp_seg, issue_login = 0;
1822 u32 fc_flags, rsp_len;
1823
1824 ENTER;
1825 job->reply->reply_payload_rcv_len = 0;
1826 if (rport)
1827 port_id = rport->port_id;
1828
1829 switch (code) {
1830 case FC_BSG_HST_ELS_NOLOGIN:
1831 port_id = (job->request->rqst_data.h_els.port_id[0] << 16) |
1832 (job->request->rqst_data.h_els.port_id[1] << 8) |
1833 job->request->rqst_data.h_els.port_id[2];
1834 case FC_BSG_RPT_ELS:
1835 fc_flags = IBMVFC_FC_ELS;
1836 break;
1837 case FC_BSG_HST_CT:
1838 issue_login = 1;
1839 port_id = (job->request->rqst_data.h_ct.port_id[0] << 16) |
1840 (job->request->rqst_data.h_ct.port_id[1] << 8) |
1841 job->request->rqst_data.h_ct.port_id[2];
1842 case FC_BSG_RPT_CT:
1843 fc_flags = IBMVFC_FC_CT_IU;
1844 break;
1845 default:
1846 return -ENOTSUPP;
1847 };
1848
1849 if (port_id == -1)
1850 return -EINVAL;
1851 if (!mutex_trylock(&vhost->passthru_mutex))
1852 return -EBUSY;
1853
1854 job->dd_data = (void *)port_id;
1855 req_seg = dma_map_sg(vhost->dev, job->request_payload.sg_list,
1856 job->request_payload.sg_cnt, DMA_TO_DEVICE);
1857
1858 if (!req_seg) {
1859 mutex_unlock(&vhost->passthru_mutex);
1860 return -ENOMEM;
1861 }
1862
1863 rsp_seg = dma_map_sg(vhost->dev, job->reply_payload.sg_list,
1864 job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1865
1866 if (!rsp_seg) {
1867 dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
1868 job->request_payload.sg_cnt, DMA_TO_DEVICE);
1869 mutex_unlock(&vhost->passthru_mutex);
1870 return -ENOMEM;
1871 }
1872
1873 if (req_seg > 1 || rsp_seg > 1) {
1874 rc = -EINVAL;
1875 goto out;
1876 }
1877
1878 if (issue_login)
1879 rc = ibmvfc_bsg_plogi(vhost, port_id);
1880
1881 spin_lock_irqsave(vhost->host->host_lock, flags);
1882
1883 if (unlikely(rc || (rport && (rc = fc_remote_port_chkready(rport)))) ||
1884 unlikely((rc = ibmvfc_host_chkready(vhost)))) {
1885 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1886 goto out;
1887 }
1888
1889 evt = ibmvfc_get_event(vhost);
1890 ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
1891 mad = &evt->iu.passthru;
1892
1893 memset(mad, 0, sizeof(*mad));
1894 mad->common.version = 1;
1895 mad->common.opcode = IBMVFC_PASSTHRU;
1896 mad->common.length = sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu);
1897
1898 mad->cmd_ioba.va = (u64)evt->crq.ioba +
1899 offsetof(struct ibmvfc_passthru_mad, iu);
1900 mad->cmd_ioba.len = sizeof(mad->iu);
1901
1902 mad->iu.cmd_len = job->request_payload.payload_len;
1903 mad->iu.rsp_len = job->reply_payload.payload_len;
1904 mad->iu.flags = fc_flags;
1905 mad->iu.cancel_key = IBMVFC_PASSTHRU_CANCEL_KEY;
1906
1907 mad->iu.cmd.va = sg_dma_address(job->request_payload.sg_list);
1908 mad->iu.cmd.len = sg_dma_len(job->request_payload.sg_list);
1909 mad->iu.rsp.va = sg_dma_address(job->reply_payload.sg_list);
1910 mad->iu.rsp.len = sg_dma_len(job->reply_payload.sg_list);
1911 mad->iu.scsi_id = port_id;
1912 mad->iu.tag = (u64)evt;
1913 rsp_len = mad->iu.rsp.len;
1914
1915 evt->sync_iu = &rsp_iu;
1916 init_completion(&evt->comp);
1917 rc = ibmvfc_send_event(evt, vhost, 0);
1918 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1919
1920 if (rc) {
1921 rc = -EIO;
1922 goto out;
1923 }
1924
1925 wait_for_completion(&evt->comp);
1926
1927 if (rsp_iu.passthru.common.status)
1928 rc = -EIO;
1929 else
1930 job->reply->reply_payload_rcv_len = rsp_len;
1931
1932 spin_lock_irqsave(vhost->host->host_lock, flags);
1933 ibmvfc_free_event(evt);
1934 spin_unlock_irqrestore(vhost->host->host_lock, flags);
1935 job->reply->result = rc;
1936 job->job_done(job);
1937 rc = 0;
1938out:
1939 dma_unmap_sg(vhost->dev, job->request_payload.sg_list,
1940 job->request_payload.sg_cnt, DMA_TO_DEVICE);
1941 dma_unmap_sg(vhost->dev, job->reply_payload.sg_list,
1942 job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1943 mutex_unlock(&vhost->passthru_mutex);
1944 LEAVE;
1945 return rc;
1946}
1947
1948/**
1681 * ibmvfc_reset_device - Reset the device with the specified reset type 1949 * ibmvfc_reset_device - Reset the device with the specified reset type
1682 * @sdev: scsi device to reset 1950 * @sdev: scsi device to reset
1683 * @type: reset type 1951 * @type: reset type
@@ -1731,7 +1999,10 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc)
1731 sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc); 1999 sdev_printk(KERN_INFO, sdev, "Resetting %s\n", desc);
1732 wait_for_completion(&evt->comp); 2000 wait_for_completion(&evt->comp);
1733 2001
1734 if (rsp_iu.cmd.status) { 2002 if (rsp_iu.cmd.status)
2003 rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
2004
2005 if (rsp_code) {
1735 if (fc_rsp->flags & FCP_RSP_LEN_VALID) 2006 if (fc_rsp->flags & FCP_RSP_LEN_VALID)
1736 rsp_code = fc_rsp->data.info.rsp_code; 2007 rsp_code = fc_rsp->data.info.rsp_code;
1737 2008
@@ -1820,7 +2091,10 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
1820 sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n"); 2091 sdev_printk(KERN_INFO, sdev, "Aborting outstanding commands\n");
1821 wait_for_completion(&evt->comp); 2092 wait_for_completion(&evt->comp);
1822 2093
1823 if (rsp_iu.cmd.status) { 2094 if (rsp_iu.cmd.status)
2095 rsp_code = ibmvfc_get_err_result(&rsp_iu.cmd);
2096
2097 if (rsp_code) {
1824 if (fc_rsp->flags & FCP_RSP_LEN_VALID) 2098 if (fc_rsp->flags & FCP_RSP_LEN_VALID)
1825 rsp_code = fc_rsp->data.info.rsp_code; 2099 rsp_code = fc_rsp->data.info.rsp_code;
1826 2100
@@ -2061,12 +2335,24 @@ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
2061} 2335}
2062 2336
2063/** 2337/**
2064 * ibmvfc_dev_cancel_all - Device iterated cancel all function 2338 * ibmvfc_dev_cancel_all_abts - Device iterated cancel all function
2065 * @sdev: scsi device struct 2339 * @sdev: scsi device struct
2066 * @data: return code 2340 * @data: return code
2067 * 2341 *
2068 **/ 2342 **/
2069static void ibmvfc_dev_cancel_all(struct scsi_device *sdev, void *data) 2343static void ibmvfc_dev_cancel_all_abts(struct scsi_device *sdev, void *data)
2344{
2345 unsigned long *rc = data;
2346 *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
2347}
2348
2349/**
2350 * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function
2351 * @sdev: scsi device struct
2352 * @data: return code
2353 *
2354 **/
2355static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
2070{ 2356{
2071 unsigned long *rc = data; 2357 unsigned long *rc = data;
2072 *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET); 2358 *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET);
@@ -2102,7 +2388,7 @@ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
2102 2388
2103 ENTER; 2389 ENTER;
2104 ibmvfc_wait_while_resetting(vhost); 2390 ibmvfc_wait_while_resetting(vhost);
2105 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all); 2391 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
2106 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target"); 2392 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target");
2107 2393
2108 if (!cancel_rc && !reset_rc) 2394 if (!cancel_rc && !reset_rc)
@@ -2144,7 +2430,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
2144 int rc = FAILED; 2430 int rc = FAILED;
2145 2431
2146 ENTER; 2432 ENTER;
2147 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all); 2433 starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_abts);
2148 starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all); 2434 starget_for_each_device(starget, &abort_rc, ibmvfc_dev_abort_all);
2149 2435
2150 if (!cancel_rc && !abort_rc) 2436 if (!cancel_rc && !abort_rc)
@@ -2297,13 +2583,13 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
2297 /* Send back a response */ 2583 /* Send back a response */
2298 rc = ibmvfc_send_crq_init_complete(vhost); 2584 rc = ibmvfc_send_crq_init_complete(vhost);
2299 if (rc == 0) 2585 if (rc == 0)
2300 ibmvfc_init_host(vhost, 0); 2586 ibmvfc_init_host(vhost);
2301 else 2587 else
2302 dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc); 2588 dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc);
2303 break; 2589 break;
2304 case IBMVFC_CRQ_INIT_COMPLETE: 2590 case IBMVFC_CRQ_INIT_COMPLETE:
2305 dev_info(vhost->dev, "Partner initialization complete\n"); 2591 dev_info(vhost->dev, "Partner initialization complete\n");
2306 ibmvfc_init_host(vhost, 0); 2592 ibmvfc_init_host(vhost);
2307 break; 2593 break;
2308 default: 2594 default:
2309 dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format); 2595 dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format);
@@ -2478,12 +2764,17 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
2478 * ibmvfc_change_queue_depth - Change the device's queue depth 2764 * ibmvfc_change_queue_depth - Change the device's queue depth
2479 * @sdev: scsi device struct 2765 * @sdev: scsi device struct
2480 * @qdepth: depth to set 2766 * @qdepth: depth to set
2767 * @reason: calling context
2481 * 2768 *
2482 * Return value: 2769 * Return value:
2483 * actual depth set 2770 * actual depth set
2484 **/ 2771 **/
2485static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth) 2772static int ibmvfc_change_queue_depth(struct scsi_device *sdev, int qdepth,
2773 int reason)
2486{ 2774{
2775 if (reason != SCSI_QDEPTH_DEFAULT)
2776 return -EOPNOTSUPP;
2777
2487 if (qdepth > IBMVFC_MAX_CMDS_PER_LUN) 2778 if (qdepth > IBMVFC_MAX_CMDS_PER_LUN)
2488 qdepth = IBMVFC_MAX_CMDS_PER_LUN; 2779 qdepth = IBMVFC_MAX_CMDS_PER_LUN;
2489 2780
@@ -3725,7 +4016,7 @@ static void ibmvfc_npiv_logout_done(struct ibmvfc_event *evt)
3725 case IBMVFC_MAD_SUCCESS: 4016 case IBMVFC_MAD_SUCCESS:
3726 if (list_empty(&vhost->sent) && 4017 if (list_empty(&vhost->sent) &&
3727 vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) { 4018 vhost->action == IBMVFC_HOST_ACTION_LOGO_WAIT) {
3728 ibmvfc_init_host(vhost, 0); 4019 ibmvfc_init_host(vhost);
3729 return; 4020 return;
3730 } 4021 }
3731 break; 4022 break;
@@ -3903,6 +4194,8 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt)
3903 rport->supported_classes |= FC_COS_CLASS2; 4194 rport->supported_classes |= FC_COS_CLASS2;
3904 if (tgt->service_parms.class3_parms[0] & 0x80000000) 4195 if (tgt->service_parms.class3_parms[0] & 0x80000000)
3905 rport->supported_classes |= FC_COS_CLASS3; 4196 rport->supported_classes |= FC_COS_CLASS3;
4197 if (rport->rqst_q)
4198 blk_queue_max_hw_segments(rport->rqst_q, 1);
3906 } else 4199 } else
3907 tgt_dbg(tgt, "rport add failed\n"); 4200 tgt_dbg(tgt, "rport add failed\n");
3908 spin_unlock_irqrestore(vhost->host->host_lock, flags); 4201 spin_unlock_irqrestore(vhost->host->host_lock, flags);
@@ -4342,6 +4635,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
4342 init_waitqueue_head(&vhost->work_wait_q); 4635 init_waitqueue_head(&vhost->work_wait_q);
4343 init_waitqueue_head(&vhost->init_wait_q); 4636 init_waitqueue_head(&vhost->init_wait_q);
4344 INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread); 4637 INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread);
4638 mutex_init(&vhost->passthru_mutex);
4345 4639
4346 if ((rc = ibmvfc_alloc_mem(vhost))) 4640 if ((rc = ibmvfc_alloc_mem(vhost)))
4347 goto free_scsi_host; 4641 goto free_scsi_host;
@@ -4374,6 +4668,8 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
4374 goto remove_shost; 4668 goto remove_shost;
4375 } 4669 }
4376 4670
4671 if (shost_to_fc_host(shost)->rqst_q)
4672 blk_queue_max_hw_segments(shost_to_fc_host(shost)->rqst_q, 1);
4377 dev_set_drvdata(dev, vhost); 4673 dev_set_drvdata(dev, vhost);
4378 spin_lock(&ibmvfc_driver_lock); 4674 spin_lock(&ibmvfc_driver_lock);
4379 list_add_tail(&vhost->queue, &ibmvfc_head); 4675 list_add_tail(&vhost->queue, &ibmvfc_head);
@@ -4414,7 +4710,11 @@ static int ibmvfc_remove(struct vio_dev *vdev)
4414 4710
4415 ENTER; 4711 ENTER;
4416 ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); 4712 ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr);
4713
4714 spin_lock_irqsave(vhost->host->host_lock, flags);
4417 ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); 4715 ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE);
4716 spin_unlock_irqrestore(vhost->host->host_lock, flags);
4717
4418 ibmvfc_wait_while_resetting(vhost); 4718 ibmvfc_wait_while_resetting(vhost);
4419 ibmvfc_release_crq_queue(vhost); 4719 ibmvfc_release_crq_queue(vhost);
4420 kthread_stop(vhost->work_thread); 4720 kthread_stop(vhost->work_thread);
@@ -4498,6 +4798,9 @@ static struct fc_function_template ibmvfc_transport_functions = {
4498 4798
4499 .get_starget_port_id = ibmvfc_get_starget_port_id, 4799 .get_starget_port_id = ibmvfc_get_starget_port_id,
4500 .show_starget_port_id = 1, 4800 .show_starget_port_id = 1,
4801
4802 .bsg_request = ibmvfc_bsg_request,
4803 .bsg_timeout = ibmvfc_bsg_timeout,
4501}; 4804};
4502 4805
4503/** 4806/**