aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c1af2aa8e4e0..c723e60f02b0 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1893,29 +1893,48 @@ EXPORT_SYMBOL_GPL(iscsi_host_free);
1893 * 1893 *
1894 * This can be used by software iscsi_transports that allocate 1894 * This can be used by software iscsi_transports that allocate
1895 * a session per scsi host. 1895 * a session per scsi host.
1896 *
1897 * Callers should set cmds_max to the largest total numer (mgmt + scsi) of
1898 * tasks they support. The iscsi layer reserves ISCSI_MGMT_CMDS_MAX tasks
1899 * for nop handling and login/logout requests.
1896 */ 1900 */
1897struct iscsi_cls_session * 1901struct iscsi_cls_session *
1898iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, 1902iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
1899 uint16_t scsi_cmds_max, int cmd_task_size, 1903 uint16_t cmds_max, int cmd_task_size,
1900 uint32_t initial_cmdsn, unsigned int id) 1904 uint32_t initial_cmdsn, unsigned int id)
1901{ 1905{
1902 struct iscsi_session *session; 1906 struct iscsi_session *session;
1903 struct iscsi_cls_session *cls_session; 1907 struct iscsi_cls_session *cls_session;
1904 int cmd_i, cmds_max; 1908 int cmd_i, scsi_cmds, total_cmds = cmds_max;
1905
1906 /* 1909 /*
1907 * The iscsi layer needs some tasks for nop handling and tmfs. 1910 * The iscsi layer needs some tasks for nop handling and tmfs,
1911 * so the cmds_max must at least be greater than ISCSI_MGMT_CMDS_MAX
1912 * + 1 command for scsi IO.
1908 */ 1913 */
1909 if (scsi_cmds_max < 1) 1914 if (total_cmds < ISCSI_TOTAL_CMDS_MIN) {
1910 scsi_cmds_max = ISCSI_MGMT_CMDS_MAX; 1915 printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
1911 if ((scsi_cmds_max + ISCSI_MGMT_CMDS_MAX) >= ISCSI_MGMT_ITT_OFFSET) { 1916 "must be a power of two that is at least %d.\n",
1912 printk(KERN_ERR "iscsi: invalid can_queue of %d. " 1917 total_cmds, ISCSI_TOTAL_CMDS_MIN);
1913 "can_queue must be less than %d.\n", 1918 return NULL;
1914 scsi_cmds_max, 1919 }
1915 ISCSI_MGMT_ITT_OFFSET - ISCSI_MGMT_CMDS_MAX); 1920
1916 scsi_cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; 1921 if (total_cmds > ISCSI_TOTAL_CMDS_MAX) {
1922 printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
1923 "must be a power of 2 less than or equal to %d.\n",
1924 cmds_max, ISCSI_TOTAL_CMDS_MAX);
1925 total_cmds = ISCSI_TOTAL_CMDS_MAX;
1926 }
1927
1928 if (!is_power_of_2(total_cmds)) {
1929 printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
1930 "must be a power of 2.\n", total_cmds);
1931 total_cmds = rounddown_pow_of_two(total_cmds);
1932 if (total_cmds < ISCSI_TOTAL_CMDS_MIN)
1933 return NULL;
1934 printk(KERN_INFO "iscsi: Rounding can_queue to %d.\n",
1935 total_cmds);
1917 } 1936 }
1918 cmds_max = roundup_pow_of_two(scsi_cmds_max + ISCSI_MGMT_CMDS_MAX); 1937 scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX;
1919 1938
1920 cls_session = iscsi_alloc_session(shost, iscsit, 1939 cls_session = iscsi_alloc_session(shost, iscsit,
1921 sizeof(struct iscsi_session)); 1940 sizeof(struct iscsi_session));
@@ -1928,8 +1947,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
1928 session->fast_abort = 1; 1947 session->fast_abort = 1;
1929 session->lu_reset_timeout = 15; 1948 session->lu_reset_timeout = 15;
1930 session->abort_timeout = 10; 1949 session->abort_timeout = 10;
1931 session->scsi_cmds_max = scsi_cmds_max; 1950 session->scsi_cmds_max = scsi_cmds;
1932 session->cmds_max = cmds_max; 1951 session->cmds_max = total_cmds;
1933 session->queued_cmdsn = session->cmdsn = initial_cmdsn; 1952 session->queued_cmdsn = session->cmdsn = initial_cmdsn;
1934 session->exp_cmdsn = initial_cmdsn + 1; 1953 session->exp_cmdsn = initial_cmdsn + 1;
1935 session->max_cmdsn = initial_cmdsn + 1; 1954 session->max_cmdsn = initial_cmdsn + 1;