aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-07-22 18:36:25 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 07:06:29 -0400
commit7c56b9fd3b6d2d933075d12abee67ceb7c90d04a (patch)
tree71edc723c736cdf55a738f8b56f83513238caebc /drivers/scsi
parent154fbf06485bbb6c28f1f7ebf462e4895613033c (diff)
[SCSI] lpfc 8.3.25: T10 DIF Fixes
T10 DIF Fixes - Fix the case where the SCSI Host supplies the CRC and driver to controller protection is on. - Only support T10 DIF type 1. LBA always goes in ref tag and app tag is not checked. - Change the format of the sense data passed up to the SCSI layer to match the Descriptor Format Sense Data found in SPC-4 sections 4.5.2.1 and 4.5.2.2. - Fix Slip PDE implementation. - Remove BUG() in else casein lpfc_sc_to_bg_opcodes. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c97
2 files changed, 33 insertions, 68 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 135a53baa735..29ccb1519226 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -3678,7 +3678,9 @@ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
3678# - Default will result in registering capabilities for all profiles. 3678# - Default will result in registering capabilities for all profiles.
3679# 3679#
3680*/ 3680*/
3681unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION; 3681unsigned int lpfc_prot_mask = SHOST_DIF_TYPE1_PROTECTION |
3682 SHOST_DIX_TYPE0_PROTECTION |
3683 SHOST_DIX_TYPE1_PROTECTION;
3682 3684
3683module_param(lpfc_prot_mask, uint, S_IRUGO); 3685module_param(lpfc_prot_mask, uint, S_IRUGO);
3684MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask"); 3686MODULE_PARM_DESC(lpfc_prot_mask, "host protection mask");
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 3ccc97496ebf..eadd241eeff1 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1302,13 +1302,13 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1302 case SCSI_PROT_NORMAL: 1302 case SCSI_PROT_NORMAL:
1303 default: 1303 default:
1304 lpfc_printf_log(phba, KERN_ERR, LOG_BG, 1304 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1305 "9063 BLKGRD: Bad op/guard:%d/%d combination\n", 1305 "9063 BLKGRD: Bad op/guard:%d/IP combination\n",
1306 scsi_get_prot_op(sc), guard_type); 1306 scsi_get_prot_op(sc));
1307 ret = 1; 1307 ret = 1;
1308 break; 1308 break;
1309 1309
1310 } 1310 }
1311 } else if (guard_type == SHOST_DIX_GUARD_CRC) { 1311 } else {
1312 switch (scsi_get_prot_op(sc)) { 1312 switch (scsi_get_prot_op(sc)) {
1313 case SCSI_PROT_READ_STRIP: 1313 case SCSI_PROT_READ_STRIP:
1314 case SCSI_PROT_WRITE_INSERT: 1314 case SCSI_PROT_WRITE_INSERT:
@@ -1324,17 +1324,18 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1324 1324
1325 case SCSI_PROT_READ_INSERT: 1325 case SCSI_PROT_READ_INSERT:
1326 case SCSI_PROT_WRITE_STRIP: 1326 case SCSI_PROT_WRITE_STRIP:
1327 *txop = BG_OP_IN_CRC_OUT_NODIF;
1328 *rxop = BG_OP_IN_NODIF_OUT_CRC;
1329 break;
1330
1327 case SCSI_PROT_NORMAL: 1331 case SCSI_PROT_NORMAL:
1328 default: 1332 default:
1329 lpfc_printf_log(phba, KERN_ERR, LOG_BG, 1333 lpfc_printf_log(phba, KERN_ERR, LOG_BG,
1330 "9075 BLKGRD: Bad op/guard:%d/%d combination\n", 1334 "9075 BLKGRD: Bad op/guard:%d/CRC combination\n",
1331 scsi_get_prot_op(sc), guard_type); 1335 scsi_get_prot_op(sc));
1332 ret = 1; 1336 ret = 1;
1333 break; 1337 break;
1334 } 1338 }
1335 } else {
1336 /* unsupported format */
1337 BUG();
1338 } 1339 }
1339 1340
1340 return ret; 1341 return ret;
@@ -1352,45 +1353,6 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
1352 return sc->device->sector_size; 1353 return sc->device->sector_size;
1353} 1354}
1354 1355
1355/**
1356 * lpfc_get_cmd_dif_parms - Extract DIF parameters from SCSI command
1357 * @sc: in: SCSI command
1358 * @apptagmask: out: app tag mask
1359 * @apptagval: out: app tag value
1360 * @reftag: out: ref tag (reference tag)
1361 *
1362 * Description:
1363 * Extract DIF parameters from the command if possible. Otherwise,
1364 * use default parameters.
1365 *
1366 **/
1367static inline void
1368lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask,
1369 uint16_t *apptagval, uint32_t *reftag)
1370{
1371 struct scsi_dif_tuple *spt;
1372 unsigned char op = scsi_get_prot_op(sc);
1373 unsigned int protcnt = scsi_prot_sg_count(sc);
1374 static int cnt;
1375
1376 if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
1377 op == SCSI_PROT_WRITE_PASS)) {
1378
1379 cnt++;
1380 spt = page_address(sg_page(scsi_prot_sglist(sc))) +
1381 scsi_prot_sglist(sc)[0].offset;
1382 *apptagmask = 0;
1383 *apptagval = 0;
1384 *reftag = cpu_to_be32(spt->ref_tag);
1385
1386 } else {
1387 /* SBC defines ref tag to be lower 32bits of LBA */
1388 *reftag = (uint32_t) (0xffffffff & scsi_get_lba(sc));
1389 *apptagmask = 0;
1390 *apptagval = 0;
1391 }
1392}
1393
1394/* 1356/*
1395 * This function sets up buffer list for protection groups of 1357 * This function sets up buffer list for protection groups of
1396 * type LPFC_PG_TYPE_NO_DIF 1358 * type LPFC_PG_TYPE_NO_DIF
@@ -1427,9 +1389,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1427 dma_addr_t physaddr; 1389 dma_addr_t physaddr;
1428 int i = 0, num_bde = 0, status; 1390 int i = 0, num_bde = 0, status;
1429 int datadir = sc->sc_data_direction; 1391 int datadir = sc->sc_data_direction;
1430 unsigned blksize;
1431 uint32_t reftag; 1392 uint32_t reftag;
1432 uint16_t apptagmask, apptagval; 1393 unsigned blksize;
1433 uint8_t txop, rxop; 1394 uint8_t txop, rxop;
1434 1395
1435 status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop); 1396 status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
@@ -1438,17 +1399,16 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1438 1399
1439 /* extract some info from the scsi command for pde*/ 1400 /* extract some info from the scsi command for pde*/
1440 blksize = lpfc_cmd_blksize(sc); 1401 blksize = lpfc_cmd_blksize(sc);
1441 lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag); 1402 reftag = scsi_get_lba(sc) & 0xffffffff;
1442 1403
1443 /* setup PDE5 with what we have */ 1404 /* setup PDE5 with what we have */
1444 pde5 = (struct lpfc_pde5 *) bpl; 1405 pde5 = (struct lpfc_pde5 *) bpl;
1445 memset(pde5, 0, sizeof(struct lpfc_pde5)); 1406 memset(pde5, 0, sizeof(struct lpfc_pde5));
1446 bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR); 1407 bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
1447 pde5->reftag = reftag;
1448 1408
1449 /* Endianness conversion if necessary for PDE5 */ 1409 /* Endianness conversion if necessary for PDE5 */
1450 pde5->word0 = cpu_to_le32(pde5->word0); 1410 pde5->word0 = cpu_to_le32(pde5->word0);
1451 pde5->reftag = cpu_to_le32(pde5->reftag); 1411 pde5->reftag = cpu_to_le32(reftag);
1452 1412
1453 /* advance bpl and increment bde count */ 1413 /* advance bpl and increment bde count */
1454 num_bde++; 1414 num_bde++;
@@ -1463,10 +1423,10 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1463 if (datadir == DMA_FROM_DEVICE) { 1423 if (datadir == DMA_FROM_DEVICE) {
1464 bf_set(pde6_ce, pde6, 1); 1424 bf_set(pde6_ce, pde6, 1);
1465 bf_set(pde6_re, pde6, 1); 1425 bf_set(pde6_re, pde6, 1);
1466 bf_set(pde6_ae, pde6, 1);
1467 } 1426 }
1468 bf_set(pde6_ai, pde6, 1); 1427 bf_set(pde6_ai, pde6, 1);
1469 bf_set(pde6_apptagval, pde6, apptagval); 1428 bf_set(pde6_ae, pde6, 0);
1429 bf_set(pde6_apptagval, pde6, 0);
1470 1430
1471 /* Endianness conversion if necessary for PDE6 */ 1431 /* Endianness conversion if necessary for PDE6 */
1472 pde6->word0 = cpu_to_le32(pde6->word0); 1432 pde6->word0 = cpu_to_le32(pde6->word0);
@@ -1551,7 +1511,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1551 unsigned char pgdone = 0, alldone = 0; 1511 unsigned char pgdone = 0, alldone = 0;
1552 unsigned blksize; 1512 unsigned blksize;
1553 uint32_t reftag; 1513 uint32_t reftag;
1554 uint16_t apptagmask, apptagval;
1555 uint8_t txop, rxop; 1514 uint8_t txop, rxop;
1556 int num_bde = 0; 1515 int num_bde = 0;
1557 1516
@@ -1571,7 +1530,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1571 1530
1572 /* extract some info from the scsi command */ 1531 /* extract some info from the scsi command */
1573 blksize = lpfc_cmd_blksize(sc); 1532 blksize = lpfc_cmd_blksize(sc);
1574 lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag); 1533 reftag = scsi_get_lba(sc) & 0xffffffff;
1575 1534
1576 split_offset = 0; 1535 split_offset = 0;
1577 do { 1536 do {
@@ -1579,11 +1538,10 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1579 pde5 = (struct lpfc_pde5 *) bpl; 1538 pde5 = (struct lpfc_pde5 *) bpl;
1580 memset(pde5, 0, sizeof(struct lpfc_pde5)); 1539 memset(pde5, 0, sizeof(struct lpfc_pde5));
1581 bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR); 1540 bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
1582 pde5->reftag = reftag;
1583 1541
1584 /* Endianness conversion if necessary for PDE5 */ 1542 /* Endianness conversion if necessary for PDE5 */
1585 pde5->word0 = cpu_to_le32(pde5->word0); 1543 pde5->word0 = cpu_to_le32(pde5->word0);
1586 pde5->reftag = cpu_to_le32(pde5->reftag); 1544 pde5->reftag = cpu_to_le32(reftag);
1587 1545
1588 /* advance bpl and increment bde count */ 1546 /* advance bpl and increment bde count */
1589 num_bde++; 1547 num_bde++;
@@ -1597,9 +1555,9 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1597 bf_set(pde6_oprx, pde6, rxop); 1555 bf_set(pde6_oprx, pde6, rxop);
1598 bf_set(pde6_ce, pde6, 1); 1556 bf_set(pde6_ce, pde6, 1);
1599 bf_set(pde6_re, pde6, 1); 1557 bf_set(pde6_re, pde6, 1);
1600 bf_set(pde6_ae, pde6, 1);
1601 bf_set(pde6_ai, pde6, 1); 1558 bf_set(pde6_ai, pde6, 1);
1602 bf_set(pde6_apptagval, pde6, apptagval); 1559 bf_set(pde6_ae, pde6, 0);
1560 bf_set(pde6_apptagval, pde6, 0);
1603 1561
1604 /* Endianness conversion if necessary for PDE6 */ 1562 /* Endianness conversion if necessary for PDE6 */
1605 pde6->word0 = cpu_to_le32(pde6->word0); 1563 pde6->word0 = cpu_to_le32(pde6->word0);
@@ -1621,8 +1579,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1621 memset(pde7, 0, sizeof(struct lpfc_pde7)); 1579 memset(pde7, 0, sizeof(struct lpfc_pde7));
1622 bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR); 1580 bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR);
1623 1581
1624 pde7->addrHigh = le32_to_cpu(putPaddrLow(protphysaddr)); 1582 pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr));
1625 pde7->addrLow = le32_to_cpu(putPaddrHigh(protphysaddr)); 1583 pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr));
1626 1584
1627 protgrp_blks = protgroup_len / 8; 1585 protgrp_blks = protgroup_len / 8;
1628 protgrp_bytes = protgrp_blks * blksize; 1586 protgrp_bytes = protgrp_blks * blksize;
@@ -1632,7 +1590,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1632 protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff); 1590 protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff);
1633 protgroup_offset += protgroup_remainder; 1591 protgroup_offset += protgroup_remainder;
1634 protgrp_blks = protgroup_remainder / 8; 1592 protgrp_blks = protgroup_remainder / 8;
1635 protgrp_bytes = protgroup_remainder * blksize; 1593 protgrp_bytes = protgrp_blks * blksize;
1636 } else { 1594 } else {
1637 protgroup_offset = 0; 1595 protgroup_offset = 0;
1638 curr_prot++; 1596 curr_prot++;
@@ -2006,16 +1964,21 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
2006 if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { 1964 if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
2007 /* 1965 /*
2008 * setup sense data descriptor 0 per SPC-4 as an information 1966 * setup sense data descriptor 0 per SPC-4 as an information
2009 * field, and put the failing LBA in it 1967 * field, and put the failing LBA in it.
1968 * This code assumes there was also a guard/app/ref tag error
1969 * indication.
2010 */ 1970 */
2011 cmd->sense_buffer[8] = 0; /* Information */ 1971 cmd->sense_buffer[7] = 0xc; /* Additional sense length */
2012 cmd->sense_buffer[9] = 0xa; /* Add. length */ 1972 cmd->sense_buffer[8] = 0; /* Information descriptor type */
1973 cmd->sense_buffer[9] = 0xa; /* Additional descriptor length */
1974 cmd->sense_buffer[10] = 0x80; /* Validity bit */
2013 bghm /= cmd->device->sector_size; 1975 bghm /= cmd->device->sector_size;
2014 1976
2015 failing_sector = scsi_get_lba(cmd); 1977 failing_sector = scsi_get_lba(cmd);
2016 failing_sector += bghm; 1978 failing_sector += bghm;
2017 1979
2018 put_unaligned_be64(failing_sector, &cmd->sense_buffer[10]); 1980 /* Descriptor Information */
1981 put_unaligned_be64(failing_sector, &cmd->sense_buffer[12]);
2019 } 1982 }
2020 1983
2021 if (!ret) { 1984 if (!ret) {