ctl_frontend_iscsi.c (256058) | ctl_frontend_iscsi.c (256065) |
---|---|
1/*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * | 1/*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Edward Tomasz Napierala under sponsorship 6 * from the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 12 unchanged lines hidden (view full) --- 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/sys/cam/ctl/ctl_frontend_iscsi.c 256058 2013-10-04 19:31:41Z trasz $ | 29 * $FreeBSD: head/sys/cam/ctl/ctl_frontend_iscsi.c 256065 2013-10-05 16:22:33Z trasz $ |
30 */ 31 32/* 33 * CTL frontend for the iSCSI protocol. 34 */ 35 36#include <sys/cdefs.h> | 30 */ 31 32/* 33 * CTL frontend for the iSCSI protocol. 34 */ 35 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_iscsi.c 256058 2013-10-04 19:31:41Z trasz $"); | 37__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl_frontend_iscsi.c 256065 2013-10-05 16:22:33Z trasz $"); |
38 39#include <sys/param.h> 40#include <sys/capability.h> 41#include <sys/condvar.h> 42#include <sys/file.h> 43#include <sys/kernel.h> 44#include <sys/kthread.h> 45#include <sys/lock.h> --- 2188 unchanged lines hidden (view full) --- 2234 break; 2235 } 2236 } 2237 mtx_unlock(&softc->lock); 2238 return (0); 2239} 2240 2241static void | 38 39#include <sys/param.h> 40#include <sys/capability.h> 41#include <sys/condvar.h> 42#include <sys/file.h> 43#include <sys/kernel.h> 44#include <sys/kthread.h> 45#include <sys/lock.h> --- 2188 unchanged lines hidden (view full) --- 2234 break; 2235 } 2236 } 2237 mtx_unlock(&softc->lock); 2238 return (0); 2239} 2240 2241static void |
2242cfiscsi_datamove(union ctl_io *io) | 2242cfiscsi_datamove_in(union ctl_io *io) |
2243{ 2244 struct cfiscsi_session *cs; 2245 struct icl_pdu *request, *response; 2246 const struct iscsi_bhs_scsi_command *bhssc; 2247 struct iscsi_bhs_data_in *bhsdi; | 2243{ 2244 struct cfiscsi_session *cs; 2245 struct icl_pdu *request, *response; 2246 const struct iscsi_bhs_scsi_command *bhssc; 2247 struct iscsi_bhs_data_in *bhsdi; |
2248 struct iscsi_bhs_r2t *bhsr2t; 2249 struct cfiscsi_data_wait *cdw; | |
2250 struct ctl_sg_entry ctl_sg_entry, *ctl_sglist; 2251 size_t copy_len, len, off; 2252 const char *addr; 2253 int ctl_sg_count, error, i; | 2248 struct ctl_sg_entry ctl_sg_entry, *ctl_sglist; 2249 size_t copy_len, len, off; 2250 const char *addr; 2251 int ctl_sg_count, error, i; |
2254 uint32_t target_transfer_tag; 2255 bool done; | |
2256 2257 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; 2258 cs = PDU_SESSION(request); 2259 2260 bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs; 2261 KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) == 2262 ISCSI_BHS_OPCODE_SCSI_COMMAND, 2263 ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND")); --- 9 unchanged lines hidden (view full) --- 2273 } 2274 2275 /* 2276 * We need to record it so that we can properly report 2277 * underflow/underflow. 2278 */ 2279 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len; 2280 | 2252 2253 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; 2254 cs = PDU_SESSION(request); 2255 2256 bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs; 2257 KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) == 2258 ISCSI_BHS_OPCODE_SCSI_COMMAND, 2259 ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND")); --- 9 unchanged lines hidden (view full) --- 2269 } 2270 2271 /* 2272 * We need to record it so that we can properly report 2273 * underflow/underflow. 2274 */ 2275 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len; 2276 |
2281 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { | |
2282#if 0 | 2277#if 0 |
2283 if (ctl_sg_count > 1) 2284 CFISCSI_SESSION_DEBUG(cs, "ctl_sg_count = %d", ctl_sg_count); | 2278 if (ctl_sg_count > 1) 2279 CFISCSI_SESSION_DEBUG(cs, "ctl_sg_count = %d", ctl_sg_count); |
2285#endif 2286 | 2280#endif 2281 |
2287 /* 2288 * This is the offset within the current SCSI command; 2289 * i.e. for the first call of datamove(), it will be 0, 2290 * and for subsequent ones it will be the sum of lengths 2291 * of previous ones. 2292 */ 2293 off = htonl(io->scsiio.kern_rel_offset); 2294 if (off > 1) 2295 CFISCSI_SESSION_DEBUG(cs, "off = %zd", off); | 2282 /* 2283 * This is the offset within the current SCSI command; 2284 * i.e. for the first call of datamove(), it will be 0, 2285 * and for subsequent ones it will be the sum of lengths 2286 * of previous ones. 2287 */ 2288 off = htonl(io->scsiio.kern_rel_offset); 2289 if (off > 1) 2290 CFISCSI_SESSION_DEBUG(cs, "off = %zd", off); |
2296 | 2291 |
2297 i = 0; 2298 addr = NULL; 2299 len = 0; 2300 response = NULL; 2301 bhsdi = NULL; 2302 for (;;) { 2303 KASSERT(i < ctl_sg_count, ("i >= ctl_sg_count")); | 2292 i = 0; 2293 addr = NULL; 2294 len = 0; 2295 response = NULL; 2296 bhsdi = NULL; 2297 for (;;) { 2298 KASSERT(i < ctl_sg_count, ("i >= ctl_sg_count")); 2299 if (response == NULL) { 2300 response = cfiscsi_pdu_new_response(request, M_NOWAIT); |
2304 if (response == NULL) { | 2301 if (response == NULL) { |
2305 response = 2306 cfiscsi_pdu_new_response(request, M_NOWAIT); 2307 if (response == NULL) { 2308 CFISCSI_SESSION_WARN(cs, "failed to " 2309 "allocate memory; dropping connection"); 2310 icl_pdu_free(request); 2311 cfiscsi_session_terminate(cs); 2312 return; 2313 } 2314 bhsdi = (struct iscsi_bhs_data_in *) 2315 response->ip_bhs; 2316 bhsdi->bhsdi_opcode = 2317 ISCSI_BHS_OPCODE_SCSI_DATA_IN; 2318 bhsdi->bhsdi_initiator_task_tag = 2319 bhssc->bhssc_initiator_task_tag; 2320 bhsdi->bhsdi_datasn = 2321 htonl(PDU_EXPDATASN(request)); 2322 PDU_EXPDATASN(request)++; 2323 bhsdi->bhsdi_buffer_offset = htonl(off); 2324 } 2325 2326 if (len == 0) { 2327 addr = ctl_sglist[i].addr; 2328 len = ctl_sglist[i].len; 2329 KASSERT(len > 0, ("len <= 0")); 2330 } 2331 2332 copy_len = len; 2333 if (response->ip_data_len + copy_len > 2334 cs->cs_max_data_segment_length) 2335 copy_len = cs->cs_max_data_segment_length - 2336 response->ip_data_len; 2337 KASSERT(copy_len <= len, ("copy_len > len")); 2338 error = icl_pdu_append_data(response, addr, copy_len, M_NOWAIT); 2339 if (error != 0) { | |
2340 CFISCSI_SESSION_WARN(cs, "failed to " 2341 "allocate memory; dropping connection"); 2342 icl_pdu_free(request); | 2302 CFISCSI_SESSION_WARN(cs, "failed to " 2303 "allocate memory; dropping connection"); 2304 icl_pdu_free(request); |
2343 icl_pdu_free(response); | |
2344 cfiscsi_session_terminate(cs); 2345 return; 2346 } | 2305 cfiscsi_session_terminate(cs); 2306 return; 2307 } |
2347 addr += copy_len; 2348 len -= copy_len; 2349 off += copy_len; 2350 io->scsiio.ext_data_filled += copy_len; | 2308 bhsdi = (struct iscsi_bhs_data_in *)response->ip_bhs; 2309 bhsdi->bhsdi_opcode = ISCSI_BHS_OPCODE_SCSI_DATA_IN; 2310 bhsdi->bhsdi_initiator_task_tag = 2311 bhssc->bhssc_initiator_task_tag; 2312 bhsdi->bhsdi_datasn = htonl(PDU_EXPDATASN(request)); 2313 PDU_EXPDATASN(request)++; 2314 bhsdi->bhsdi_buffer_offset = htonl(off); 2315 } |
2351 | 2316 |
2352 if (len == 0) { 2353 /* 2354 * End of scatter-gather segment; 2355 * proceed to the next one... 2356 */ 2357 if (i == ctl_sg_count - 1) { 2358 /* 2359 * ... unless this was the last one. 2360 */ 2361 break; 2362 } 2363 i++; 2364 } | 2317 if (len == 0) { 2318 addr = ctl_sglist[i].addr; 2319 len = ctl_sglist[i].len; 2320 KASSERT(len > 0, ("len <= 0")); 2321 } |
2365 | 2322 |
2366 if (response->ip_data_len == 2367 cs->cs_max_data_segment_length) { | 2323 copy_len = len; 2324 if (response->ip_data_len + copy_len > 2325 cs->cs_max_data_segment_length) 2326 copy_len = cs->cs_max_data_segment_length - 2327 response->ip_data_len; 2328 KASSERT(copy_len <= len, ("copy_len > len")); 2329 error = icl_pdu_append_data(response, addr, copy_len, M_NOWAIT); 2330 if (error != 0) { 2331 CFISCSI_SESSION_WARN(cs, "failed to " 2332 "allocate memory; dropping connection"); 2333 icl_pdu_free(request); 2334 icl_pdu_free(response); 2335 cfiscsi_session_terminate(cs); 2336 return; 2337 } 2338 addr += copy_len; 2339 len -= copy_len; 2340 off += copy_len; 2341 io->scsiio.ext_data_filled += copy_len; 2342 2343 if (len == 0) { 2344 /* 2345 * End of scatter-gather segment; 2346 * proceed to the next one... 2347 */ 2348 if (i == ctl_sg_count - 1) { |
2368 /* | 2349 /* |
2369 * Can't stuff more data into the current PDU; 2370 * queue it. Note that's not enough to check 2371 * for kern_data_resid == 0 instead; there 2372 * may be several Data-In PDUs for the final 2373 * call to cfiscsi_datamove(), and we want 2374 * to set the F flag only on the last of them. | 2350 * ... unless this was the last one. |
2375 */ | 2351 */ |
2376 if (off == io->scsiio.kern_total_len) 2377 bhsdi->bhsdi_flags |= BHSDI_FLAGS_F; 2378 KASSERT(response->ip_data_len > 0, 2379 ("sending empty Data-In")); 2380 cfiscsi_pdu_queue(response); 2381 response = NULL; 2382 bhsdi = NULL; | 2352 break; |
2383 } | 2353 } |
2354 i++; |
|
2384 } | 2355 } |
2385 KASSERT(i == ctl_sg_count - 1, ("missed SG segment")); 2386 KASSERT(len == 0, ("missed data from SG segment")); 2387 if (response != NULL) { 2388 if (off == io->scsiio.kern_total_len) { | 2356 2357 if (response->ip_data_len == cs->cs_max_data_segment_length) { 2358 /* 2359 * Can't stuff more data into the current PDU; 2360 * queue it. Note that's not enough to check 2361 * for kern_data_resid == 0 instead; there 2362 * may be several Data-In PDUs for the final 2363 * call to cfiscsi_datamove(), and we want 2364 * to set the F flag only on the last of them. 2365 */ 2366 if (off == io->scsiio.kern_total_len) |
2389 bhsdi->bhsdi_flags |= BHSDI_FLAGS_F; | 2367 bhsdi->bhsdi_flags |= BHSDI_FLAGS_F; |
2390 } else { 2391 CFISCSI_SESSION_DEBUG(cs, "not setting the F flag; " 2392 "have %zd, need %zd", off, 2393 (size_t)io->scsiio.kern_total_len); 2394 } | |
2395 KASSERT(response->ip_data_len > 0, 2396 ("sending empty Data-In")); 2397 cfiscsi_pdu_queue(response); | 2368 KASSERT(response->ip_data_len > 0, 2369 ("sending empty Data-In")); 2370 cfiscsi_pdu_queue(response); |
2371 response = NULL; 2372 bhsdi = NULL; |
|
2398 } | 2373 } |
2374 } 2375 KASSERT(i == ctl_sg_count - 1, ("missed SG segment")); 2376 KASSERT(len == 0, ("missed data from SG segment")); 2377 if (response != NULL) { 2378 if (off == io->scsiio.kern_total_len) { 2379 bhsdi->bhsdi_flags |= BHSDI_FLAGS_F; 2380 } else { 2381 CFISCSI_SESSION_DEBUG(cs, "not setting the F flag; " 2382 "have %zd, need %zd", off, 2383 (size_t)io->scsiio.kern_total_len); 2384 } 2385 KASSERT(response->ip_data_len > 0, ("sending empty Data-In")); 2386 cfiscsi_pdu_queue(response); 2387 } |
|
2399 | 2388 |
2400 io->scsiio.be_move_done(io); 2401 } else { 2402 CFISCSI_SESSION_LOCK(cs); 2403 target_transfer_tag = cs->cs_target_transfer_tag; 2404 cs->cs_target_transfer_tag++; 2405 CFISCSI_SESSION_UNLOCK(cs); | 2389 io->scsiio.be_move_done(io); 2390} |
2406 | 2391 |
2392static void 2393cfiscsi_datamove_out(union ctl_io *io) 2394{ 2395 struct cfiscsi_session *cs; 2396 struct icl_pdu *request, *response; 2397 const struct iscsi_bhs_scsi_command *bhssc; 2398 struct iscsi_bhs_r2t *bhsr2t; 2399 struct cfiscsi_data_wait *cdw; 2400 uint32_t target_transfer_tag; 2401 bool done; 2402 2403 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; 2404 cs = PDU_SESSION(request); 2405 2406 bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs; 2407 KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) == 2408 ISCSI_BHS_OPCODE_SCSI_COMMAND, 2409 ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND")); 2410 2411 /* 2412 * We need to record it so that we can properly report 2413 * underflow/underflow. 2414 */ 2415 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len; 2416 2417 CFISCSI_SESSION_LOCK(cs); 2418 target_transfer_tag = cs->cs_target_transfer_tag; 2419 cs->cs_target_transfer_tag++; 2420 CFISCSI_SESSION_UNLOCK(cs); 2421 |
|
2407#if 0 | 2422#if 0 |
2408 CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator " 2409 "task tag 0x%x, target transfer tag 0x%x", 2410 bhssc->bhssc_initiator_task_tag, target_transfer_tag); | 2423 CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator " 2424 "task tag 0x%x, target transfer tag 0x%x", 2425 bhssc->bhssc_initiator_task_tag, target_transfer_tag); |
2411#endif | 2426#endif |
2412 cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO); 2413 if (cdw == NULL) { 2414 CFISCSI_SESSION_WARN(cs, "failed to " 2415 "allocate memory; dropping connection"); 2416 icl_pdu_free(request); 2417 cfiscsi_session_terminate(cs); | 2427 cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO); 2428 if (cdw == NULL) { 2429 CFISCSI_SESSION_WARN(cs, "failed to " 2430 "allocate memory; dropping connection"); 2431 icl_pdu_free(request); 2432 cfiscsi_session_terminate(cs); 2433 } 2434 cdw->cdw_ctl_io = io; 2435 cdw->cdw_target_transfer_tag = htonl(target_transfer_tag); 2436 cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag; 2437 2438 if (cs->cs_immediate_data && icl_pdu_data_segment_length(request) > 0) { 2439 done = cfiscsi_handle_data_segment(request, cdw); 2440 if (done) { 2441 uma_zfree(cfiscsi_data_wait_zone, cdw); 2442 io->scsiio.be_move_done(io); 2443 return; |
2418 } | 2444 } |
2419 cdw->cdw_ctl_io = io; 2420 cdw->cdw_target_transfer_tag = htonl(target_transfer_tag); 2421 cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag; | |
2422 | 2445 |
2423 if (cs->cs_immediate_data && 2424 icl_pdu_data_segment_length(request) > 0) { 2425 done = cfiscsi_handle_data_segment(request, cdw); 2426 if (done) { 2427 uma_zfree(cfiscsi_data_wait_zone, cdw); 2428 io->scsiio.be_move_done(io); 2429 return; 2430 } 2431 | |
2432#if 0 | 2446#if 0 |
2433 if (io->scsiio.ext_data_filled != 0) 2434 CFISCSI_SESSION_DEBUG(cs, "got %zd bytes of immediate data, need %zd", 2435 io->scsiio.ext_data_filled, io->scsiio.kern_data_len); | 2447 if (io->scsiio.ext_data_filled != 0) 2448 CFISCSI_SESSION_DEBUG(cs, "got %zd bytes of immediate data, need %zd", 2449 io->scsiio.ext_data_filled, io->scsiio.kern_data_len); |
2436#endif | 2450#endif |
2437 } | 2451 } |
2438 | 2452 |
2439 CFISCSI_SESSION_LOCK(cs); 2440 TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next); 2441 CFISCSI_SESSION_UNLOCK(cs); | 2453 CFISCSI_SESSION_LOCK(cs); 2454 TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next); 2455 CFISCSI_SESSION_UNLOCK(cs); |
2442 | 2456 |
2443 /* 2444 * XXX: We should limit the number of outstanding R2T PDUs 2445 * per task to MaxOutstandingR2T. 2446 */ 2447 response = cfiscsi_pdu_new_response(request, M_NOWAIT); 2448 if (response == NULL) { 2449 CFISCSI_SESSION_WARN(cs, "failed to " 2450 "allocate memory; dropping connection"); 2451 icl_pdu_free(request); 2452 cfiscsi_session_terminate(cs); 2453 } 2454 bhsr2t = (struct iscsi_bhs_r2t *)response->ip_bhs; 2455 bhsr2t->bhsr2t_opcode = ISCSI_BHS_OPCODE_R2T; 2456 bhsr2t->bhsr2t_flags = 0x80; 2457 bhsr2t->bhsr2t_lun = bhssc->bhssc_lun; 2458 bhsr2t->bhsr2t_initiator_task_tag = 2459 bhssc->bhssc_initiator_task_tag; 2460 bhsr2t->bhsr2t_target_transfer_tag = 2461 htonl(target_transfer_tag); 2462 /* 2463 * XXX: Here we assume that cfiscsi_datamove() won't ever 2464 * be running concurrently on several CPUs for a given 2465 * command. 2466 */ 2467 bhsr2t->bhsr2t_r2tsn = htonl(PDU_R2TSN(request)); 2468 PDU_R2TSN(request)++; 2469 /* 2470 * This is the offset within the current SCSI command; 2471 * i.e. for the first call of datamove(), it will be 0, 2472 * and for subsequent ones it will be the sum of lengths 2473 * of previous ones. 2474 * 2475 * The ext_data_filled is to account for unsolicited 2476 * (immediate) data that might have already arrived. 2477 */ 2478 bhsr2t->bhsr2t_buffer_offset = 2479 htonl(io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled); 2480 /* 2481 * This is the total length (sum of S/G lengths) this call 2482 * to cfiscsi_datamove() is supposed to handle. 2483 * 2484 * XXX: Limit it to MaxBurstLength. 2485 */ 2486 bhsr2t->bhsr2t_desired_data_transfer_length = 2487 htonl(io->scsiio.kern_data_len - io->scsiio.ext_data_filled); 2488 cfiscsi_pdu_queue(response); | 2457 /* 2458 * XXX: We should limit the number of outstanding R2T PDUs 2459 * per task to MaxOutstandingR2T. 2460 */ 2461 response = cfiscsi_pdu_new_response(request, M_NOWAIT); 2462 if (response == NULL) { 2463 CFISCSI_SESSION_WARN(cs, "failed to " 2464 "allocate memory; dropping connection"); 2465 icl_pdu_free(request); 2466 cfiscsi_session_terminate(cs); |
2489 } | 2467 } |
2468 bhsr2t = (struct iscsi_bhs_r2t *)response->ip_bhs; 2469 bhsr2t->bhsr2t_opcode = ISCSI_BHS_OPCODE_R2T; 2470 bhsr2t->bhsr2t_flags = 0x80; 2471 bhsr2t->bhsr2t_lun = bhssc->bhssc_lun; 2472 bhsr2t->bhsr2t_initiator_task_tag = bhssc->bhssc_initiator_task_tag; 2473 bhsr2t->bhsr2t_target_transfer_tag = htonl(target_transfer_tag); 2474 /* 2475 * XXX: Here we assume that cfiscsi_datamove() won't ever 2476 * be running concurrently on several CPUs for a given 2477 * command. 2478 */ 2479 bhsr2t->bhsr2t_r2tsn = htonl(PDU_R2TSN(request)); 2480 PDU_R2TSN(request)++; 2481 /* 2482 * This is the offset within the current SCSI command; 2483 * i.e. for the first call of datamove(), it will be 0, 2484 * and for subsequent ones it will be the sum of lengths 2485 * of previous ones. 2486 * 2487 * The ext_data_filled is to account for unsolicited 2488 * (immediate) data that might have already arrived. 2489 */ 2490 bhsr2t->bhsr2t_buffer_offset = 2491 htonl(io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled); 2492 /* 2493 * This is the total length (sum of S/G lengths) this call 2494 * to cfiscsi_datamove() is supposed to handle. 2495 * 2496 * XXX: Limit it to MaxBurstLength. 2497 */ 2498 bhsr2t->bhsr2t_desired_data_transfer_length = 2499 htonl(io->scsiio.kern_data_len - io->scsiio.ext_data_filled); 2500 cfiscsi_pdu_queue(response); |
|
2490} 2491 2492static void | 2501} 2502 2503static void |
2504cfiscsi_datamove(union ctl_io *io) 2505{ 2506 2507 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) 2508 cfiscsi_datamove_in(io); 2509 else 2510 cfiscsi_datamove_out(io); 2511} 2512 2513static void |
|
2493cfiscsi_scsi_command_done(union ctl_io *io) 2494{ 2495 struct icl_pdu *request, *response; 2496 struct iscsi_bhs_scsi_command *bhssc; 2497 struct iscsi_bhs_scsi_response *bhssr; 2498#ifdef DIAGNOSTIC 2499 struct cfiscsi_data_wait *cdw; 2500#endif --- 170 unchanged lines hidden --- | 2514cfiscsi_scsi_command_done(union ctl_io *io) 2515{ 2516 struct icl_pdu *request, *response; 2517 struct iscsi_bhs_scsi_command *bhssc; 2518 struct iscsi_bhs_scsi_response *bhssr; 2519#ifdef DIAGNOSTIC 2520 struct cfiscsi_data_wait *cdw; 2521#endif --- 170 unchanged lines hidden --- |