tree: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next head: 1c356ec5e932c8d4c83d9782ab3c4164b6471d5d commit: 016d5c35e27824f31c394009dd0f72f2c6b0dc85 [182/194] scsi: mpt3sas: SGL to PRP Translation for I/Os to NVMe devices config: i386-randconfig-x071-201744 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: git checkout 016d5c35e27824f31c394009dd0f72f2c6b0dc85 # save the attached .config to linux build tree make ARCH=i386
All warnings (new ones prefixed by >>):
drivers/scsi//mpt3sas/mpt3sas_base.c: In function 'base_make_prp_nvme':
>> drivers/scsi//mpt3sas/mpt3sas_base.c:1418:13: warning: cast from pointer to
>> integer of different size [-Wpointer-to-int-cast]
msg_phys = (dma_addr_t)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
^
vim +1418 drivers/scsi//mpt3sas/mpt3sas_base.c
1347
1348 /**
1349 * base_make_prp_nvme -
1350 * Prepare PRPs(Physical Region Page)- SGLs specific to NVMe drives only
1351 *
1352 * @ioc: per adapter object
1353 * @scmd: SCSI command from the mid-layer
1354 * @mpi_request: mpi request
1355 * @smid: msg Index
1356 * @sge_count: scatter gather element count.
1357 *
1358 * Returns: true: PRPs are built
1359 * false: IEEE SGLs needs to be built
1360 */
1361 void
1362 base_make_prp_nvme(struct MPT3SAS_ADAPTER *ioc,
1363 struct scsi_cmnd *scmd,
1364 Mpi25SCSIIORequest_t *mpi_request,
1365 u16 smid, int sge_count)
1366 {
1367 int sge_len, offset, num_prp_in_chain = 0;
1368 Mpi25IeeeSgeChain64_t *main_chain_element, *ptr_first_sgl;
1369 u64 *curr_buff;
1370 dma_addr_t msg_phys;
1371 u64 sge_addr;
1372 u32 page_mask, page_mask_result;
1373 struct scatterlist *sg_scmd;
1374 u32 first_prp_len;
1375 int data_len = scsi_bufflen(scmd);
1376 u32 nvme_pg_size;
1377
1378 nvme_pg_size = max_t(u32, ioc->page_size, NVME_PRP_PAGE_SIZE);
1379 /*
1380 * Nvme has a very convoluted prp format. One prp is required
1381 * for each page or partial page. Driver need to split up OS
sg_list
1382 * entries if it is longer than one page or cross a page
1383 * boundary. Driver also have to insert a PRP list pointer
entry as
1384 * the last entry in each physical page of the PRP list.
1385 *
1386 * NOTE: The first PRP "entry" is actually placed in the first
1387 * SGL entry in the main message as IEEE 64 format. The 2nd
1388 * entry in the main message is the chain element, and the rest
1389 * of the PRP entries are built in the contiguous pcie buffer.
1390 */
1391 page_mask = nvme_pg_size - 1;
1392
1393 /*
1394 * Native SGL is needed.
1395 * Put a chain element in main message frame that points to the
first
1396 * chain buffer.
1397 *
1398 * NOTE: The ChainOffset field must be 0 when using a chain
pointer to
1399 * a native SGL.
1400 */
1401
1402 /* Set main message chain element pointer */
1403 main_chain_element = (pMpi25IeeeSgeChain64_t)&mpi_request->SGL;
1404 /*
1405 * For NVMe the chain element needs to be the 2nd SG entry in
the main
1406 * message.
1407 */
1408 main_chain_element = (Mpi25IeeeSgeChain64_t *)
1409 ((u8 *)main_chain_element +
sizeof(MPI25_IEEE_SGE_CHAIN64));
1410
1411 /*
1412 * For the PRP entries, use the specially allocated buffer of
1413 * contiguous memory. Normal chain buffers can't be used
1414 * because each chain buffer would need to be the size of an OS
1415 * page (4k).
1416 */
1417 curr_buff = mpt3sas_base_get_pcie_sgl(ioc, smid);
> 1418 msg_phys = (dma_addr_t)mpt3sas_base_get_pcie_sgl_dma(ioc, smid);
1419
1420 main_chain_element->Address = cpu_to_le64(msg_phys);
1421 main_chain_element->NextChainOffset = 0;
1422 main_chain_element->Flags = MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
1423 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR |
1424 MPI26_IEEE_SGE_FLAGS_NSF_NVME_PRP;
1425
1426 /* Build first prp, sge need not to be page aligned*/
1427 ptr_first_sgl = (pMpi25IeeeSgeChain64_t)&mpi_request->SGL;
1428 sg_scmd = scsi_sglist(scmd);
1429 sge_addr = sg_dma_address(sg_scmd);
1430 sge_len = sg_dma_len(sg_scmd);
1431
1432 offset = (u32)(sge_addr & page_mask);
1433 first_prp_len = nvme_pg_size - offset;
1434
1435 ptr_first_sgl->Address = cpu_to_le64(sge_addr);
1436 ptr_first_sgl->Length = cpu_to_le32(first_prp_len);
1437
1438 data_len -= first_prp_len;
1439
1440 if (sge_len > first_prp_len) {
1441 sge_addr += first_prp_len;
1442 sge_len -= first_prp_len;
1443 } else if (data_len && (sge_len == first_prp_len)) {
1444 sg_scmd = sg_next(sg_scmd);
1445 sge_addr = sg_dma_address(sg_scmd);
1446 sge_len = sg_dma_len(sg_scmd);
1447 }
1448
1449 for (;;) {
1450 offset = (u32)(sge_addr & page_mask);
1451
1452 /* Put PRP pointer due to page boundary*/
1453 page_mask_result = (uintptr_t)(curr_buff + 1) &
page_mask;
1454 if (unlikely(!page_mask_result)) {
1455 scmd_printk(KERN_NOTICE,
1456 scmd, "page boundary curr_buff: 0x%p\n",
1457 curr_buff);
1458 msg_phys += 8;
1459 *curr_buff = cpu_to_le64(msg_phys);
1460 curr_buff++;
1461 num_prp_in_chain++;
1462 }
1463
1464 *curr_buff = cpu_to_le64(sge_addr);
1465 curr_buff++;
1466 msg_phys += 8;
1467 num_prp_in_chain++;
1468
1469 sge_addr += nvme_pg_size;
1470 sge_len -= nvme_pg_size;
1471 data_len -= nvme_pg_size;
1472
1473 if (data_len <= 0)
1474 break;
1475
1476 if (sge_len > 0)
1477 continue;
1478
1479 sg_scmd = sg_next(sg_scmd);
1480 sge_addr = sg_dma_address(sg_scmd);
1481 sge_len = sg_dma_len(sg_scmd);
1482 }
1483
1484 main_chain_element->Length =
1485 cpu_to_le32(num_prp_in_chain * sizeof(u64));
1486 return;
1487 }
1488
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
.config.gz
Description: application/gzip

