diff options
Diffstat (limited to 'drivers/block/mtip32xx/mtip32xx.c')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 250 |
1 files changed, 158 insertions, 92 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 52b2f2a71470..516026954be6 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -41,10 +41,31 @@ | |||
41 | #include "mtip32xx.h" | 41 | #include "mtip32xx.h" |
42 | 42 | ||
43 | #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) | 43 | #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) |
44 | #define HW_CMD_TBL_SZ (AHCI_CMD_TBL_HDR_SZ + (MTIP_MAX_SG * 16)) | 44 | |
45 | #define HW_CMD_TBL_AR_SZ (HW_CMD_TBL_SZ * MTIP_MAX_COMMAND_SLOTS) | 45 | /* DMA region containing RX Fis, Identify, RLE10, and SMART buffers */ |
46 | #define HW_PORT_PRIV_DMA_SZ \ | 46 | #define AHCI_RX_FIS_SZ 0x100 |
47 | (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) | 47 | #define AHCI_RX_FIS_OFFSET 0x0 |
48 | #define AHCI_IDFY_SZ ATA_SECT_SIZE | ||
49 | #define AHCI_IDFY_OFFSET 0x400 | ||
50 | #define AHCI_SECTBUF_SZ ATA_SECT_SIZE | ||
51 | #define AHCI_SECTBUF_OFFSET 0x800 | ||
52 | #define AHCI_SMARTBUF_SZ ATA_SECT_SIZE | ||
53 | #define AHCI_SMARTBUF_OFFSET 0xC00 | ||
54 | /* 0x100 + 0x200 + 0x200 + 0x200 is smaller than 4k but we pad it out */ | ||
55 | #define BLOCK_DMA_ALLOC_SZ 4096 | ||
56 | |||
57 | /* DMA region containing command table (should be 8192 bytes) */ | ||
58 | #define AHCI_CMD_SLOT_SZ sizeof(struct mtip_cmd_hdr) | ||
59 | #define AHCI_CMD_TBL_SZ (MTIP_MAX_COMMAND_SLOTS * AHCI_CMD_SLOT_SZ) | ||
60 | #define AHCI_CMD_TBL_OFFSET 0x0 | ||
61 | |||
62 | /* DMA region per command (contains header and SGL) */ | ||
63 | #define AHCI_CMD_TBL_HDR_SZ 0x80 | ||
64 | #define AHCI_CMD_TBL_HDR_OFFSET 0x0 | ||
65 | #define AHCI_CMD_TBL_SGL_SZ (MTIP_MAX_SG * sizeof(struct mtip_cmd_sg)) | ||
66 | #define AHCI_CMD_TBL_SGL_OFFSET AHCI_CMD_TBL_HDR_SZ | ||
67 | #define CMD_DMA_ALLOC_SZ (AHCI_CMD_TBL_SGL_SZ + AHCI_CMD_TBL_HDR_SZ) | ||
68 | |||
48 | 69 | ||
49 | #define HOST_CAP_NZDMA (1 << 19) | 70 | #define HOST_CAP_NZDMA (1 << 19) |
50 | #define HOST_HSORG 0xFC | 71 | #define HOST_HSORG 0xFC |
@@ -899,8 +920,9 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
899 | fail_reason = "thermal shutdown"; | 920 | fail_reason = "thermal shutdown"; |
900 | } | 921 | } |
901 | if (buf[288] == 0xBF) { | 922 | if (buf[288] == 0xBF) { |
923 | set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag); | ||
902 | dev_info(&dd->pdev->dev, | 924 | dev_info(&dd->pdev->dev, |
903 | "Drive indicates rebuild has failed.\n"); | 925 | "Drive indicates rebuild has failed. Secure erase required.\n"); |
904 | fail_all_ncq_cmds = 1; | 926 | fail_all_ncq_cmds = 1; |
905 | fail_reason = "rebuild failed"; | 927 | fail_reason = "rebuild failed"; |
906 | } | 928 | } |
@@ -1566,6 +1588,12 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1566 | } | 1588 | } |
1567 | #endif | 1589 | #endif |
1568 | 1590 | ||
1591 | /* Check security locked state */ | ||
1592 | if (port->identify[128] & 0x4) | ||
1593 | set_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); | ||
1594 | else | ||
1595 | clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); | ||
1596 | |||
1569 | #ifdef MTIP_TRIM /* Disabling TRIM support temporarily */ | 1597 | #ifdef MTIP_TRIM /* Disabling TRIM support temporarily */ |
1570 | /* Demux ID.DRAT & ID.RZAT to determine trim support */ | 1598 | /* Demux ID.DRAT & ID.RZAT to determine trim support */ |
1571 | if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5)) | 1599 | if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5)) |
@@ -1887,6 +1915,10 @@ static void mtip_dump_identify(struct mtip_port *port) | |||
1887 | strlcpy(cbuf, (char *)(port->identify+27), 41); | 1915 | strlcpy(cbuf, (char *)(port->identify+27), 41); |
1888 | dev_info(&port->dd->pdev->dev, "Model: %s\n", cbuf); | 1916 | dev_info(&port->dd->pdev->dev, "Model: %s\n", cbuf); |
1889 | 1917 | ||
1918 | dev_info(&port->dd->pdev->dev, "Security: %04x %s\n", | ||
1919 | port->identify[128], | ||
1920 | port->identify[128] & 0x4 ? "(LOCKED)" : ""); | ||
1921 | |||
1890 | if (mtip_hw_get_capacity(port->dd, §ors)) | 1922 | if (mtip_hw_get_capacity(port->dd, §ors)) |
1891 | dev_info(&port->dd->pdev->dev, | 1923 | dev_info(&port->dd->pdev->dev, |
1892 | "Capacity: %llu sectors (%llu MB)\n", | 1924 | "Capacity: %llu sectors (%llu MB)\n", |
@@ -3313,6 +3345,118 @@ st_out: | |||
3313 | } | 3345 | } |
3314 | 3346 | ||
3315 | /* | 3347 | /* |
3348 | * DMA region teardown | ||
3349 | * | ||
3350 | * @dd Pointer to driver_data structure | ||
3351 | * | ||
3352 | * return value | ||
3353 | * None | ||
3354 | */ | ||
3355 | static void mtip_dma_free(struct driver_data *dd) | ||
3356 | { | ||
3357 | int i; | ||
3358 | struct mtip_port *port = dd->port; | ||
3359 | |||
3360 | if (port->block1) | ||
3361 | dmam_free_coherent(&dd->pdev->dev, BLOCK_DMA_ALLOC_SZ, | ||
3362 | port->block1, port->block1_dma); | ||
3363 | |||
3364 | if (port->command_list) { | ||
3365 | dmam_free_coherent(&dd->pdev->dev, AHCI_CMD_TBL_SZ, | ||
3366 | port->command_list, port->command_list_dma); | ||
3367 | } | ||
3368 | |||
3369 | for (i = 0; i < MTIP_MAX_COMMAND_SLOTS; i++) { | ||
3370 | if (port->commands[i].command) | ||
3371 | dmam_free_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3372 | port->commands[i].command, | ||
3373 | port->commands[i].command_dma); | ||
3374 | } | ||
3375 | } | ||
3376 | |||
3377 | /* | ||
3378 | * DMA region setup | ||
3379 | * | ||
3380 | * @dd Pointer to driver_data structure | ||
3381 | * | ||
3382 | * return value | ||
3383 | * -ENOMEM Not enough free DMA region space to initialize driver | ||
3384 | */ | ||
3385 | static int mtip_dma_alloc(struct driver_data *dd) | ||
3386 | { | ||
3387 | struct mtip_port *port = dd->port; | ||
3388 | int i, rv = 0; | ||
3389 | u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; | ||
3390 | |||
3391 | /* Allocate dma memory for RX Fis, Identify, and Sector Bufffer */ | ||
3392 | port->block1 = | ||
3393 | dmam_alloc_coherent(&dd->pdev->dev, BLOCK_DMA_ALLOC_SZ, | ||
3394 | &port->block1_dma, GFP_KERNEL); | ||
3395 | if (!port->block1) | ||
3396 | return -ENOMEM; | ||
3397 | memset(port->block1, 0, BLOCK_DMA_ALLOC_SZ); | ||
3398 | |||
3399 | /* Allocate dma memory for command list */ | ||
3400 | port->command_list = | ||
3401 | dmam_alloc_coherent(&dd->pdev->dev, AHCI_CMD_TBL_SZ, | ||
3402 | &port->command_list_dma, GFP_KERNEL); | ||
3403 | if (!port->command_list) { | ||
3404 | dmam_free_coherent(&dd->pdev->dev, BLOCK_DMA_ALLOC_SZ, | ||
3405 | port->block1, port->block1_dma); | ||
3406 | port->block1 = NULL; | ||
3407 | port->block1_dma = 0; | ||
3408 | return -ENOMEM; | ||
3409 | } | ||
3410 | memset(port->command_list, 0, AHCI_CMD_TBL_SZ); | ||
3411 | |||
3412 | /* Setup all pointers into first DMA region */ | ||
3413 | port->rxfis = port->block1 + AHCI_RX_FIS_OFFSET; | ||
3414 | port->rxfis_dma = port->block1_dma + AHCI_RX_FIS_OFFSET; | ||
3415 | port->identify = port->block1 + AHCI_IDFY_OFFSET; | ||
3416 | port->identify_dma = port->block1_dma + AHCI_IDFY_OFFSET; | ||
3417 | port->log_buf = port->block1 + AHCI_SECTBUF_OFFSET; | ||
3418 | port->log_buf_dma = port->block1_dma + AHCI_SECTBUF_OFFSET; | ||
3419 | port->smart_buf = port->block1 + AHCI_SMARTBUF_OFFSET; | ||
3420 | port->smart_buf_dma = port->block1_dma + AHCI_SMARTBUF_OFFSET; | ||
3421 | |||
3422 | /* Setup per command SGL DMA region */ | ||
3423 | |||
3424 | /* Point the command headers at the command tables */ | ||
3425 | for (i = 0; i < MTIP_MAX_COMMAND_SLOTS; i++) { | ||
3426 | port->commands[i].command = | ||
3427 | dmam_alloc_coherent(&dd->pdev->dev, CMD_DMA_ALLOC_SZ, | ||
3428 | &port->commands[i].command_dma, GFP_KERNEL); | ||
3429 | if (!port->commands[i].command) { | ||
3430 | rv = -ENOMEM; | ||
3431 | mtip_dma_free(dd); | ||
3432 | return rv; | ||
3433 | } | ||
3434 | memset(port->commands[i].command, 0, CMD_DMA_ALLOC_SZ); | ||
3435 | |||
3436 | port->commands[i].command_header = port->command_list + | ||
3437 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3438 | port->commands[i].command_header_dma = | ||
3439 | dd->port->command_list_dma + | ||
3440 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3441 | |||
3442 | if (host_cap_64) | ||
3443 | port->commands[i].command_header->ctbau = | ||
3444 | __force_bit2int cpu_to_le32( | ||
3445 | (port->commands[i].command_dma >> 16) >> 16); | ||
3446 | |||
3447 | port->commands[i].command_header->ctba = | ||
3448 | __force_bit2int cpu_to_le32( | ||
3449 | port->commands[i].command_dma & 0xFFFFFFFF); | ||
3450 | |||
3451 | sg_init_table(port->commands[i].sg, MTIP_MAX_SG); | ||
3452 | |||
3453 | /* Mark command as currently inactive */ | ||
3454 | atomic_set(&dd->port->commands[i].active, 0); | ||
3455 | } | ||
3456 | return 0; | ||
3457 | } | ||
3458 | |||
3459 | /* | ||
3316 | * Called once for each card. | 3460 | * Called once for each card. |
3317 | * | 3461 | * |
3318 | * @dd Pointer to the driver data structure. | 3462 | * @dd Pointer to the driver data structure. |
@@ -3370,83 +3514,10 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3370 | dd->port->mmio = dd->mmio + PORT_OFFSET; | 3514 | dd->port->mmio = dd->mmio + PORT_OFFSET; |
3371 | dd->port->dd = dd; | 3515 | dd->port->dd = dd; |
3372 | 3516 | ||
3373 | /* Allocate memory for the command list. */ | 3517 | /* DMA allocations */ |
3374 | dd->port->command_list = | 3518 | rv = mtip_dma_alloc(dd); |
3375 | dmam_alloc_coherent(&dd->pdev->dev, | 3519 | if (rv < 0) |
3376 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), | ||
3377 | &dd->port->command_list_dma, | ||
3378 | GFP_KERNEL); | ||
3379 | if (!dd->port->command_list) { | ||
3380 | dev_err(&dd->pdev->dev, | ||
3381 | "Memory allocation: command list\n"); | ||
3382 | rv = -ENOMEM; | ||
3383 | goto out1; | 3520 | goto out1; |
3384 | } | ||
3385 | |||
3386 | /* Clear the memory we have allocated. */ | ||
3387 | memset(dd->port->command_list, | ||
3388 | 0, | ||
3389 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4)); | ||
3390 | |||
3391 | /* Setup the addresse of the RX FIS. */ | ||
3392 | dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ; | ||
3393 | dd->port->rxfis_dma = dd->port->command_list_dma + HW_CMD_SLOT_SZ; | ||
3394 | |||
3395 | /* Setup the address of the command tables. */ | ||
3396 | dd->port->command_table = dd->port->rxfis + AHCI_RX_FIS_SZ; | ||
3397 | dd->port->command_tbl_dma = dd->port->rxfis_dma + AHCI_RX_FIS_SZ; | ||
3398 | |||
3399 | /* Setup the address of the identify data. */ | ||
3400 | dd->port->identify = dd->port->command_table + | ||
3401 | HW_CMD_TBL_AR_SZ; | ||
3402 | dd->port->identify_dma = dd->port->command_tbl_dma + | ||
3403 | HW_CMD_TBL_AR_SZ; | ||
3404 | |||
3405 | /* Setup the address of the sector buffer - for some non-ncq cmds */ | ||
3406 | dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE; | ||
3407 | dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE; | ||
3408 | |||
3409 | /* Setup the address of the log buf - for read log command */ | ||
3410 | dd->port->log_buf = (void *)dd->port->sector_buffer + ATA_SECT_SIZE; | ||
3411 | dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE; | ||
3412 | |||
3413 | /* Setup the address of the smart buf - for smart read data command */ | ||
3414 | dd->port->smart_buf = (void *)dd->port->log_buf + ATA_SECT_SIZE; | ||
3415 | dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE; | ||
3416 | |||
3417 | |||
3418 | /* Point the command headers at the command tables. */ | ||
3419 | for (i = 0; i < num_command_slots; i++) { | ||
3420 | dd->port->commands[i].command_header = | ||
3421 | dd->port->command_list + | ||
3422 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3423 | dd->port->commands[i].command_header_dma = | ||
3424 | dd->port->command_list_dma + | ||
3425 | (sizeof(struct mtip_cmd_hdr) * i); | ||
3426 | |||
3427 | dd->port->commands[i].command = | ||
3428 | dd->port->command_table + (HW_CMD_TBL_SZ * i); | ||
3429 | dd->port->commands[i].command_dma = | ||
3430 | dd->port->command_tbl_dma + (HW_CMD_TBL_SZ * i); | ||
3431 | |||
3432 | if (readl(dd->mmio + HOST_CAP) & HOST_CAP_64) | ||
3433 | dd->port->commands[i].command_header->ctbau = | ||
3434 | __force_bit2int cpu_to_le32( | ||
3435 | (dd->port->commands[i].command_dma >> 16) >> 16); | ||
3436 | dd->port->commands[i].command_header->ctba = | ||
3437 | __force_bit2int cpu_to_le32( | ||
3438 | dd->port->commands[i].command_dma & 0xFFFFFFFF); | ||
3439 | |||
3440 | /* | ||
3441 | * If this is not done, a bug is reported by the stock | ||
3442 | * FC11 i386. Due to the fact that it has lots of kernel | ||
3443 | * debugging enabled. | ||
3444 | */ | ||
3445 | sg_init_table(dd->port->commands[i].sg, MTIP_MAX_SG); | ||
3446 | |||
3447 | /* Mark all commands as currently inactive.*/ | ||
3448 | atomic_set(&dd->port->commands[i].active, 0); | ||
3449 | } | ||
3450 | 3521 | ||
3451 | /* Setup the pointers to the extended s_active and CI registers. */ | 3522 | /* Setup the pointers to the extended s_active and CI registers. */ |
3452 | for (i = 0; i < dd->slot_groups; i++) { | 3523 | for (i = 0; i < dd->slot_groups; i++) { |
@@ -3594,12 +3665,8 @@ out3: | |||
3594 | 3665 | ||
3595 | out2: | 3666 | out2: |
3596 | mtip_deinit_port(dd->port); | 3667 | mtip_deinit_port(dd->port); |
3668 | mtip_dma_free(dd); | ||
3597 | 3669 | ||
3598 | /* Free the command/command header memory. */ | ||
3599 | dmam_free_coherent(&dd->pdev->dev, | ||
3600 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), | ||
3601 | dd->port->command_list, | ||
3602 | dd->port->command_list_dma); | ||
3603 | out1: | 3670 | out1: |
3604 | /* Free the memory allocated for the for structure. */ | 3671 | /* Free the memory allocated for the for structure. */ |
3605 | kfree(dd->port); | 3672 | kfree(dd->port); |
@@ -3622,7 +3689,8 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3622 | * saves its state. | 3689 | * saves its state. |
3623 | */ | 3690 | */ |
3624 | if (!dd->sr) { | 3691 | if (!dd->sr) { |
3625 | if (!test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) | 3692 | if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) && |
3693 | !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) | ||
3626 | if (mtip_standby_immediate(dd->port)) | 3694 | if (mtip_standby_immediate(dd->port)) |
3627 | dev_warn(&dd->pdev->dev, | 3695 | dev_warn(&dd->pdev->dev, |
3628 | "STANDBY IMMEDIATE failed\n"); | 3696 | "STANDBY IMMEDIATE failed\n"); |
@@ -3641,11 +3709,9 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3641 | irq_set_affinity_hint(dd->pdev->irq, NULL); | 3709 | irq_set_affinity_hint(dd->pdev->irq, NULL); |
3642 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); | 3710 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); |
3643 | 3711 | ||
3644 | /* Free the command/command header memory. */ | 3712 | /* Free dma regions */ |
3645 | dmam_free_coherent(&dd->pdev->dev, | 3713 | mtip_dma_free(dd); |
3646 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), | 3714 | |
3647 | dd->port->command_list, | ||
3648 | dd->port->command_list_dma); | ||
3649 | /* Free the memory allocated for the for structure. */ | 3715 | /* Free the memory allocated for the for structure. */ |
3650 | kfree(dd->port); | 3716 | kfree(dd->port); |
3651 | dd->port = NULL; | 3717 | dd->port = NULL; |