diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2011-11-23 02:29:24 -0500 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2011-11-23 02:29:24 -0500 |
commit | 60ec0eecfa8968d0f1188e3730979196ac28b9de (patch) | |
tree | 59c1f3df77df31dc9d851f41ed658952150998b1 /drivers/block/mtip32xx | |
parent | a71f483d7957c74368a76a3a88ae54d524fa3b49 (diff) |
mtip32xx: updates based on feedback
* queue ncq commands when a non-ncq is in progress or error handling is active
* merge variables 'internal_cmd_in_progress' and 'eh_active' into new variable 'flags'
* get rid of read/write semaphore 'internal_sem'
* new service thread to issue queued commands
* use macros from ata.h for command codes
* return ENOTTY for BLKFLSBUF ioctl
* style changes
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: Sam Bradshaw <sbradshaw@micron.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 342 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 42 |
2 files changed, 230 insertions, 154 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 880facbb0534..b5d843a02bfa 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/bio.h> | 34 | #include <linux/bio.h> |
35 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
37 | #include <linux/kthread.h> | ||
37 | #include <../drivers/ata/ahci.h> | 38 | #include <../drivers/ata/ahci.h> |
38 | #include "mtip32xx.h" | 39 | #include "mtip32xx.h" |
39 | 40 | ||
@@ -99,15 +100,6 @@ struct mtip_compat_ide_task_request_s { | |||
99 | }; | 100 | }; |
100 | #endif | 101 | #endif |
101 | 102 | ||
102 | static int mtip_exec_internal_command(struct mtip_port *port, | ||
103 | void *fis, | ||
104 | int fisLen, | ||
105 | dma_addr_t buffer, | ||
106 | int bufLen, | ||
107 | u32 opts, | ||
108 | gfp_t atomic, | ||
109 | unsigned long timeout); | ||
110 | |||
111 | /* | 103 | /* |
112 | * This function check_for_surprise_removal is called | 104 | * This function check_for_surprise_removal is called |
113 | * while card is removed from the system and it will | 105 | * while card is removed from the system and it will |
@@ -414,9 +406,9 @@ static void mtip_init_port(struct mtip_port *port) | |||
414 | port->mmio + PORT_FIS_ADDR_HI); | 406 | port->mmio + PORT_FIS_ADDR_HI); |
415 | } | 407 | } |
416 | 408 | ||
417 | writel(port->command_list_dma & 0xffffffff, | 409 | writel(port->command_list_dma & 0xFFFFFFFF, |
418 | port->mmio + PORT_LST_ADDR); | 410 | port->mmio + PORT_LST_ADDR); |
419 | writel(port->rxfis_dma & 0xffffffff, port->mmio + PORT_FIS_ADDR); | 411 | writel(port->rxfis_dma & 0xFFFFFFFF, port->mmio + PORT_FIS_ADDR); |
420 | 412 | ||
421 | /* Clear SError */ | 413 | /* Clear SError */ |
422 | writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); | 414 | writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); |
@@ -541,7 +533,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
541 | if (atomic_read(&port->commands[tag].active) && | 533 | if (atomic_read(&port->commands[tag].active) && |
542 | (time_after(jiffies, port->commands[tag].comp_time))) { | 534 | (time_after(jiffies, port->commands[tag].comp_time))) { |
543 | group = tag >> 5; | 535 | group = tag >> 5; |
544 | bit = tag & 0x1f; | 536 | bit = tag & 0x1F; |
545 | 537 | ||
546 | command = &port->commands[tag]; | 538 | command = &port->commands[tag]; |
547 | fis = (struct host_to_dev_fis *) command->command; | 539 | fis = (struct host_to_dev_fis *) command->command; |
@@ -551,7 +543,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
551 | 543 | ||
552 | cmdto_cnt++; | 544 | cmdto_cnt++; |
553 | if (cmdto_cnt == 1) | 545 | if (cmdto_cnt == 1) |
554 | atomic_inc(&port->dd->eh_active); | 546 | set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); |
555 | 547 | ||
556 | /* | 548 | /* |
557 | * Clear the completed bit. This should prevent | 549 | * Clear the completed bit. This should prevent |
@@ -589,7 +581,8 @@ static void mtip_timeout_function(unsigned long int data) | |||
589 | "%d commands timed out: restarting port", | 581 | "%d commands timed out: restarting port", |
590 | cmdto_cnt); | 582 | cmdto_cnt); |
591 | mtip_restart_port(port); | 583 | mtip_restart_port(port); |
592 | atomic_dec(&port->dd->eh_active); | 584 | clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); |
585 | wake_up_interruptible(&port->svc_wait); | ||
593 | } | 586 | } |
594 | 587 | ||
595 | /* Restart the timer */ | 588 | /* Restart the timer */ |
@@ -728,7 +721,7 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
728 | del_timer(&port->cmd_timer); | 721 | del_timer(&port->cmd_timer); |
729 | 722 | ||
730 | /* Set eh_active */ | 723 | /* Set eh_active */ |
731 | atomic_inc(&dd->eh_active); | 724 | set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); |
732 | 725 | ||
733 | /* Loop through all the groups */ | 726 | /* Loop through all the groups */ |
734 | for (group = 0; group < dd->slot_groups; group++) { | 727 | for (group = 0; group < dd->slot_groups; group++) { |
@@ -835,8 +828,9 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
835 | } | 828 | } |
836 | print_tags(dd, "TFE tags reissued:", tagaccum); | 829 | print_tags(dd, "TFE tags reissued:", tagaccum); |
837 | 830 | ||
838 | /* Decrement eh_active */ | 831 | /* clear eh_active */ |
839 | atomic_dec(&dd->eh_active); | 832 | clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); |
833 | wake_up_interruptible(&port->svc_wait); | ||
840 | 834 | ||
841 | mod_timer(&port->cmd_timer, | 835 | mod_timer(&port->cmd_timer, |
842 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); | 836 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); |
@@ -871,7 +865,6 @@ static inline void mtip_process_sdbf(struct driver_data *dd) | |||
871 | continue; | 865 | continue; |
872 | 866 | ||
873 | command = &port->commands[tag]; | 867 | command = &port->commands[tag]; |
874 | |||
875 | /* make internal callback */ | 868 | /* make internal callback */ |
876 | if (likely(command->comp_func)) { | 869 | if (likely(command->comp_func)) { |
877 | command->comp_func( | 870 | command->comp_func( |
@@ -904,9 +897,8 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) | |||
904 | struct mtip_port *port = dd->port; | 897 | struct mtip_port *port = dd->port; |
905 | struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; | 898 | struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; |
906 | 899 | ||
907 | if (port->internal_cmd_in_progress && | 900 | if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && |
908 | cmd != NULL && | 901 | (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) |
909 | !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | ||
910 | & (1 << MTIP_TAG_INTERNAL))) { | 902 | & (1 << MTIP_TAG_INTERNAL))) { |
911 | if (cmd->comp_func) { | 903 | if (cmd->comp_func) { |
912 | cmd->comp_func(port, | 904 | cmd->comp_func(port, |
@@ -1038,11 +1030,15 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1038 | 1030 | ||
1039 | to = jiffies + msecs_to_jiffies(timeout); | 1031 | to = jiffies + msecs_to_jiffies(timeout); |
1040 | do { | 1032 | do { |
1033 | if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags)) { | ||
1034 | msleep(20); | ||
1035 | continue; /* svc thd is actively issuing commands */ | ||
1036 | } | ||
1041 | /* | 1037 | /* |
1042 | * Ignore s_active bit 0 of array element 0. | 1038 | * Ignore s_active bit 0 of array element 0. |
1043 | * This bit will always be set | 1039 | * This bit will always be set |
1044 | */ | 1040 | */ |
1045 | active = readl(port->s_active[0]) & 0xfffffffe; | 1041 | active = readl(port->s_active[0]) & 0xFFFFFFFE; |
1046 | for (n = 1; n < port->dd->slot_groups; n++) | 1042 | for (n = 1; n < port->dd->slot_groups; n++) |
1047 | active |= readl(port->s_active[n]); | 1043 | active |= readl(port->s_active[n]); |
1048 | 1044 | ||
@@ -1060,9 +1056,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1060 | * | 1056 | * |
1061 | * @port Pointer to the port data structure. | 1057 | * @port Pointer to the port data structure. |
1062 | * @fis Pointer to the FIS that describes the command. | 1058 | * @fis Pointer to the FIS that describes the command. |
1063 | * @fisLen Length in WORDS of the FIS. | 1059 | * @fis_len Length in WORDS of the FIS. |
1064 | * @buffer DMA accessible for command data. | 1060 | * @buffer DMA accessible for command data. |
1065 | * @bufLen Length, in bytes, of the data buffer. | 1061 | * @buf_len Length, in bytes, of the data buffer. |
1066 | * @opts Command header options, excluding the FIS length | 1062 | * @opts Command header options, excluding the FIS length |
1067 | * and the number of PRD entries. | 1063 | * and the number of PRD entries. |
1068 | * @timeout Time in ms to wait for the command to complete. | 1064 | * @timeout Time in ms to wait for the command to complete. |
@@ -1075,9 +1071,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1075 | */ | 1071 | */ |
1076 | static int mtip_exec_internal_command(struct mtip_port *port, | 1072 | static int mtip_exec_internal_command(struct mtip_port *port, |
1077 | void *fis, | 1073 | void *fis, |
1078 | int fisLen, | 1074 | int fis_len, |
1079 | dma_addr_t buffer, | 1075 | dma_addr_t buffer, |
1080 | int bufLen, | 1076 | int buf_len, |
1081 | u32 opts, | 1077 | u32 opts, |
1082 | gfp_t atomic, | 1078 | gfp_t atomic, |
1083 | unsigned long timeout) | 1079 | unsigned long timeout) |
@@ -1100,7 +1096,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1100 | "Internal command already active\n"); | 1096 | "Internal command already active\n"); |
1101 | return -EBUSY; | 1097 | return -EBUSY; |
1102 | } | 1098 | } |
1103 | port->internal_cmd_in_progress = 1; | 1099 | set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); |
1104 | 1100 | ||
1105 | if (atomic == GFP_KERNEL) { | 1101 | if (atomic == GFP_KERNEL) { |
1106 | /* wait for io to complete if non atomic */ | 1102 | /* wait for io to complete if non atomic */ |
@@ -1108,7 +1104,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1108 | dev_warn(&port->dd->pdev->dev, | 1104 | dev_warn(&port->dd->pdev->dev, |
1109 | "Failed to quiesce IO\n"); | 1105 | "Failed to quiesce IO\n"); |
1110 | release_slot(port, MTIP_TAG_INTERNAL); | 1106 | release_slot(port, MTIP_TAG_INTERNAL); |
1111 | port->internal_cmd_in_progress = 0; | 1107 | clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); |
1108 | wake_up_interruptible(&port->svc_wait); | ||
1112 | return -EBUSY; | 1109 | return -EBUSY; |
1113 | } | 1110 | } |
1114 | 1111 | ||
@@ -1123,19 +1120,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1123 | } | 1120 | } |
1124 | 1121 | ||
1125 | /* Copy the command to the command table */ | 1122 | /* Copy the command to the command table */ |
1126 | memcpy(int_cmd->command, fis, fisLen*4); | 1123 | memcpy(int_cmd->command, fis, fis_len*4); |
1127 | 1124 | ||
1128 | /* Populate the SG list */ | 1125 | /* Populate the SG list */ |
1129 | int_cmd->command_header->opts = | 1126 | int_cmd->command_header->opts = |
1130 | cpu_to_le32(opts | fisLen); | 1127 | __force_bit2int cpu_to_le32(opts | fis_len); |
1131 | if (bufLen) { | 1128 | if (buf_len) { |
1132 | command_sg = int_cmd->command + AHCI_CMD_TBL_HDR_SZ; | 1129 | command_sg = int_cmd->command + AHCI_CMD_TBL_HDR_SZ; |
1133 | 1130 | ||
1134 | command_sg->info = cpu_to_le32((bufLen-1) & 0x3fffff); | 1131 | command_sg->info = |
1135 | command_sg->dba = cpu_to_le32(buffer & 0xffffffff); | 1132 | __force_bit2int cpu_to_le32((buf_len-1) & 0x3FFFFF); |
1136 | command_sg->dba_upper = cpu_to_le32((buffer >> 16) >> 16); | 1133 | command_sg->dba = |
1134 | __force_bit2int cpu_to_le32(buffer & 0xFFFFFFFF); | ||
1135 | command_sg->dba_upper = | ||
1136 | __force_bit2int cpu_to_le32((buffer >> 16) >> 16); | ||
1137 | 1137 | ||
1138 | int_cmd->command_header->opts |= cpu_to_le32((1 << 16)); | 1138 | int_cmd->command_header->opts |= |
1139 | __force_bit2int cpu_to_le32((1 << 16)); | ||
1139 | } | 1140 | } |
1140 | 1141 | ||
1141 | /* Populate the command header */ | 1142 | /* Populate the command header */ |
@@ -1151,8 +1152,9 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1151 | &wait, | 1152 | &wait, |
1152 | msecs_to_jiffies(timeout)) == 0) { | 1153 | msecs_to_jiffies(timeout)) == 0) { |
1153 | dev_err(&port->dd->pdev->dev, | 1154 | dev_err(&port->dd->pdev->dev, |
1154 | "Internal command did not complete [%d]\n", | 1155 | "Internal command did not complete [%d] " |
1155 | atomic); | 1156 | "within timeout of %lu ms\n", |
1157 | atomic, timeout); | ||
1156 | rv = -EAGAIN; | 1158 | rv = -EAGAIN; |
1157 | } | 1159 | } |
1158 | 1160 | ||
@@ -1184,7 +1186,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1184 | /* Clear the allocated and active bits for the internal command. */ | 1186 | /* Clear the allocated and active bits for the internal command. */ |
1185 | atomic_set(&int_cmd->active, 0); | 1187 | atomic_set(&int_cmd->active, 0); |
1186 | release_slot(port, MTIP_TAG_INTERNAL); | 1188 | release_slot(port, MTIP_TAG_INTERNAL); |
1187 | port->internal_cmd_in_progress = 0; | 1189 | clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); |
1190 | wake_up_interruptible(&port->svc_wait); | ||
1188 | 1191 | ||
1189 | return rv; | 1192 | return rv; |
1190 | } | 1193 | } |
@@ -1233,8 +1236,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1233 | int rv = 0; | 1236 | int rv = 0; |
1234 | struct host_to_dev_fis fis; | 1237 | struct host_to_dev_fis fis; |
1235 | 1238 | ||
1236 | down_write(&port->dd->internal_sem); | ||
1237 | |||
1238 | /* Build the FIS. */ | 1239 | /* Build the FIS. */ |
1239 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1240 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1240 | fis.type = 0x27; | 1241 | fis.type = 0x27; |
@@ -1292,7 +1293,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1292 | } | 1293 | } |
1293 | 1294 | ||
1294 | out: | 1295 | out: |
1295 | up_write(&port->dd->internal_sem); | ||
1296 | return rv; | 1296 | return rv; |
1297 | } | 1297 | } |
1298 | 1298 | ||
@@ -1310,8 +1310,6 @@ static int mtip_standby_immediate(struct mtip_port *port) | |||
1310 | int rv; | 1310 | int rv; |
1311 | struct host_to_dev_fis fis; | 1311 | struct host_to_dev_fis fis; |
1312 | 1312 | ||
1313 | down_write(&port->dd->internal_sem); | ||
1314 | |||
1315 | /* Build the FIS. */ | 1313 | /* Build the FIS. */ |
1316 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1314 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1317 | fis.type = 0x27; | 1315 | fis.type = 0x27; |
@@ -1328,8 +1326,6 @@ static int mtip_standby_immediate(struct mtip_port *port) | |||
1328 | GFP_KERNEL, | 1326 | GFP_KERNEL, |
1329 | 15000); | 1327 | 15000); |
1330 | 1328 | ||
1331 | up_write(&port->dd->internal_sem); | ||
1332 | |||
1333 | return rv; | 1329 | return rv; |
1334 | } | 1330 | } |
1335 | 1331 | ||
@@ -1430,7 +1426,7 @@ static void mtip_dump_identify(struct mtip_port *port) | |||
1430 | ((u64)sectors) * ATA_SECT_SIZE >> 20); | 1426 | ((u64)sectors) * ATA_SECT_SIZE >> 20); |
1431 | 1427 | ||
1432 | pci_read_config_word(port->dd->pdev, PCI_REVISION_ID, &revid); | 1428 | pci_read_config_word(port->dd->pdev, PCI_REVISION_ID, &revid); |
1433 | switch (revid & 0xff) { | 1429 | switch (revid & 0xFF) { |
1434 | case 0x1: | 1430 | case 0x1: |
1435 | strlcpy(cbuf, "A0", 3); | 1431 | strlcpy(cbuf, "A0", 3); |
1436 | break; | 1432 | break; |
@@ -1470,15 +1466,12 @@ static inline void fill_command_sg(struct driver_data *dd, | |||
1470 | if (dma_len > 0x400000) | 1466 | if (dma_len > 0x400000) |
1471 | dev_err(&dd->pdev->dev, | 1467 | dev_err(&dd->pdev->dev, |
1472 | "DMA segment length truncated\n"); | 1468 | "DMA segment length truncated\n"); |
1473 | command_sg->info = cpu_to_le32((dma_len-1) & 0x3fffff); | 1469 | command_sg->info = __force_bit2int |
1474 | #if (BITS_PER_LONG == 64) | 1470 | cpu_to_le32((dma_len-1) & 0x3FFFFF); |
1475 | *((unsigned long *) &command_sg->dba) = | 1471 | command_sg->dba = __force_bit2int |
1476 | cpu_to_le64(sg_dma_address(sg)); | 1472 | cpu_to_le32(sg_dma_address(sg)); |
1477 | #else | 1473 | command_sg->dba_upper = __force_bit2int |
1478 | command_sg->dba = cpu_to_le32(sg_dma_address(sg)); | 1474 | cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); |
1479 | command_sg->dba_upper = | ||
1480 | cpu_to_le32((sg_dma_address(sg) >> 16) >> 16); | ||
1481 | #endif | ||
1482 | command_sg++; | 1475 | command_sg++; |
1483 | sg++; | 1476 | sg++; |
1484 | } | 1477 | } |
@@ -1495,9 +1488,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1495 | struct host_to_dev_fis fis; | 1488 | struct host_to_dev_fis fis; |
1496 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); | 1489 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); |
1497 | 1490 | ||
1498 | /* Lock the internal command semaphore. */ | ||
1499 | down_write(&port->dd->internal_sem); | ||
1500 | |||
1501 | /* Build the FIS. */ | 1491 | /* Build the FIS. */ |
1502 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1492 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1503 | fis.type = 0x27; | 1493 | fis.type = 0x27; |
@@ -1532,7 +1522,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1532 | 0, | 1522 | 0, |
1533 | GFP_KERNEL, | 1523 | GFP_KERNEL, |
1534 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { | 1524 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) < 0) { |
1535 | up_write(&port->dd->internal_sem); | ||
1536 | return -1; | 1525 | return -1; |
1537 | } | 1526 | } |
1538 | 1527 | ||
@@ -1549,7 +1538,6 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1549 | command[4], | 1538 | command[4], |
1550 | command[5]); | 1539 | command[5]); |
1551 | 1540 | ||
1552 | up_write(&port->dd->internal_sem); | ||
1553 | return 0; | 1541 | return 0; |
1554 | } | 1542 | } |
1555 | 1543 | ||
@@ -1572,9 +1560,6 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1572 | struct host_to_dev_fis fis; | 1560 | struct host_to_dev_fis fis; |
1573 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); | 1561 | struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG); |
1574 | 1562 | ||
1575 | /* Lock the internal command semaphore. */ | ||
1576 | down_write(&port->dd->internal_sem); | ||
1577 | |||
1578 | /* Build the FIS. */ | 1563 | /* Build the FIS. */ |
1579 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1564 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1580 | fis.type = 0x27; | 1565 | fis.type = 0x27; |
@@ -1584,8 +1569,8 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1584 | fis.sect_count = command[3]; | 1569 | fis.sect_count = command[3]; |
1585 | if (fis.command == ATA_CMD_SMART) { | 1570 | if (fis.command == ATA_CMD_SMART) { |
1586 | fis.sector = command[1]; | 1571 | fis.sector = command[1]; |
1587 | fis.cyl_low = 0x4f; | 1572 | fis.cyl_low = 0x4F; |
1588 | fis.cyl_hi = 0xc2; | 1573 | fis.cyl_hi = 0xC2; |
1589 | } | 1574 | } |
1590 | 1575 | ||
1591 | dbg_printk(MTIP_DRV_NAME | 1576 | dbg_printk(MTIP_DRV_NAME |
@@ -1609,7 +1594,6 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1609 | GFP_KERNEL, | 1594 | GFP_KERNEL, |
1610 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) | 1595 | MTIP_IOCTL_COMMAND_TIMEOUT_MS) |
1611 | < 0) { | 1596 | < 0) { |
1612 | up_write(&port->dd->internal_sem); | ||
1613 | return -1; | 1597 | return -1; |
1614 | } | 1598 | } |
1615 | 1599 | ||
@@ -1630,12 +1614,10 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1630 | if (copy_to_user(user_buffer, | 1614 | if (copy_to_user(user_buffer, |
1631 | port->sector_buffer, | 1615 | port->sector_buffer, |
1632 | ATA_SECT_SIZE * command[3])) { | 1616 | ATA_SECT_SIZE * command[3])) { |
1633 | up_write(&port->dd->internal_sem); | ||
1634 | return -EFAULT; | 1617 | return -EFAULT; |
1635 | } | 1618 | } |
1636 | } | 1619 | } |
1637 | 1620 | ||
1638 | up_write(&port->dd->internal_sem); | ||
1639 | return 0; | 1621 | return 0; |
1640 | } | 1622 | } |
1641 | 1623 | ||
@@ -1658,26 +1640,28 @@ static unsigned int implicit_sector(unsigned char command, | |||
1658 | 1640 | ||
1659 | /* list of commands that have an implicit sector count of 1 */ | 1641 | /* list of commands that have an implicit sector count of 1 */ |
1660 | switch (command) { | 1642 | switch (command) { |
1661 | case 0xF1: | 1643 | case ATA_CMD_SEC_SET_PASS: |
1662 | case 0xF2: | 1644 | case ATA_CMD_SEC_UNLOCK: |
1663 | case 0xF3: | 1645 | case ATA_CMD_SEC_ERASE_PREP: |
1664 | case 0xF4: | 1646 | case ATA_CMD_SEC_ERASE_UNIT: |
1665 | case 0xF5: | 1647 | case ATA_CMD_SEC_FREEZE_LOCK: |
1666 | case 0xF6: | 1648 | case ATA_CMD_SEC_DISABLE_PASS: |
1667 | case 0xE4: | 1649 | case ATA_CMD_PMP_READ: |
1668 | case 0xE8: | 1650 | case ATA_CMD_PMP_WRITE: |
1669 | rv = 1; | 1651 | rv = 1; |
1670 | break; | 1652 | break; |
1671 | case 0xF9: | 1653 | case ATA_CMD_SET_MAX: |
1672 | if (features == 0x03) | 1654 | if (features == ATA_SET_MAX_UNLOCK) |
1673 | rv = 1; | 1655 | rv = 1; |
1674 | break; | 1656 | break; |
1675 | case 0xB0: | 1657 | case ATA_CMD_SMART: |
1676 | if ((features == 0xD0) || (features == 0xD1)) | 1658 | if ((features == ATA_SMART_READ_VALUES) || |
1659 | (features == ATA_SMART_READ_THRESHOLDS)) | ||
1677 | rv = 1; | 1660 | rv = 1; |
1678 | break; | 1661 | break; |
1679 | case 0xB1: | 1662 | case ATA_CMD_CONF_OVERLAY: |
1680 | if ((features == 0xC2) || (features == 0xC3)) | 1663 | if ((features == ATA_DCO_IDENTIFY) || |
1664 | (features == ATA_DCO_SET)) | ||
1681 | rv = 1; | 1665 | rv = 1; |
1682 | break; | 1666 | break; |
1683 | } | 1667 | } |
@@ -1777,9 +1761,6 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1777 | goto abort; | 1761 | goto abort; |
1778 | } | 1762 | } |
1779 | 1763 | ||
1780 | /* Lock the internal command semaphore. */ | ||
1781 | down_write(&dd->internal_sem); | ||
1782 | |||
1783 | /* Build the FIS. */ | 1764 | /* Build the FIS. */ |
1784 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1765 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1785 | 1766 | ||
@@ -1818,7 +1799,6 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1818 | dev_warn(&dd->pdev->dev, | 1799 | dev_warn(&dd->pdev->dev, |
1819 | "data movement but " | 1800 | "data movement but " |
1820 | "sect_count is 0\n"); | 1801 | "sect_count is 0\n"); |
1821 | up_write(&dd->internal_sem); | ||
1822 | err = -EINVAL; | 1802 | err = -EINVAL; |
1823 | goto abort; | 1803 | goto abort; |
1824 | } | 1804 | } |
@@ -1838,19 +1818,25 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1838 | fis.device); | 1818 | fis.device); |
1839 | 1819 | ||
1840 | switch (fis.command) { | 1820 | switch (fis.command) { |
1841 | case 0x92: /* Change timeout for Download Microcode to 60 seconds.*/ | 1821 | case ATA_CMD_DOWNLOAD_MICRO: |
1822 | /* Change timeout for Download Microcode to 60 seconds.*/ | ||
1842 | timeout = 60000; | 1823 | timeout = 60000; |
1843 | break; | 1824 | break; |
1844 | case 0xf4: /* Change timeout for Security Erase Unit to 4 minutes.*/ | 1825 | case ATA_CMD_SEC_ERASE_UNIT: |
1826 | /* Change timeout for Security Erase Unit to 4 minutes.*/ | ||
1845 | timeout = 240000; | 1827 | timeout = 240000; |
1846 | break; | 1828 | break; |
1847 | case 0xe0: /* Change timeout for standby immediate to 10 seconds.*/ | 1829 | case ATA_CMD_STANDBYNOW1: |
1830 | /* Change timeout for standby immediate to 10 seconds.*/ | ||
1848 | timeout = 10000; | 1831 | timeout = 10000; |
1849 | break; | 1832 | break; |
1850 | case 0xf7: /* Change timeout for vendor unique command to 10 secs */ | 1833 | case 0xF7: |
1834 | case 0xFA: | ||
1835 | /* Change timeout for vendor unique command to 10 secs */ | ||
1851 | timeout = 10000; | 1836 | timeout = 10000; |
1852 | break; | 1837 | break; |
1853 | case 0xfa: /* Change timeout for vendor unique command to 10 secs */ | 1838 | case ATA_CMD_SMART: |
1839 | /* Change timeout for vendor unique command to 10 secs */ | ||
1854 | timeout = 10000; | 1840 | timeout = 10000; |
1855 | break; | 1841 | break; |
1856 | default: | 1842 | default: |
@@ -1873,7 +1859,6 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1873 | 0, | 1859 | 0, |
1874 | GFP_KERNEL, | 1860 | GFP_KERNEL, |
1875 | timeout) < 0) { | 1861 | timeout) < 0) { |
1876 | up_write(&dd->internal_sem); | ||
1877 | err = -EIO; | 1862 | err = -EIO; |
1878 | goto abort; | 1863 | goto abort; |
1879 | } | 1864 | } |
@@ -1916,7 +1901,7 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1916 | } | 1901 | } |
1917 | 1902 | ||
1918 | /* Com rest after secure erase or lowlevel format */ | 1903 | /* Com rest after secure erase or lowlevel format */ |
1919 | if (((fis.command == 0xF4) || | 1904 | if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) || |
1920 | ((fis.command == 0xFC) && | 1905 | ((fis.command == 0xFC) && |
1921 | (fis.features == 0x27 || fis.features == 0x72 || | 1906 | (fis.features == 0x27 || fis.features == 0x72 || |
1922 | fis.features == 0x62 || fis.features == 0x26))) && | 1907 | fis.features == 0x62 || fis.features == 0x26))) && |
@@ -1937,8 +1922,6 @@ static int exec_drive_taskfile(struct driver_data *dd, | |||
1937 | req_task->io_ports[5], | 1922 | req_task->io_ports[5], |
1938 | req_task->io_ports[6]); | 1923 | req_task->io_ports[6]); |
1939 | 1924 | ||
1940 | up_write(&dd->internal_sem); | ||
1941 | |||
1942 | if (taskout) { | 1925 | if (taskout) { |
1943 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { | 1926 | if (copy_to_user(buf + outtotal, outbuf, taskout)) { |
1944 | err = -EFAULT; | 1927 | err = -EFAULT; |
@@ -2052,7 +2035,8 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, | |||
2052 | ret = exec_drive_taskfile(dd, (void __user *) arg, | 2035 | ret = exec_drive_taskfile(dd, (void __user *) arg, |
2053 | &req_task, outtotal); | 2036 | &req_task, outtotal); |
2054 | 2037 | ||
2055 | if (copy_to_user((void __user *) arg, &req_task, sizeof(req_task))) | 2038 | if (copy_to_user((void __user *) arg, &req_task, |
2039 | sizeof(req_task))) | ||
2056 | return -EFAULT; | 2040 | return -EFAULT; |
2057 | 2041 | ||
2058 | return ret; | 2042 | return ret; |
@@ -2117,13 +2101,13 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2117 | fis->opts = 1 << 7; | 2101 | fis->opts = 1 << 7; |
2118 | fis->command = | 2102 | fis->command = |
2119 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); | 2103 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); |
2120 | *((unsigned int *) &fis->lba_low) = (start & 0xffffff); | 2104 | *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); |
2121 | *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xffffff); | 2105 | *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); |
2122 | fis->device = 1 << 6; | 2106 | fis->device = 1 << 6; |
2123 | if (barrier) | 2107 | if (barrier) |
2124 | fis->device |= FUA_BIT; | 2108 | fis->device |= FUA_BIT; |
2125 | fis->features = nsect & 0xff; | 2109 | fis->features = nsect & 0xFF; |
2126 | fis->features_ex = (nsect >> 8) & 0xff; | 2110 | fis->features_ex = (nsect >> 8) & 0xFF; |
2127 | fis->sect_count = ((tag << 3) | (tag >> 5)); | 2111 | fis->sect_count = ((tag << 3) | (tag >> 5)); |
2128 | fis->sect_cnt_ex = 0; | 2112 | fis->sect_cnt_ex = 0; |
2129 | fis->control = 0; | 2113 | fis->control = 0; |
@@ -2132,8 +2116,9 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2132 | fill_command_sg(dd, command, nents); | 2116 | fill_command_sg(dd, command, nents); |
2133 | 2117 | ||
2134 | /* Populate the command header */ | 2118 | /* Populate the command header */ |
2135 | command->command_header->opts = cpu_to_le32( | 2119 | command->command_header->opts = |
2136 | (nents << 16) | 5 | AHCI_CMD_PREFETCH); | 2120 | __force_bit2int cpu_to_le32( |
2121 | (nents << 16) | 5 | AHCI_CMD_PREFETCH); | ||
2137 | command->command_header->byte_count = 0; | 2122 | command->command_header->byte_count = 0; |
2138 | 2123 | ||
2139 | /* | 2124 | /* |
@@ -2152,10 +2137,15 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2152 | command->async_callback = callback; | 2137 | command->async_callback = callback; |
2153 | 2138 | ||
2154 | /* | 2139 | /* |
2155 | * Lock used to prevent this command from being issued | 2140 | * To prevent this command from being issued |
2156 | * if an internal command is in progress. | 2141 | * if an internal command is in progress or error handling is active. |
2157 | */ | 2142 | */ |
2158 | down_read(&port->dd->internal_sem); | 2143 | if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) || |
2144 | test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) { | ||
2145 | set_bit(tag, port->cmds_to_issue); | ||
2146 | set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); | ||
2147 | return; | ||
2148 | } | ||
2159 | 2149 | ||
2160 | /* Issue the command to the hardware */ | 2150 | /* Issue the command to the hardware */ |
2161 | mtip_issue_ncq_command(port, tag); | 2151 | mtip_issue_ncq_command(port, tag); |
@@ -2163,8 +2153,6 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2163 | /* Set the command's timeout value.*/ | 2153 | /* Set the command's timeout value.*/ |
2164 | port->commands[tag].comp_time = jiffies + msecs_to_jiffies( | 2154 | port->commands[tag].comp_time = jiffies + msecs_to_jiffies( |
2165 | MTIP_NCQ_COMMAND_TIMEOUT_MS); | 2155 | MTIP_NCQ_COMMAND_TIMEOUT_MS); |
2166 | |||
2167 | up_read(&port->dd->internal_sem); | ||
2168 | } | 2156 | } |
2169 | 2157 | ||
2170 | /* | 2158 | /* |
@@ -2400,10 +2388,9 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) | |||
2400 | timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); | 2388 | timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); |
2401 | 2389 | ||
2402 | do { | 2390 | do { |
2403 | #ifdef CONFIG_HOTPLUG | ||
2404 | if (mtip_check_surprise_removal(dd->pdev)) | 2391 | if (mtip_check_surprise_removal(dd->pdev)) |
2405 | return -EFAULT; | 2392 | return -EFAULT; |
2406 | #endif | 2393 | |
2407 | if (mtip_get_identify(dd->port, NULL) < 0) | 2394 | if (mtip_get_identify(dd->port, NULL) < 0) |
2408 | return -EFAULT; | 2395 | return -EFAULT; |
2409 | 2396 | ||
@@ -2439,6 +2426,74 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) | |||
2439 | } | 2426 | } |
2440 | 2427 | ||
2441 | /* | 2428 | /* |
2429 | * service thread to issue queued commands | ||
2430 | * | ||
2431 | * @data Pointer to the driver data structure. | ||
2432 | * | ||
2433 | * return value | ||
2434 | * 0 | ||
2435 | */ | ||
2436 | |||
2437 | static int mtip_service_thread(void *data) | ||
2438 | { | ||
2439 | struct driver_data *dd = (struct driver_data *)data; | ||
2440 | unsigned long slot, slot_start, slot_wrap; | ||
2441 | unsigned int num_cmd_slots = dd->slot_groups * 32; | ||
2442 | struct mtip_port *port = dd->port; | ||
2443 | |||
2444 | while (1) { | ||
2445 | /* | ||
2446 | * the condition is to check neither an internal command is | ||
2447 | * is in progress nor error handling is active | ||
2448 | */ | ||
2449 | wait_event_interruptible(port->svc_wait, (port->flags) && | ||
2450 | !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && | ||
2451 | !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags)); | ||
2452 | |||
2453 | if (kthread_should_stop()) | ||
2454 | break; | ||
2455 | |||
2456 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { | ||
2457 | set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2458 | slot = 1; | ||
2459 | /* used to restrict the loop to one iteration */ | ||
2460 | slot_start = num_cmd_slots; | ||
2461 | slot_wrap = 0; | ||
2462 | while (1) { | ||
2463 | slot = find_next_bit(port->cmds_to_issue, | ||
2464 | num_cmd_slots, slot); | ||
2465 | if (slot_wrap == 1) { | ||
2466 | if ((slot_start >= slot) || | ||
2467 | (slot >= num_cmd_slots)) | ||
2468 | break; | ||
2469 | } | ||
2470 | if (unlikely(slot_start == num_cmd_slots)) | ||
2471 | slot_start = slot; | ||
2472 | |||
2473 | if (unlikely(slot == num_cmd_slots)) { | ||
2474 | slot = 1; | ||
2475 | slot_wrap = 1; | ||
2476 | continue; | ||
2477 | } | ||
2478 | |||
2479 | /* Issue the command to the hardware */ | ||
2480 | mtip_issue_ncq_command(port, slot); | ||
2481 | |||
2482 | /* Set the command's timeout value.*/ | ||
2483 | port->commands[slot].comp_time = jiffies + | ||
2484 | msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS); | ||
2485 | |||
2486 | clear_bit(slot, port->cmds_to_issue); | ||
2487 | } | ||
2488 | |||
2489 | clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); | ||
2490 | clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | ||
2491 | } | ||
2492 | } | ||
2493 | return 0; | ||
2494 | } | ||
2495 | |||
2496 | /* | ||
2442 | * Called once for each card. | 2497 | * Called once for each card. |
2443 | * | 2498 | * |
2444 | * @dd Pointer to the driver data structure. | 2499 | * @dd Pointer to the driver data structure. |
@@ -2463,13 +2518,6 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2463 | 2518 | ||
2464 | hba_setup(dd); | 2519 | hba_setup(dd); |
2465 | 2520 | ||
2466 | /* | ||
2467 | * Initialize the internal semaphore | ||
2468 | * Use a rw semaphore to enable prioritization of | ||
2469 | * mgmnt ioctl traffic during heavy IO load | ||
2470 | */ | ||
2471 | init_rwsem(&dd->internal_sem); | ||
2472 | |||
2473 | tasklet_init(&dd->tasklet, mtip_tasklet, (unsigned long)dd); | 2521 | tasklet_init(&dd->tasklet, mtip_tasklet, (unsigned long)dd); |
2474 | 2522 | ||
2475 | dd->port = kzalloc(sizeof(struct mtip_port), GFP_KERNEL); | 2523 | dd->port = kzalloc(sizeof(struct mtip_port), GFP_KERNEL); |
@@ -2541,10 +2589,11 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2541 | 2589 | ||
2542 | if (readl(dd->mmio + HOST_CAP) & HOST_CAP_64) | 2590 | if (readl(dd->mmio + HOST_CAP) & HOST_CAP_64) |
2543 | dd->port->commands[i].command_header->ctbau = | 2591 | dd->port->commands[i].command_header->ctbau = |
2544 | cpu_to_le32( | 2592 | __force_bit2int cpu_to_le32( |
2545 | (dd->port->commands[i].command_dma >> 16) >> 16); | 2593 | (dd->port->commands[i].command_dma >> 16) >> 16); |
2546 | dd->port->commands[i].command_header->ctba = cpu_to_le32( | 2594 | dd->port->commands[i].command_header->ctba = |
2547 | dd->port->commands[i].command_dma & 0xffffffff); | 2595 | __force_bit2int cpu_to_le32( |
2596 | dd->port->commands[i].command_dma & 0xFFFFFFFF); | ||
2548 | 2597 | ||
2549 | /* | 2598 | /* |
2550 | * If this is not done, a bug is reported by the stock | 2599 | * If this is not done, a bug is reported by the stock |
@@ -2597,6 +2646,8 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2597 | dd->mmio + HOST_CTL); | 2646 | dd->mmio + HOST_CTL); |
2598 | 2647 | ||
2599 | init_timer(&dd->port->cmd_timer); | 2648 | init_timer(&dd->port->cmd_timer); |
2649 | init_waitqueue_head(&dd->port->svc_wait); | ||
2650 | |||
2600 | dd->port->cmd_timer.data = (unsigned long int) dd->port; | 2651 | dd->port->cmd_timer.data = (unsigned long int) dd->port; |
2601 | dd->port->cmd_timer.function = mtip_timeout_function; | 2652 | dd->port->cmd_timer.function = mtip_timeout_function; |
2602 | mod_timer(&dd->port->cmd_timer, | 2653 | mod_timer(&dd->port->cmd_timer, |
@@ -2667,12 +2718,12 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
2667 | 2718 | ||
2668 | del_timer_sync(&dd->port->cmd_timer); | 2719 | del_timer_sync(&dd->port->cmd_timer); |
2669 | 2720 | ||
2670 | /* Stop the bottom half tasklet. */ | ||
2671 | tasklet_kill(&dd->tasklet); | ||
2672 | |||
2673 | /* Release the IRQ. */ | 2721 | /* Release the IRQ. */ |
2674 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); | 2722 | devm_free_irq(&dd->pdev->dev, dd->pdev->irq, dd); |
2675 | 2723 | ||
2724 | /* Stop the bottom half tasklet. */ | ||
2725 | tasklet_kill(&dd->tasklet); | ||
2726 | |||
2676 | /* Free the command/command header memory. */ | 2727 | /* Free the command/command header memory. */ |
2677 | dmam_free_coherent(&dd->pdev->dev, | 2728 | dmam_free_coherent(&dd->pdev->dev, |
2678 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), | 2729 | HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), |
@@ -2835,7 +2886,7 @@ static int mtip_block_ioctl(struct block_device *dev, | |||
2835 | 2886 | ||
2836 | switch (cmd) { | 2887 | switch (cmd) { |
2837 | case BLKFLSBUF: | 2888 | case BLKFLSBUF: |
2838 | return 0; | 2889 | return -ENOTTY; |
2839 | default: | 2890 | default: |
2840 | return mtip_hw_ioctl(dd, cmd, arg); | 2891 | return mtip_hw_ioctl(dd, cmd, arg); |
2841 | } | 2892 | } |
@@ -2870,19 +2921,20 @@ static int mtip_block_compat_ioctl(struct block_device *dev, | |||
2870 | 2921 | ||
2871 | switch (cmd) { | 2922 | switch (cmd) { |
2872 | case BLKFLSBUF: | 2923 | case BLKFLSBUF: |
2873 | return 0; | 2924 | return -ENOTTY; |
2874 | case HDIO_DRIVE_TASKFILE: { | 2925 | case HDIO_DRIVE_TASKFILE: { |
2875 | struct mtip_compat_ide_task_request_s *compat_req_task; | 2926 | struct mtip_compat_ide_task_request_s __user *compat_req_task; |
2876 | ide_task_request_t req_task; | 2927 | ide_task_request_t req_task; |
2877 | int compat_tasksize, outtotal, ret; | 2928 | int compat_tasksize, outtotal, ret; |
2878 | 2929 | ||
2879 | compat_tasksize = sizeof(struct mtip_compat_ide_task_request_s); | 2930 | compat_tasksize = |
2931 | sizeof(struct mtip_compat_ide_task_request_s); | ||
2880 | 2932 | ||
2881 | compat_req_task = | 2933 | compat_req_task = |
2882 | (struct mtip_compat_ide_task_request_s __user *) arg; | 2934 | (struct mtip_compat_ide_task_request_s __user *) arg; |
2883 | 2935 | ||
2884 | if (copy_from_user(&req_task, (void __user *) arg, | 2936 | if (copy_from_user(&req_task, (void __user *) arg, |
2885 | compat_tasksize - (2 * sizeof(compat_long_t)))) | 2937 | compat_tasksize - (2 * sizeof(compat_long_t)))) |
2886 | return -EFAULT; | 2938 | return -EFAULT; |
2887 | 2939 | ||
2888 | if (get_user(req_task.out_size, &compat_req_task->out_size)) | 2940 | if (get_user(req_task.out_size, &compat_req_task->out_size)) |
@@ -2950,12 +3002,8 @@ static int mtip_block_getgeo(struct block_device *dev, | |||
2950 | 3002 | ||
2951 | geo->heads = 224; | 3003 | geo->heads = 224; |
2952 | geo->sectors = 56; | 3004 | geo->sectors = 56; |
2953 | #if BITS_PER_LONG == 64 | 3005 | sector_div(capacity, (geo->heads * geo->sectors)); |
2954 | geo->cylinders = capacity / (geo->heads * geo->sectors); | ||
2955 | #else | ||
2956 | do_div(capacity, (geo->heads * geo->sectors)); | ||
2957 | geo->cylinders = capacity; | 3006 | geo->cylinders = capacity; |
2958 | #endif | ||
2959 | return 0; | 3007 | return 0; |
2960 | } | 3008 | } |
2961 | 3009 | ||
@@ -2999,11 +3047,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
2999 | return; | 3047 | return; |
3000 | } | 3048 | } |
3001 | 3049 | ||
3002 | if (unlikely(atomic_read(&dd->eh_active))) { | ||
3003 | bio_endio(bio, -EBUSY); | ||
3004 | return; | ||
3005 | } | ||
3006 | |||
3007 | sg = mtip_hw_get_scatterlist(dd, &tag); | 3050 | sg = mtip_hw_get_scatterlist(dd, &tag); |
3008 | if (likely(sg != NULL)) { | 3051 | if (likely(sg != NULL)) { |
3009 | blk_queue_bounce(queue, &bio); | 3052 | blk_queue_bounce(queue, &bio); |
@@ -3032,7 +3075,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3032 | tag, | 3075 | tag, |
3033 | bio_endio, | 3076 | bio_endio, |
3034 | bio, | 3077 | bio, |
3035 | bio->bi_rw & REQ_FLUSH, | 3078 | bio->bi_rw & REQ_FUA, |
3036 | bio_data_dir(bio)); | 3079 | bio_data_dir(bio)); |
3037 | } else | 3080 | } else |
3038 | bio_io_error(bio); | 3081 | bio_io_error(bio); |
@@ -3055,6 +3098,7 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3055 | sector_t capacity; | 3098 | sector_t capacity; |
3056 | unsigned int index = 0; | 3099 | unsigned int index = 0; |
3057 | struct kobject *kobj; | 3100 | struct kobject *kobj; |
3101 | unsigned char thd_name[16]; | ||
3058 | 3102 | ||
3059 | /* Initialize the protocol layer. */ | 3103 | /* Initialize the protocol layer. */ |
3060 | rv = mtip_hw_init(dd); | 3104 | rv = mtip_hw_init(dd); |
@@ -3082,6 +3126,7 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3082 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); | 3126 | blk_queue_max_segments(dd->queue, MTIP_MAX_SG); |
3083 | blk_queue_physical_block_size(dd->queue, 4096); | 3127 | blk_queue_physical_block_size(dd->queue, 4096); |
3084 | blk_queue_io_min(dd->queue, 4096); | 3128 | blk_queue_io_min(dd->queue, 4096); |
3129 | blk_queue_flush(dd->queue, 0); | ||
3085 | 3130 | ||
3086 | dd->disk = alloc_disk(MTIP_MAX_MINORS); | 3131 | dd->disk = alloc_disk(MTIP_MAX_MINORS); |
3087 | if (dd->disk == NULL) { | 3132 | if (dd->disk == NULL) { |
@@ -3142,6 +3187,18 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
3142 | kobject_put(kobj); | 3187 | kobject_put(kobj); |
3143 | } | 3188 | } |
3144 | 3189 | ||
3190 | sprintf(thd_name, "mtip_svc_thd_%02d", index); | ||
3191 | |||
3192 | dd->mtip_svc_handler = kthread_run(mtip_service_thread, | ||
3193 | dd, thd_name); | ||
3194 | |||
3195 | if (IS_ERR(dd->mtip_svc_handler)) { | ||
3196 | printk(KERN_ERR "mtip32xx: service thread failed to start\n"); | ||
3197 | dd->mtip_svc_handler = NULL; | ||
3198 | rv = -EFAULT; | ||
3199 | goto read_capacity_error; | ||
3200 | } | ||
3201 | |||
3145 | return rv; | 3202 | return rv; |
3146 | 3203 | ||
3147 | read_capacity_error: | 3204 | read_capacity_error: |
@@ -3183,6 +3240,13 @@ protocol_init_error: | |||
3183 | static int mtip_block_remove(struct driver_data *dd) | 3240 | static int mtip_block_remove(struct driver_data *dd) |
3184 | { | 3241 | { |
3185 | struct kobject *kobj; | 3242 | struct kobject *kobj; |
3243 | |||
3244 | if (dd->mtip_svc_handler) { | ||
3245 | set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); | ||
3246 | wake_up_interruptible(&dd->port->svc_wait); | ||
3247 | kthread_stop(dd->mtip_svc_handler); | ||
3248 | } | ||
3249 | |||
3186 | /* Clean up the sysfs attributes managed by the protocol layer. */ | 3250 | /* Clean up the sysfs attributes managed by the protocol layer. */ |
3187 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); | 3251 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); |
3188 | if (kobj) { | 3252 | if (kobj) { |
@@ -3275,7 +3339,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
3275 | atomic_set(&dd->drv_cleanup_done, true); | 3339 | atomic_set(&dd->drv_cleanup_done, true); |
3276 | 3340 | ||
3277 | atomic_set(&dd->resumeflag, false); | 3341 | atomic_set(&dd->resumeflag, false); |
3278 | atomic_set(&dd->eh_active, 0); | ||
3279 | 3342 | ||
3280 | /* Attach the private data to this PCI device. */ | 3343 | /* Attach the private data to this PCI device. */ |
3281 | pci_set_drvdata(pdev, dd); | 3344 | pci_set_drvdata(pdev, dd); |
@@ -3317,7 +3380,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
3317 | 3380 | ||
3318 | /* Copy the info we may need later into the private data structure. */ | 3381 | /* Copy the info we may need later into the private data structure. */ |
3319 | dd->major = mtip_major; | 3382 | dd->major = mtip_major; |
3320 | dd->protocol = ent->driver_data; | ||
3321 | dd->instance = instance; | 3383 | dd->instance = instance; |
3322 | dd->pdev = pdev; | 3384 | dd->pdev = pdev; |
3323 | 3385 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 17be4f444e7d..933192abe178 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -47,11 +47,11 @@ | |||
47 | 47 | ||
48 | /* ftl rebuild */ | 48 | /* ftl rebuild */ |
49 | #define MTIP_FTL_REBUILD_OFFSET 142 | 49 | #define MTIP_FTL_REBUILD_OFFSET 142 |
50 | #define MTIP_FTL_REBUILD_MAGIC 0xed51 | 50 | #define MTIP_FTL_REBUILD_MAGIC 0xED51 |
51 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 | 51 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 |
52 | 52 | ||
53 | /* Macro to extract the tag bit number from a tag value. */ | 53 | /* Macro to extract the tag bit number from a tag value. */ |
54 | #define MTIP_TAG_BIT(tag) (tag & 0x1f) | 54 | #define MTIP_TAG_BIT(tag) (tag & 0x1F) |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Macro to extract the tag index from a tag value. The index | 57 | * Macro to extract the tag index from a tag value. The index |
@@ -81,7 +81,7 @@ | |||
81 | 81 | ||
82 | /* Driver name and version strings */ | 82 | /* Driver name and version strings */ |
83 | #define MTIP_DRV_NAME "mtip32xx" | 83 | #define MTIP_DRV_NAME "mtip32xx" |
84 | #define MTIP_DRV_VERSION "1.2.6os2" | 84 | #define MTIP_DRV_VERSION "1.2.6os3" |
85 | 85 | ||
86 | /* Maximum number of minor device numbers per device. */ | 86 | /* Maximum number of minor device numbers per device. */ |
87 | #define MTIP_MAX_MINORS 16 | 87 | #define MTIP_MAX_MINORS 16 |
@@ -114,6 +114,15 @@ | |||
114 | #define dbg_printk(format, arg...) | 114 | #define dbg_printk(format, arg...) |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | #define __force_bit2int (unsigned int __force) | ||
118 | |||
119 | /* below are bit numbers in 'flags' defined in mtip_port */ | ||
120 | #define MTIP_FLAG_IC_ACTIVE_BIT 0 | ||
121 | #define MTIP_FLAG_EH_ACTIVE_BIT 1 | ||
122 | #define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 | ||
123 | #define MTIP_FLAG_ISSUE_CMDS_BIT 4 | ||
124 | #define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 | ||
125 | |||
117 | /* Register Frame Information Structure (FIS), host to device. */ | 126 | /* Register Frame Information Structure (FIS), host to device. */ |
118 | struct host_to_dev_fis { | 127 | struct host_to_dev_fis { |
119 | /* | 128 | /* |
@@ -262,7 +271,7 @@ struct mtip_cmd { | |||
262 | 271 | ||
263 | unsigned long comp_time; /* command completion time, in jiffies */ | 272 | unsigned long comp_time; /* command completion time, in jiffies */ |
264 | 273 | ||
265 | atomic_t active; /* declares if this command sent to the drive. */ | 274 | atomic_t active; /* declares if this command sent to the drive. */ |
266 | }; | 275 | }; |
267 | 276 | ||
268 | /* Structure used to describe a port. */ | 277 | /* Structure used to describe a port. */ |
@@ -278,7 +287,7 @@ struct mtip_port { | |||
278 | void __iomem *mmio; | 287 | void __iomem *mmio; |
279 | /* Array of pointers to the memory mapped s_active registers. */ | 288 | /* Array of pointers to the memory mapped s_active registers. */ |
280 | void __iomem *s_active[MTIP_MAX_SLOT_GROUPS]; | 289 | void __iomem *s_active[MTIP_MAX_SLOT_GROUPS]; |
281 | /* Array of pointers to the memory mapped completed registers. */ | 290 | /* Array of pointers to the memory mapped completed registers. */ |
282 | void __iomem *completed[MTIP_MAX_SLOT_GROUPS]; | 291 | void __iomem *completed[MTIP_MAX_SLOT_GROUPS]; |
283 | /* Array of pointers to the memory mapped Command Issue registers. */ | 292 | /* Array of pointers to the memory mapped Command Issue registers. */ |
284 | void __iomem *cmd_issue[MTIP_MAX_SLOT_GROUPS]; | 293 | void __iomem *cmd_issue[MTIP_MAX_SLOT_GROUPS]; |
@@ -340,13 +349,23 @@ struct mtip_port { | |||
340 | */ | 349 | */ |
341 | unsigned long allocated[SLOTBITS_IN_LONGS]; | 350 | unsigned long allocated[SLOTBITS_IN_LONGS]; |
342 | /* | 351 | /* |
352 | * used to queue commands when an internal command is in progress | ||
353 | * or error handling is active | ||
354 | */ | ||
355 | unsigned long cmds_to_issue[SLOTBITS_IN_LONGS]; | ||
356 | /* | ||
343 | * Array of command slots. Structure includes pointers to the | 357 | * Array of command slots. Structure includes pointers to the |
344 | * command header and command table, and completion function and data | 358 | * command header and command table, and completion function and data |
345 | * pointers. | 359 | * pointers. |
346 | */ | 360 | */ |
347 | struct mtip_cmd commands[MTIP_MAX_COMMAND_SLOTS]; | 361 | struct mtip_cmd commands[MTIP_MAX_COMMAND_SLOTS]; |
348 | /* Non-zero if an internal command is in progress. */ | 362 | /* Used by mtip_service_thread to wait for an event */ |
349 | int internal_cmd_in_progress; | 363 | wait_queue_head_t svc_wait; |
364 | /* | ||
365 | * indicates the state of the port. Also, helps the service thread | ||
366 | * to determine its action on wake up. | ||
367 | */ | ||
368 | unsigned long flags; | ||
350 | /* | 369 | /* |
351 | * Timer used to complete commands that have been active for too long. | 370 | * Timer used to complete commands that have been active for too long. |
352 | */ | 371 | */ |
@@ -372,18 +391,11 @@ struct driver_data { | |||
372 | 391 | ||
373 | int instance; /* Instance number. First device probed is 0, ... */ | 392 | int instance; /* Instance number. First device probed is 0, ... */ |
374 | 393 | ||
375 | int protocol; /* FIXME: Protocol ops array index. */ | ||
376 | |||
377 | struct gendisk *disk; /* Pointer to our gendisk structure. */ | 394 | struct gendisk *disk; /* Pointer to our gendisk structure. */ |
378 | 395 | ||
379 | struct pci_dev *pdev; /* Pointer to the PCI device structure. */ | 396 | struct pci_dev *pdev; /* Pointer to the PCI device structure. */ |
380 | 397 | ||
381 | struct request_queue *queue; /* Our request queue. */ | 398 | struct request_queue *queue; /* Our request queue. */ |
382 | /* | ||
383 | * Semaphore used to lock out read/write commands during the | ||
384 | * execution of an internal command. | ||
385 | */ | ||
386 | struct rw_semaphore internal_sem; | ||
387 | 399 | ||
388 | struct mtip_port *port; /* Pointer to the port data structure. */ | 400 | struct mtip_port *port; /* Pointer to the port data structure. */ |
389 | 401 | ||
@@ -403,6 +415,8 @@ struct driver_data { | |||
403 | atomic_t resumeflag; /* Atomic variable to track suspend/resume */ | 415 | atomic_t resumeflag; /* Atomic variable to track suspend/resume */ |
404 | 416 | ||
405 | atomic_t eh_active; /* Flag for error handling tracking */ | 417 | atomic_t eh_active; /* Flag for error handling tracking */ |
418 | |||
419 | struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ | ||
406 | }; | 420 | }; |
407 | 421 | ||
408 | #endif | 422 | #endif |