diff options
Diffstat (limited to 'drivers/target/sbp/sbp_target.c')
| -rw-r--r-- | drivers/target/sbp/sbp_target.c | 277 |
1 files changed, 54 insertions, 223 deletions
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 18b0f9703ff2..0edf320fb685 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c | |||
| @@ -30,13 +30,12 @@ | |||
| 30 | #include <linux/ctype.h> | 30 | #include <linux/ctype.h> |
| 31 | #include <linux/firewire.h> | 31 | #include <linux/firewire.h> |
| 32 | #include <linux/firewire-constants.h> | 32 | #include <linux/firewire-constants.h> |
| 33 | #include <scsi/scsi.h> | 33 | #include <scsi/scsi_proto.h> |
| 34 | #include <scsi/scsi_tcq.h> | 34 | #include <scsi/scsi_tcq.h> |
| 35 | #include <target/target_core_base.h> | 35 | #include <target/target_core_base.h> |
| 36 | #include <target/target_core_backend.h> | 36 | #include <target/target_core_backend.h> |
| 37 | #include <target/target_core_fabric.h> | 37 | #include <target/target_core_fabric.h> |
| 38 | #include <target/target_core_fabric_configfs.h> | 38 | #include <target/target_core_fabric_configfs.h> |
| 39 | #include <target/target_core_configfs.h> | ||
| 40 | #include <target/configfs_macros.h> | 39 | #include <target/configfs_macros.h> |
| 41 | #include <asm/unaligned.h> | 40 | #include <asm/unaligned.h> |
| 42 | 41 | ||
| @@ -109,13 +108,13 @@ static struct sbp_session *sbp_session_find_by_guid( | |||
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | static struct sbp_login_descriptor *sbp_login_find_by_lun( | 110 | static struct sbp_login_descriptor *sbp_login_find_by_lun( |
| 112 | struct sbp_session *session, struct se_lun *lun) | 111 | struct sbp_session *session, u32 unpacked_lun) |
| 113 | { | 112 | { |
| 114 | struct sbp_login_descriptor *login, *found = NULL; | 113 | struct sbp_login_descriptor *login, *found = NULL; |
| 115 | 114 | ||
| 116 | spin_lock_bh(&session->lock); | 115 | spin_lock_bh(&session->lock); |
| 117 | list_for_each_entry(login, &session->login_list, link) { | 116 | list_for_each_entry(login, &session->login_list, link) { |
| 118 | if (login->lun == lun) | 117 | if (login->login_lun == unpacked_lun) |
| 119 | found = login; | 118 | found = login; |
| 120 | } | 119 | } |
| 121 | spin_unlock_bh(&session->lock); | 120 | spin_unlock_bh(&session->lock); |
| @@ -125,7 +124,7 @@ static struct sbp_login_descriptor *sbp_login_find_by_lun( | |||
| 125 | 124 | ||
| 126 | static int sbp_login_count_all_by_lun( | 125 | static int sbp_login_count_all_by_lun( |
| 127 | struct sbp_tpg *tpg, | 126 | struct sbp_tpg *tpg, |
| 128 | struct se_lun *lun, | 127 | u32 unpacked_lun, |
| 129 | int exclusive) | 128 | int exclusive) |
| 130 | { | 129 | { |
| 131 | struct se_session *se_sess; | 130 | struct se_session *se_sess; |
| @@ -139,7 +138,7 @@ static int sbp_login_count_all_by_lun( | |||
| 139 | 138 | ||
| 140 | spin_lock_bh(&sess->lock); | 139 | spin_lock_bh(&sess->lock); |
| 141 | list_for_each_entry(login, &sess->login_list, link) { | 140 | list_for_each_entry(login, &sess->login_list, link) { |
| 142 | if (login->lun != lun) | 141 | if (login->login_lun != unpacked_lun) |
| 143 | continue; | 142 | continue; |
| 144 | 143 | ||
| 145 | if (!exclusive || login->exclusive) | 144 | if (!exclusive || login->exclusive) |
| @@ -175,23 +174,23 @@ static struct sbp_login_descriptor *sbp_login_find_by_id( | |||
| 175 | return found; | 174 | return found; |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | static struct se_lun *sbp_get_lun_from_tpg(struct sbp_tpg *tpg, int lun) | 177 | static u32 sbp_get_lun_from_tpg(struct sbp_tpg *tpg, u32 login_lun, int *err) |
| 179 | { | 178 | { |
| 180 | struct se_portal_group *se_tpg = &tpg->se_tpg; | 179 | struct se_portal_group *se_tpg = &tpg->se_tpg; |
| 181 | struct se_lun *se_lun; | 180 | struct se_lun *se_lun; |
| 182 | 181 | ||
| 183 | if (lun >= TRANSPORT_MAX_LUNS_PER_TPG) | 182 | rcu_read_lock(); |
| 184 | return ERR_PTR(-EINVAL); | 183 | hlist_for_each_entry_rcu(se_lun, &se_tpg->tpg_lun_hlist, link) { |
| 185 | 184 | if (se_lun->unpacked_lun == login_lun) { | |
| 186 | spin_lock(&se_tpg->tpg_lun_lock); | 185 | rcu_read_unlock(); |
| 187 | se_lun = se_tpg->tpg_lun_list[lun]; | 186 | *err = 0; |
| 188 | 187 | return login_lun; | |
| 189 | if (se_lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE) | 188 | } |
| 190 | se_lun = ERR_PTR(-ENODEV); | 189 | } |
| 191 | 190 | rcu_read_unlock(); | |
| 192 | spin_unlock(&se_tpg->tpg_lun_lock); | ||
| 193 | 191 | ||
| 194 | return se_lun; | 192 | *err = -ENODEV; |
| 193 | return login_lun; | ||
| 195 | } | 194 | } |
| 196 | 195 | ||
| 197 | static struct sbp_session *sbp_session_create( | 196 | static struct sbp_session *sbp_session_create( |
| @@ -295,17 +294,16 @@ static void sbp_management_request_login( | |||
| 295 | { | 294 | { |
| 296 | struct sbp_tport *tport = agent->tport; | 295 | struct sbp_tport *tport = agent->tport; |
| 297 | struct sbp_tpg *tpg = tport->tpg; | 296 | struct sbp_tpg *tpg = tport->tpg; |
| 298 | struct se_lun *se_lun; | ||
| 299 | int ret; | ||
| 300 | u64 guid; | ||
| 301 | struct sbp_session *sess; | 297 | struct sbp_session *sess; |
| 302 | struct sbp_login_descriptor *login; | 298 | struct sbp_login_descriptor *login; |
| 303 | struct sbp_login_response_block *response; | 299 | struct sbp_login_response_block *response; |
| 304 | int login_response_len; | 300 | u64 guid; |
| 301 | u32 unpacked_lun; | ||
| 302 | int login_response_len, ret; | ||
| 305 | 303 | ||
| 306 | se_lun = sbp_get_lun_from_tpg(tpg, | 304 | unpacked_lun = sbp_get_lun_from_tpg(tpg, |
| 307 | LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc))); | 305 | LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)), &ret); |
| 308 | if (IS_ERR(se_lun)) { | 306 | if (ret) { |
| 309 | pr_notice("login to unknown LUN: %d\n", | 307 | pr_notice("login to unknown LUN: %d\n", |
| 310 | LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc))); | 308 | LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc))); |
| 311 | 309 | ||
| @@ -326,11 +324,11 @@ static void sbp_management_request_login( | |||
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | pr_notice("mgt_agent LOGIN to LUN %d from %016llx\n", | 326 | pr_notice("mgt_agent LOGIN to LUN %d from %016llx\n", |
| 329 | se_lun->unpacked_lun, guid); | 327 | unpacked_lun, guid); |
| 330 | 328 | ||
| 331 | sess = sbp_session_find_by_guid(tpg, guid); | 329 | sess = sbp_session_find_by_guid(tpg, guid); |
| 332 | if (sess) { | 330 | if (sess) { |
| 333 | login = sbp_login_find_by_lun(sess, se_lun); | 331 | login = sbp_login_find_by_lun(sess, unpacked_lun); |
| 334 | if (login) { | 332 | if (login) { |
| 335 | pr_notice("initiator already logged-in\n"); | 333 | pr_notice("initiator already logged-in\n"); |
| 336 | 334 | ||
| @@ -358,7 +356,7 @@ static void sbp_management_request_login( | |||
| 358 | * reject with access_denied if any logins present | 356 | * reject with access_denied if any logins present |
| 359 | */ | 357 | */ |
| 360 | if (LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)) && | 358 | if (LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)) && |
| 361 | sbp_login_count_all_by_lun(tpg, se_lun, 0)) { | 359 | sbp_login_count_all_by_lun(tpg, unpacked_lun, 0)) { |
| 362 | pr_warn("refusing exclusive login with other active logins\n"); | 360 | pr_warn("refusing exclusive login with other active logins\n"); |
| 363 | 361 | ||
| 364 | req->status.status = cpu_to_be32( | 362 | req->status.status = cpu_to_be32( |
| @@ -371,7 +369,7 @@ static void sbp_management_request_login( | |||
| 371 | * check exclusive bit in any existing login descriptor | 369 | * check exclusive bit in any existing login descriptor |
| 372 | * reject with access_denied if any exclusive logins present | 370 | * reject with access_denied if any exclusive logins present |
| 373 | */ | 371 | */ |
| 374 | if (sbp_login_count_all_by_lun(tpg, se_lun, 1)) { | 372 | if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 1)) { |
| 375 | pr_warn("refusing login while another exclusive login present\n"); | 373 | pr_warn("refusing login while another exclusive login present\n"); |
| 376 | 374 | ||
| 377 | req->status.status = cpu_to_be32( | 375 | req->status.status = cpu_to_be32( |
| @@ -384,7 +382,7 @@ static void sbp_management_request_login( | |||
| 384 | * check we haven't exceeded the number of allowed logins | 382 | * check we haven't exceeded the number of allowed logins |
| 385 | * reject with resources_unavailable if we have | 383 | * reject with resources_unavailable if we have |
| 386 | */ | 384 | */ |
| 387 | if (sbp_login_count_all_by_lun(tpg, se_lun, 0) >= | 385 | if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 0) >= |
| 388 | tport->max_logins_per_lun) { | 386 | tport->max_logins_per_lun) { |
| 389 | pr_warn("max number of logins reached\n"); | 387 | pr_warn("max number of logins reached\n"); |
| 390 | 388 | ||
| @@ -440,7 +438,7 @@ static void sbp_management_request_login( | |||
| 440 | } | 438 | } |
| 441 | 439 | ||
| 442 | login->sess = sess; | 440 | login->sess = sess; |
| 443 | login->lun = se_lun; | 441 | login->login_lun = unpacked_lun; |
| 444 | login->status_fifo_addr = sbp2_pointer_to_addr(&req->orb.status_fifo); | 442 | login->status_fifo_addr = sbp2_pointer_to_addr(&req->orb.status_fifo); |
| 445 | login->exclusive = LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)); | 443 | login->exclusive = LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)); |
| 446 | login->login_id = atomic_inc_return(&login_id); | 444 | login->login_id = atomic_inc_return(&login_id); |
| @@ -602,7 +600,7 @@ static void sbp_management_request_logout( | |||
| 602 | } | 600 | } |
| 603 | 601 | ||
| 604 | pr_info("mgt_agent LOGOUT from LUN %d session %d\n", | 602 | pr_info("mgt_agent LOGOUT from LUN %d session %d\n", |
| 605 | login->lun->unpacked_lun, login->login_id); | 603 | login->login_lun, login->login_id); |
| 606 | 604 | ||
| 607 | if (req->node_addr != login->sess->node_id) { | 605 | if (req->node_addr != login->sess->node_id) { |
| 608 | pr_warn("logout from different node ID\n"); | 606 | pr_warn("logout from different node ID\n"); |
| @@ -1228,12 +1226,14 @@ static void sbp_handle_command(struct sbp_target_request *req) | |||
| 1228 | goto err; | 1226 | goto err; |
| 1229 | } | 1227 | } |
| 1230 | 1228 | ||
| 1231 | unpacked_lun = req->login->lun->unpacked_lun; | 1229 | unpacked_lun = req->login->login_lun; |
| 1232 | sbp_calc_data_length_direction(req, &data_length, &data_dir); | 1230 | sbp_calc_data_length_direction(req, &data_length, &data_dir); |
| 1233 | 1231 | ||
| 1234 | pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", | 1232 | pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n", |
| 1235 | req->orb_pointer, unpacked_lun, data_length, data_dir); | 1233 | req->orb_pointer, unpacked_lun, data_length, data_dir); |
| 1236 | 1234 | ||
| 1235 | /* only used for printk until we do TMRs */ | ||
| 1236 | req->se_cmd.tag = req->orb_pointer; | ||
| 1237 | if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, | 1237 | if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, |
| 1238 | req->sense_buf, unpacked_lun, data_length, | 1238 | req->sense_buf, unpacked_lun, data_length, |
| 1239 | TCM_SIMPLE_TAG, data_dir, 0)) | 1239 | TCM_SIMPLE_TAG, data_dir, 0)) |
| @@ -1707,33 +1707,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg) | |||
| 1707 | return tpg->tport_tpgt; | 1707 | return tpg->tport_tpgt; |
| 1708 | } | 1708 | } |
| 1709 | 1709 | ||
| 1710 | static u32 sbp_get_default_depth(struct se_portal_group *se_tpg) | ||
| 1711 | { | ||
| 1712 | return 1; | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | static struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg) | ||
| 1716 | { | ||
| 1717 | struct sbp_nacl *nacl; | ||
| 1718 | |||
| 1719 | nacl = kzalloc(sizeof(struct sbp_nacl), GFP_KERNEL); | ||
| 1720 | if (!nacl) { | ||
| 1721 | pr_err("Unable to allocate struct sbp_nacl\n"); | ||
| 1722 | return NULL; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | return &nacl->se_node_acl; | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | static void sbp_release_fabric_acl( | ||
| 1729 | struct se_portal_group *se_tpg, | ||
| 1730 | struct se_node_acl *se_nacl) | ||
| 1731 | { | ||
| 1732 | struct sbp_nacl *nacl = | ||
| 1733 | container_of(se_nacl, struct sbp_nacl, se_node_acl); | ||
| 1734 | kfree(nacl); | ||
| 1735 | } | ||
| 1736 | |||
| 1737 | static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) | 1710 | static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg) |
| 1738 | { | 1711 | { |
| 1739 | return 1; | 1712 | return 1; |
| @@ -1795,15 +1768,6 @@ static void sbp_set_default_node_attrs(struct se_node_acl *nacl) | |||
| 1795 | return; | 1768 | return; |
| 1796 | } | 1769 | } |
| 1797 | 1770 | ||
| 1798 | static u32 sbp_get_task_tag(struct se_cmd *se_cmd) | ||
| 1799 | { | ||
| 1800 | struct sbp_target_request *req = container_of(se_cmd, | ||
| 1801 | struct sbp_target_request, se_cmd); | ||
| 1802 | |||
| 1803 | /* only used for printk until we do TMRs */ | ||
| 1804 | return (u32)req->orb_pointer; | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | static int sbp_get_cmd_state(struct se_cmd *se_cmd) | 1771 | static int sbp_get_cmd_state(struct se_cmd *se_cmd) |
| 1808 | { | 1772 | { |
| 1809 | return 0; | 1773 | return 0; |
| @@ -1859,106 +1823,23 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd) | |||
| 1859 | return 1; | 1823 | return 1; |
| 1860 | } | 1824 | } |
| 1861 | 1825 | ||
| 1862 | /* | ||
| 1863 | * Handlers for Serial Bus Protocol 2/3 (SBP-2 / SBP-3) | ||
| 1864 | */ | ||
| 1865 | static u8 sbp_get_fabric_proto_ident(struct se_portal_group *se_tpg) | ||
| 1866 | { | ||
| 1867 | /* | ||
| 1868 | * Return a IEEE 1394 SCSI Protocol identifier for loopback operations | ||
| 1869 | * This is defined in section 7.5.1 Table 362 in spc4r17 | ||
| 1870 | */ | ||
| 1871 | return SCSI_PROTOCOL_SBP; | ||
| 1872 | } | ||
| 1873 | |||
| 1874 | static u32 sbp_get_pr_transport_id( | ||
| 1875 | struct se_portal_group *se_tpg, | ||
| 1876 | struct se_node_acl *se_nacl, | ||
| 1877 | struct t10_pr_registration *pr_reg, | ||
| 1878 | int *format_code, | ||
| 1879 | unsigned char *buf) | ||
| 1880 | { | ||
| 1881 | int ret; | ||
| 1882 | |||
| 1883 | /* | ||
| 1884 | * Set PROTOCOL IDENTIFIER to 3h for SBP | ||
| 1885 | */ | ||
| 1886 | buf[0] = SCSI_PROTOCOL_SBP; | ||
| 1887 | /* | ||
| 1888 | * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI | ||
| 1889 | * over IEEE 1394 | ||
| 1890 | */ | ||
| 1891 | ret = hex2bin(&buf[8], se_nacl->initiatorname, 8); | ||
| 1892 | if (ret < 0) | ||
| 1893 | pr_debug("sbp transport_id: invalid hex string\n"); | ||
| 1894 | |||
| 1895 | /* | ||
| 1896 | * The IEEE 1394 Transport ID is a hardcoded 24-byte length | ||
| 1897 | */ | ||
| 1898 | return 24; | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | static u32 sbp_get_pr_transport_id_len( | ||
| 1902 | struct se_portal_group *se_tpg, | ||
| 1903 | struct se_node_acl *se_nacl, | ||
| 1904 | struct t10_pr_registration *pr_reg, | ||
| 1905 | int *format_code) | ||
| 1906 | { | ||
| 1907 | *format_code = 0; | ||
| 1908 | /* | ||
| 1909 | * From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI | ||
| 1910 | * over IEEE 1394 | ||
| 1911 | * | ||
| 1912 | * The SBP Transport ID is a hardcoded 24-byte length | ||
| 1913 | */ | ||
| 1914 | return 24; | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | /* | ||
| 1918 | * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above | ||
| 1919 | * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations. | ||
| 1920 | */ | ||
| 1921 | static char *sbp_parse_pr_out_transport_id( | ||
| 1922 | struct se_portal_group *se_tpg, | ||
| 1923 | const char *buf, | ||
| 1924 | u32 *out_tid_len, | ||
| 1925 | char **port_nexus_ptr) | ||
| 1926 | { | ||
| 1927 | /* | ||
| 1928 | * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.4 TransportID | ||
| 1929 | * for initiator ports using SCSI over SBP Serial SCSI Protocol | ||
| 1930 | * | ||
| 1931 | * The TransportID for a IEEE 1394 Initiator Port is of fixed size of | ||
| 1932 | * 24 bytes, and IEEE 1394 does not contain a I_T nexus identifier, | ||
| 1933 | * so we return the **port_nexus_ptr set to NULL. | ||
| 1934 | */ | ||
| 1935 | *port_nexus_ptr = NULL; | ||
| 1936 | *out_tid_len = 24; | ||
| 1937 | |||
| 1938 | return (char *)&buf[8]; | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) | 1826 | static int sbp_count_se_tpg_luns(struct se_portal_group *tpg) |
| 1942 | { | 1827 | { |
| 1943 | int i, count = 0; | 1828 | struct se_lun *lun; |
| 1944 | 1829 | int count = 0; | |
| 1945 | spin_lock(&tpg->tpg_lun_lock); | ||
| 1946 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | ||
| 1947 | struct se_lun *se_lun = tpg->tpg_lun_list[i]; | ||
| 1948 | |||
| 1949 | if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE) | ||
| 1950 | continue; | ||
| 1951 | 1830 | ||
| 1831 | rcu_read_lock(); | ||
| 1832 | hlist_for_each_entry_rcu(lun, &tpg->tpg_lun_hlist, link) | ||
| 1952 | count++; | 1833 | count++; |
| 1953 | } | 1834 | rcu_read_unlock(); |
| 1954 | spin_unlock(&tpg->tpg_lun_lock); | ||
| 1955 | 1835 | ||
| 1956 | return count; | 1836 | return count; |
| 1957 | } | 1837 | } |
| 1958 | 1838 | ||
| 1959 | static int sbp_update_unit_directory(struct sbp_tport *tport) | 1839 | static int sbp_update_unit_directory(struct sbp_tport *tport) |
| 1960 | { | 1840 | { |
| 1961 | int num_luns, num_entries, idx = 0, mgt_agt_addr, ret, i; | 1841 | struct se_lun *lun; |
| 1842 | int num_luns, num_entries, idx = 0, mgt_agt_addr, ret; | ||
| 1962 | u32 *data; | 1843 | u32 *data; |
| 1963 | 1844 | ||
| 1964 | if (tport->unit_directory.data) { | 1845 | if (tport->unit_directory.data) { |
| @@ -2020,28 +1901,23 @@ static int sbp_update_unit_directory(struct sbp_tport *tport) | |||
| 2020 | /* unit unique ID (leaf is just after LUNs) */ | 1901 | /* unit unique ID (leaf is just after LUNs) */ |
| 2021 | data[idx++] = 0x8d000000 | (num_luns + 1); | 1902 | data[idx++] = 0x8d000000 | (num_luns + 1); |
| 2022 | 1903 | ||
| 2023 | spin_lock(&tport->tpg->se_tpg.tpg_lun_lock); | 1904 | rcu_read_lock(); |
| 2024 | for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { | 1905 | hlist_for_each_entry_rcu(lun, &tport->tpg->se_tpg.tpg_lun_hlist, link) { |
| 2025 | struct se_lun *se_lun = tport->tpg->se_tpg.tpg_lun_list[i]; | ||
| 2026 | struct se_device *dev; | 1906 | struct se_device *dev; |
| 2027 | int type; | 1907 | int type; |
| 2028 | 1908 | /* | |
| 2029 | if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE) | 1909 | * rcu_dereference_raw protected by se_lun->lun_group symlink |
| 2030 | continue; | 1910 | * reference to se_device->dev_group. |
| 2031 | 1911 | */ | |
| 2032 | spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock); | 1912 | dev = rcu_dereference_raw(lun->lun_se_dev); |
| 2033 | |||
| 2034 | dev = se_lun->lun_se_dev; | ||
| 2035 | type = dev->transport->get_device_type(dev); | 1913 | type = dev->transport->get_device_type(dev); |
| 2036 | 1914 | ||
| 2037 | /* logical_unit_number */ | 1915 | /* logical_unit_number */ |
| 2038 | data[idx++] = 0x14000000 | | 1916 | data[idx++] = 0x14000000 | |
| 2039 | ((type << 16) & 0x1f0000) | | 1917 | ((type << 16) & 0x1f0000) | |
| 2040 | (se_lun->unpacked_lun & 0xffff); | 1918 | (lun->unpacked_lun & 0xffff); |
| 2041 | |||
| 2042 | spin_lock(&tport->tpg->se_tpg.tpg_lun_lock); | ||
| 2043 | } | 1919 | } |
| 2044 | spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock); | 1920 | rcu_read_unlock(); |
| 2045 | 1921 | ||
| 2046 | /* unit unique ID leaf */ | 1922 | /* unit unique ID leaf */ |
| 2047 | data[idx++] = 2 << 16; | 1923 | data[idx++] = 2 << 16; |
| @@ -2100,48 +1976,13 @@ static ssize_t sbp_format_wwn(char *buf, size_t len, u64 wwn) | |||
| 2100 | return snprintf(buf, len, "%016llx", wwn); | 1976 | return snprintf(buf, len, "%016llx", wwn); |
| 2101 | } | 1977 | } |
| 2102 | 1978 | ||
| 2103 | static struct se_node_acl *sbp_make_nodeacl( | 1979 | static int sbp_init_nodeacl(struct se_node_acl *se_nacl, const char *name) |
| 2104 | struct se_portal_group *se_tpg, | ||
| 2105 | struct config_group *group, | ||
| 2106 | const char *name) | ||
| 2107 | { | 1980 | { |
| 2108 | struct se_node_acl *se_nacl, *se_nacl_new; | ||
| 2109 | struct sbp_nacl *nacl; | ||
| 2110 | u64 guid = 0; | 1981 | u64 guid = 0; |
| 2111 | u32 nexus_depth = 1; | ||
| 2112 | 1982 | ||
| 2113 | if (sbp_parse_wwn(name, &guid) < 0) | 1983 | if (sbp_parse_wwn(name, &guid) < 0) |
| 2114 | return ERR_PTR(-EINVAL); | 1984 | return -EINVAL; |
| 2115 | 1985 | return 0; | |
| 2116 | se_nacl_new = sbp_alloc_fabric_acl(se_tpg); | ||
| 2117 | if (!se_nacl_new) | ||
| 2118 | return ERR_PTR(-ENOMEM); | ||
| 2119 | |||
| 2120 | /* | ||
| 2121 | * se_nacl_new may be released by core_tpg_add_initiator_node_acl() | ||
| 2122 | * when converting a NodeACL from demo mode -> explict | ||
| 2123 | */ | ||
| 2124 | se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, | ||
| 2125 | name, nexus_depth); | ||
| 2126 | if (IS_ERR(se_nacl)) { | ||
| 2127 | sbp_release_fabric_acl(se_tpg, se_nacl_new); | ||
| 2128 | return se_nacl; | ||
| 2129 | } | ||
| 2130 | |||
| 2131 | nacl = container_of(se_nacl, struct sbp_nacl, se_node_acl); | ||
| 2132 | nacl->guid = guid; | ||
| 2133 | sbp_format_wwn(nacl->iport_name, SBP_NAMELEN, guid); | ||
| 2134 | |||
| 2135 | return se_nacl; | ||
| 2136 | } | ||
| 2137 | |||
| 2138 | static void sbp_drop_nodeacl(struct se_node_acl *se_acl) | ||
| 2139 | { | ||
| 2140 | struct sbp_nacl *nacl = | ||
| 2141 | container_of(se_acl, struct sbp_nacl, se_node_acl); | ||
| 2142 | |||
| 2143 | core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); | ||
| 2144 | kfree(nacl); | ||
| 2145 | } | 1986 | } |
| 2146 | 1987 | ||
| 2147 | static int sbp_post_link_lun( | 1988 | static int sbp_post_link_lun( |
| @@ -2214,8 +2055,7 @@ static struct se_portal_group *sbp_make_tpg( | |||
| 2214 | goto out_free_tpg; | 2055 | goto out_free_tpg; |
| 2215 | } | 2056 | } |
| 2216 | 2057 | ||
| 2217 | ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, tpg, | 2058 | ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP); |
| 2218 | TRANSPORT_TPG_TYPE_NORMAL); | ||
| 2219 | if (ret < 0) | 2059 | if (ret < 0) |
| 2220 | goto out_unreg_mgt_agt; | 2060 | goto out_unreg_mgt_agt; |
| 2221 | 2061 | ||
| @@ -2505,19 +2345,12 @@ static const struct target_core_fabric_ops sbp_ops = { | |||
| 2505 | .module = THIS_MODULE, | 2345 | .module = THIS_MODULE, |
| 2506 | .name = "sbp", | 2346 | .name = "sbp", |
| 2507 | .get_fabric_name = sbp_get_fabric_name, | 2347 | .get_fabric_name = sbp_get_fabric_name, |
| 2508 | .get_fabric_proto_ident = sbp_get_fabric_proto_ident, | ||
| 2509 | .tpg_get_wwn = sbp_get_fabric_wwn, | 2348 | .tpg_get_wwn = sbp_get_fabric_wwn, |
| 2510 | .tpg_get_tag = sbp_get_tag, | 2349 | .tpg_get_tag = sbp_get_tag, |
| 2511 | .tpg_get_default_depth = sbp_get_default_depth, | ||
| 2512 | .tpg_get_pr_transport_id = sbp_get_pr_transport_id, | ||
| 2513 | .tpg_get_pr_transport_id_len = sbp_get_pr_transport_id_len, | ||
| 2514 | .tpg_parse_pr_out_transport_id = sbp_parse_pr_out_transport_id, | ||
| 2515 | .tpg_check_demo_mode = sbp_check_true, | 2350 | .tpg_check_demo_mode = sbp_check_true, |
| 2516 | .tpg_check_demo_mode_cache = sbp_check_true, | 2351 | .tpg_check_demo_mode_cache = sbp_check_true, |
| 2517 | .tpg_check_demo_mode_write_protect = sbp_check_false, | 2352 | .tpg_check_demo_mode_write_protect = sbp_check_false, |
| 2518 | .tpg_check_prod_mode_write_protect = sbp_check_false, | 2353 | .tpg_check_prod_mode_write_protect = sbp_check_false, |
| 2519 | .tpg_alloc_fabric_acl = sbp_alloc_fabric_acl, | ||
| 2520 | .tpg_release_fabric_acl = sbp_release_fabric_acl, | ||
| 2521 | .tpg_get_inst_index = sbp_tpg_get_inst_index, | 2354 | .tpg_get_inst_index = sbp_tpg_get_inst_index, |
| 2522 | .release_cmd = sbp_release_cmd, | 2355 | .release_cmd = sbp_release_cmd, |
| 2523 | .shutdown_session = sbp_shutdown_session, | 2356 | .shutdown_session = sbp_shutdown_session, |
| @@ -2526,7 +2359,6 @@ static const struct target_core_fabric_ops sbp_ops = { | |||
| 2526 | .write_pending = sbp_write_pending, | 2359 | .write_pending = sbp_write_pending, |
| 2527 | .write_pending_status = sbp_write_pending_status, | 2360 | .write_pending_status = sbp_write_pending_status, |
| 2528 | .set_default_node_attributes = sbp_set_default_node_attrs, | 2361 | .set_default_node_attributes = sbp_set_default_node_attrs, |
| 2529 | .get_task_tag = sbp_get_task_tag, | ||
| 2530 | .get_cmd_state = sbp_get_cmd_state, | 2362 | .get_cmd_state = sbp_get_cmd_state, |
| 2531 | .queue_data_in = sbp_queue_data_in, | 2363 | .queue_data_in = sbp_queue_data_in, |
| 2532 | .queue_status = sbp_queue_status, | 2364 | .queue_status = sbp_queue_status, |
| @@ -2542,8 +2374,7 @@ static const struct target_core_fabric_ops sbp_ops = { | |||
| 2542 | .fabric_pre_unlink = sbp_pre_unlink_lun, | 2374 | .fabric_pre_unlink = sbp_pre_unlink_lun, |
| 2543 | .fabric_make_np = NULL, | 2375 | .fabric_make_np = NULL, |
| 2544 | .fabric_drop_np = NULL, | 2376 | .fabric_drop_np = NULL, |
| 2545 | .fabric_make_nodeacl = sbp_make_nodeacl, | 2377 | .fabric_init_nodeacl = sbp_init_nodeacl, |
| 2546 | .fabric_drop_nodeacl = sbp_drop_nodeacl, | ||
| 2547 | 2378 | ||
| 2548 | .tfc_wwn_attrs = sbp_wwn_attrs, | 2379 | .tfc_wwn_attrs = sbp_wwn_attrs, |
| 2549 | .tfc_tpg_base_attrs = sbp_tpg_base_attrs, | 2380 | .tfc_tpg_base_attrs = sbp_tpg_base_attrs, |
