@@ -1073,39 +1073,66 @@ static void usbg_cmd_work(struct work_struct *work)
10731073 usbg_cleanup_cmd (cmd );
10741074}
10751075
1076+ static struct usbg_cmd * usbg_get_cmd (struct f_uas * fu ,
1077+ struct tcm_usbg_nexus * tv_nexus , u32 scsi_tag )
1078+ {
1079+ struct se_session * se_sess = tv_nexus -> tvn_se_sess ;
1080+ struct usbg_cmd * cmd ;
1081+ int tag ;
1082+
1083+ tag = percpu_ida_alloc (& se_sess -> sess_tag_pool , GFP_ATOMIC );
1084+ if (tag < 0 )
1085+ return ERR_PTR (- ENOMEM );
1086+
1087+ cmd = & ((struct usbg_cmd * )se_sess -> sess_cmd_map )[tag ];
1088+ memset (cmd , 0 , sizeof (* cmd ));
1089+ cmd -> se_cmd .map_tag = tag ;
1090+ cmd -> se_cmd .tag = cmd -> tag = scsi_tag ;
1091+ cmd -> fu = fu ;
1092+
1093+ return cmd ;
1094+ }
1095+
1096+ static void usbg_release_cmd (struct se_cmd * );
1097+
10761098static int usbg_submit_command (struct f_uas * fu ,
10771099 void * cmdbuf , unsigned int len )
10781100{
10791101 struct command_iu * cmd_iu = cmdbuf ;
10801102 struct usbg_cmd * cmd ;
1081- struct usbg_tpg * tpg ;
1082- struct tcm_usbg_nexus * tv_nexus ;
1103+ struct usbg_tpg * tpg = fu -> tpg ;
1104+ struct tcm_usbg_nexus * tv_nexus = tpg -> tpg_nexus ;
10831105 u32 cmd_len ;
1106+ u16 scsi_tag ;
10841107
10851108 if (cmd_iu -> iu_id != IU_ID_COMMAND ) {
10861109 pr_err ("Unsupported type %d\n" , cmd_iu -> iu_id );
10871110 return - EINVAL ;
10881111 }
10891112
1090- cmd = kzalloc (sizeof (* cmd ), GFP_ATOMIC );
1091- if (!cmd )
1092- return - ENOMEM ;
1113+ tv_nexus = tpg -> tpg_nexus ;
1114+ if (!tv_nexus ) {
1115+ pr_err ("Missing nexus, ignoring command\n" );
1116+ return - EINVAL ;
1117+ }
10931118
1094- cmd -> fu = fu ;
1119+ cmd_len = (cmd_iu -> len & ~0x3 ) + 16 ;
1120+ if (cmd_len > USBG_MAX_CMD )
1121+ return - EINVAL ;
1122+
1123+ scsi_tag = be16_to_cpup (& cmd_iu -> tag );
1124+ cmd = usbg_get_cmd (fu , tv_nexus , scsi_tag );
1125+ if (IS_ERR (cmd )) {
1126+ pr_err ("usbg_get_cmd failed\n" );
1127+ return - ENOMEM ;
1128+ }
10951129
10961130 /* XXX until I figure out why I can't free in on complete */
10971131 kref_init (& cmd -> ref );
10981132 kref_get (& cmd -> ref );
10991133
1100- tpg = fu -> tpg ;
1101- cmd_len = (cmd_iu -> len & ~0x3 ) + 16 ;
1102- if (cmd_len > USBG_MAX_CMD )
1103- goto err ;
1104-
11051134 memcpy (cmd -> cmd_buf , cmd_iu -> cdb , cmd_len );
11061135
1107- cmd -> tag = be16_to_cpup (& cmd_iu -> tag );
1108- cmd -> se_cmd .tag = cmd -> tag ;
11091136 if (fu -> flags & USBG_USE_STREAMS ) {
11101137 if (cmd -> tag > UASP_SS_EP_COMP_NUM_STREAMS )
11111138 goto err ;
@@ -1117,12 +1144,6 @@ static int usbg_submit_command(struct f_uas *fu,
11171144 cmd -> stream = & fu -> stream [0 ];
11181145 }
11191146
1120- tv_nexus = tpg -> tpg_nexus ;
1121- if (!tv_nexus ) {
1122- pr_err ("Missing nexus, ignoring command\n" );
1123- goto err ;
1124- }
1125-
11261147 switch (cmd_iu -> prio_attr & 0x7 ) {
11271148 case UAS_HEAD_TAG :
11281149 cmd -> prio_attr = TCM_HEAD_TAG ;
@@ -1148,7 +1169,7 @@ static int usbg_submit_command(struct f_uas *fu,
11481169
11491170 return 0 ;
11501171err :
1151- kfree ( cmd );
1172+ usbg_release_cmd ( & cmd -> se_cmd );
11521173 return - EINVAL ;
11531174}
11541175
@@ -1190,7 +1211,7 @@ static int bot_submit_command(struct f_uas *fu,
11901211{
11911212 struct bulk_cb_wrap * cbw = cmdbuf ;
11921213 struct usbg_cmd * cmd ;
1193- struct usbg_tpg * tpg ;
1214+ struct usbg_tpg * tpg = fu -> tpg ;
11941215 struct tcm_usbg_nexus * tv_nexus ;
11951216 u32 cmd_len ;
11961217
@@ -1207,28 +1228,25 @@ static int bot_submit_command(struct f_uas *fu,
12071228 if (cmd_len < 1 || cmd_len > 16 )
12081229 return - EINVAL ;
12091230
1210- cmd = kzalloc (sizeof (* cmd ), GFP_ATOMIC );
1211- if (!cmd )
1212- return - ENOMEM ;
1231+ tv_nexus = tpg -> tpg_nexus ;
1232+ if (!tv_nexus ) {
1233+ pr_err ("Missing nexus, ignoring command\n" );
1234+ return - ENODEV ;
1235+ }
12131236
1214- cmd -> fu = fu ;
1237+ cmd = usbg_get_cmd (fu , tv_nexus , cbw -> Tag );
1238+ if (IS_ERR (cmd )) {
1239+ pr_err ("usbg_get_cmd failed\n" );
1240+ return - ENOMEM ;
1241+ }
12151242
12161243 /* XXX until I figure out why I can't free in on complete */
12171244 kref_init (& cmd -> ref );
12181245 kref_get (& cmd -> ref );
12191246
1220- tpg = fu -> tpg ;
1221-
12221247 memcpy (cmd -> cmd_buf , cbw -> CDB , cmd_len );
12231248
12241249 cmd -> bot_tag = cbw -> Tag ;
1225-
1226- tv_nexus = tpg -> tpg_nexus ;
1227- if (!tv_nexus ) {
1228- pr_err ("Missing nexus, ignoring command\n" );
1229- goto err ;
1230- }
1231-
12321250 cmd -> prio_attr = TCM_SIMPLE_TAG ;
12331251 cmd -> unpacked_lun = cbw -> Lun ;
12341252 cmd -> is_read = cbw -> Flags & US_BULK_FLAG_IN ? 1 : 0 ;
@@ -1239,9 +1257,6 @@ static int bot_submit_command(struct f_uas *fu,
12391257 queue_work (tpg -> workqueue , & cmd -> work );
12401258
12411259 return 0 ;
1242- err :
1243- kfree (cmd );
1244- return - EINVAL ;
12451260}
12461261
12471262/* Start fabric.c code */
@@ -1294,8 +1309,10 @@ static void usbg_release_cmd(struct se_cmd *se_cmd)
12941309{
12951310 struct usbg_cmd * cmd = container_of (se_cmd , struct usbg_cmd ,
12961311 se_cmd );
1312+ struct se_session * se_sess = se_cmd -> se_sess ;
1313+
12971314 kfree (cmd -> data_buf );
1298- kfree ( cmd );
1315+ percpu_ida_free ( & se_sess -> sess_tag_pool , se_cmd -> map_tag );
12991316}
13001317
13011318static int usbg_shutdown_session (struct se_session * se_sess )
@@ -1607,7 +1624,9 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
16071624 goto out_unlock ;
16081625 }
16091626
1610- tv_nexus -> tvn_se_sess = target_alloc_session (& tpg -> se_tpg , 0 , 0 ,
1627+ tv_nexus -> tvn_se_sess = target_alloc_session (& tpg -> se_tpg ,
1628+ USB_G_DEFAULT_SESSION_TAGS ,
1629+ sizeof (struct usbg_cmd ),
16111630 TARGET_PROT_NORMAL , name ,
16121631 tv_nexus , usbg_alloc_sess_cb );
16131632 if (IS_ERR (tv_nexus -> tvn_se_sess )) {
0 commit comments