Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] bfa: scatter gather processing change

Modified scatter gather processing to use the kernel provided
scsi_for_each_sg() macro.

1) Instead of allocating and setting up sgpg in bfa_ioim_sge_setup(),
we only do allocation. As a result, we remove
bfa_ioim_sgpg_setup() and rename bfa_ioim_sge_setup() to
bfa_ioim_sgpg_alloc().

2) bfa_ioim_send_ioreq() call scsi_for_each_sg() to handle both inline
and sgpg setup.

Signed-off-by: Maggie Zhang <xmzhang@brocade.com>
Signed-off-by: Jing Huang <huangj@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

authored by

Maggie Zhang and committed by
James Bottomley
e3e7d3ee b77ee1fb

+59 -81
+59 -81
drivers/scsi/bfa/bfa_fcpim.c
··· 218 218 * forward declaration for BFA IOIM functions 219 219 */ 220 220 static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim); 221 - static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim); 222 - static void bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim); 221 + static bfa_boolean_t bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim); 223 222 static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim); 224 223 static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim); 225 224 static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete); ··· 1620 1621 } 1621 1622 1622 1623 if (ioim->nsges > BFI_SGE_INLINE) { 1623 - if (!bfa_ioim_sge_setup(ioim)) { 1624 + if (!bfa_ioim_sgpg_alloc(ioim)) { 1624 1625 bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc); 1625 1626 return; 1626 1627 } ··· 2303 2304 2304 2305 ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); 2305 2306 list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q); 2306 - bfa_ioim_sgpg_setup(ioim); 2307 + ioim->sgpg = bfa_q_first(&ioim->sgpg_q); 2307 2308 bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED); 2308 2309 } 2309 2310 ··· 2316 2317 struct bfa_itnim_s *itnim = ioim->itnim; 2317 2318 struct bfi_ioim_req_s *m; 2318 2319 static struct fcp_cmnd_s cmnd_z0 = { 0 }; 2319 - struct bfi_sge_s *sge; 2320 + struct bfi_sge_s *sge, *sgpge; 2320 2321 u32 pgdlen = 0; 2321 2322 u32 fcp_dl; 2322 2323 u64 addr; 2323 2324 struct scatterlist *sg; 2325 + struct bfa_sgpg_s *sgpg; 2324 2326 struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio; 2327 + u32 i, sge_id, pgcumsz; 2325 2328 2326 2329 /* 2327 2330 * check for room in queue to send request now ··· 2343 2342 m->rport_hdl = ioim->itnim->rport->fw_handle; 2344 2343 m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio); 2345 2344 2346 - /* 2347 - * build inline IO SG element here 2348 - */ 2349 2345 sge = &m->sges[0]; 2350 - if (ioim->nsges) { 2351 - sg = (struct scatterlist *)scsi_sglist(cmnd); 2352 - addr = bfa_os_sgaddr(sg_dma_address(sg)); 2353 - sge->sga = *(union bfi_addr_u *) &addr; 2354 - pgdlen = sg_dma_len(sg); 2355 - sge->sg_len = pgdlen; 2356 - sge->flags = (ioim->nsges > BFI_SGE_INLINE) ? 2346 + sgpg = ioim->sgpg; 2347 + sge_id = 0; 2348 + sgpge = NULL; 2349 + pgcumsz = 0; 2350 + scsi_for_each_sg(cmnd, sg, ioim->nsges, i) { 2351 + if (i == 0) { 2352 + /* build inline IO SG element */ 2353 + addr = bfa_os_sgaddr(sg_dma_address(sg)); 2354 + sge->sga = *(union bfi_addr_u *) &addr; 2355 + pgdlen = sg_dma_len(sg); 2356 + sge->sg_len = pgdlen; 2357 + sge->flags = (ioim->nsges > BFI_SGE_INLINE) ? 2357 2358 BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST; 2358 - bfa_sge_to_be(sge); 2359 - sge++; 2359 + bfa_sge_to_be(sge); 2360 + sge++; 2361 + } else { 2362 + if (sge_id == 0) 2363 + sgpge = sgpg->sgpg->sges; 2364 + 2365 + addr = bfa_os_sgaddr(sg_dma_address(sg)); 2366 + sgpge->sga = *(union bfi_addr_u *) &addr; 2367 + sgpge->sg_len = sg_dma_len(sg); 2368 + pgcumsz += sgpge->sg_len; 2369 + 2370 + /* set flags */ 2371 + if (i < (ioim->nsges - 1) && 2372 + sge_id < (BFI_SGPG_DATA_SGES - 1)) 2373 + sgpge->flags = BFI_SGE_DATA; 2374 + else if (i < (ioim->nsges - 1)) 2375 + sgpge->flags = BFI_SGE_DATA_CPL; 2376 + else 2377 + sgpge->flags = BFI_SGE_DATA_LAST; 2378 + 2379 + bfa_sge_to_le(sgpge); 2380 + 2381 + sgpge++; 2382 + if (i == (ioim->nsges - 1)) { 2383 + sgpge->flags = BFI_SGE_PGDLEN; 2384 + sgpge->sga.a32.addr_lo = 0; 2385 + sgpge->sga.a32.addr_hi = 0; 2386 + sgpge->sg_len = pgcumsz; 2387 + bfa_sge_to_le(sgpge); 2388 + } else if (++sge_id == BFI_SGPG_DATA_SGES) { 2389 + sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg); 2390 + sgpge->flags = BFI_SGE_LINK; 2391 + sgpge->sga = sgpg->sgpg_pa; 2392 + sgpge->sg_len = pgcumsz; 2393 + bfa_sge_to_le(sgpge); 2394 + sge_id = 0; 2395 + pgcumsz = 0; 2396 + } 2397 + } 2360 2398 } 2361 2399 2362 2400 if (ioim->nsges > BFI_SGE_INLINE) { ··· 2454 2414 * at queuing time. 2455 2415 */ 2456 2416 static bfa_boolean_t 2457 - bfa_ioim_sge_setup(struct bfa_ioim_s *ioim) 2417 + bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim) 2458 2418 { 2459 2419 u16 nsgpgs; 2460 2420 ··· 2474 2434 } 2475 2435 2476 2436 ioim->nsgpgs = nsgpgs; 2477 - bfa_ioim_sgpg_setup(ioim); 2437 + ioim->sgpg = bfa_q_first(&ioim->sgpg_q); 2478 2438 2479 2439 return BFA_TRUE; 2480 - } 2481 - 2482 - static void 2483 - bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim) 2484 - { 2485 - int sgeid, nsges, i; 2486 - struct bfi_sge_s *sge; 2487 - struct bfa_sgpg_s *sgpg; 2488 - u32 pgcumsz; 2489 - u64 addr; 2490 - struct scatterlist *sg; 2491 - struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio; 2492 - 2493 - sgeid = BFI_SGE_INLINE; 2494 - ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q); 2495 - 2496 - sg = scsi_sglist(cmnd); 2497 - sg = sg_next(sg); 2498 - 2499 - do { 2500 - sge = sgpg->sgpg->sges; 2501 - nsges = ioim->nsges - sgeid; 2502 - if (nsges > BFI_SGPG_DATA_SGES) 2503 - nsges = BFI_SGPG_DATA_SGES; 2504 - 2505 - pgcumsz = 0; 2506 - for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) { 2507 - addr = bfa_os_sgaddr(sg_dma_address(sg)); 2508 - sge->sga = *(union bfi_addr_u *) &addr; 2509 - sge->sg_len = sg_dma_len(sg); 2510 - pgcumsz += sge->sg_len; 2511 - 2512 - /* 2513 - * set flags 2514 - */ 2515 - if (i < (nsges - 1)) 2516 - sge->flags = BFI_SGE_DATA; 2517 - else if (sgeid < (ioim->nsges - 1)) 2518 - sge->flags = BFI_SGE_DATA_CPL; 2519 - else 2520 - sge->flags = BFI_SGE_DATA_LAST; 2521 - 2522 - bfa_sge_to_le(sge); 2523 - } 2524 - 2525 - sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg); 2526 - 2527 - /* 2528 - * set the link element of each page 2529 - */ 2530 - if (sgeid == ioim->nsges) { 2531 - sge->flags = BFI_SGE_PGDLEN; 2532 - sge->sga.a32.addr_lo = 0; 2533 - sge->sga.a32.addr_hi = 0; 2534 - } else { 2535 - sge->flags = BFI_SGE_LINK; 2536 - sge->sga = sgpg->sgpg_pa; 2537 - } 2538 - sge->sg_len = pgcumsz; 2539 - 2540 - bfa_sge_to_le(sge); 2541 - } while (sgeid < ioim->nsges); 2542 2440 } 2543 2441 2544 2442 /*