diff options
author | Asai Thambi S P <asamymuthupa@micron.com> | 2012-04-09 02:35:38 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-04-09 02:35:38 -0400 |
commit | 45038367c271f83b649b16551bf2d8174b203cb9 (patch) | |
tree | 3669503784863f51df047f82d4cbce1b4576e65e /drivers/block/mtip32xx/mtip32xx.c | |
parent | 6d27f09a6398ee086b11804aa3a16609876f0c7c (diff) |
mtip32xx: Add new bitwise flag 'dd_flag'
* Merged the following flags into one variable 'dd_flag':
* drv_cleanup_done
* resumeflag
* Added the following flags into 'dd_flag'
* remove pending
* init done
* Removed 'ftlrebuildflag' (similar flag is already part of mti_port->flags)
Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/mtip32xx/mtip32xx.c')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 211 |
1 files changed, 161 insertions, 50 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index c37073ddf7d4..34b395d2d98d 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
38 | #include <../drivers/ata/ahci.h> | 38 | #include <../drivers/ata/ahci.h> |
39 | #include <linux/export.h> | ||
39 | #include "mtip32xx.h" | 40 | #include "mtip32xx.h" |
40 | 41 | ||
41 | #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) | 42 | #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) |
@@ -44,6 +45,7 @@ | |||
44 | #define HW_PORT_PRIV_DMA_SZ \ | 45 | #define HW_PORT_PRIV_DMA_SZ \ |
45 | (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) | 46 | (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) |
46 | 47 | ||
48 | #define HOST_CAP_NZDMA (1 << 19) | ||
47 | #define HOST_HSORG 0xFC | 49 | #define HOST_HSORG 0xFC |
48 | #define HSORG_DISABLE_SLOTGRP_INTR (1<<24) | 50 | #define HSORG_DISABLE_SLOTGRP_INTR (1<<24) |
49 | #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) | 51 | #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) |
@@ -139,6 +141,12 @@ static void mtip_command_cleanup(struct driver_data *dd) | |||
139 | int group = 0, commandslot = 0, commandindex = 0; | 141 | int group = 0, commandslot = 0, commandindex = 0; |
140 | struct mtip_cmd *command; | 142 | struct mtip_cmd *command; |
141 | struct mtip_port *port = dd->port; | 143 | struct mtip_port *port = dd->port; |
144 | static int in_progress; | ||
145 | |||
146 | if (in_progress) | ||
147 | return; | ||
148 | |||
149 | in_progress = 1; | ||
142 | 150 | ||
143 | for (group = 0; group < 4; group++) { | 151 | for (group = 0; group < 4; group++) { |
144 | for (commandslot = 0; commandslot < 32; commandslot++) { | 152 | for (commandslot = 0; commandslot < 32; commandslot++) { |
@@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd) | |||
165 | 173 | ||
166 | up(&port->cmd_slot); | 174 | up(&port->cmd_slot); |
167 | 175 | ||
168 | atomic_set(&dd->drv_cleanup_done, true); | 176 | set_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag); |
177 | in_progress = 0; | ||
169 | } | 178 | } |
170 | 179 | ||
171 | /* | 180 | /* |
@@ -262,6 +271,9 @@ static int hba_reset_nosleep(struct driver_data *dd) | |||
262 | && time_before(jiffies, timeout)) | 271 | && time_before(jiffies, timeout)) |
263 | mdelay(1); | 272 | mdelay(1); |
264 | 273 | ||
274 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) | ||
275 | return -1; | ||
276 | |||
265 | if (readl(dd->mmio + HOST_CTL) & HOST_RESET) | 277 | if (readl(dd->mmio + HOST_CTL) & HOST_RESET) |
266 | return -1; | 278 | return -1; |
267 | 279 | ||
@@ -451,6 +463,9 @@ static void mtip_restart_port(struct mtip_port *port) | |||
451 | && time_before(jiffies, timeout)) | 463 | && time_before(jiffies, timeout)) |
452 | ; | 464 | ; |
453 | 465 | ||
466 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | ||
467 | return; | ||
468 | |||
454 | /* | 469 | /* |
455 | * Chip quirk: escalate to hba reset if | 470 | * Chip quirk: escalate to hba reset if |
456 | * PxCMD.CR not clear after 500 ms | 471 | * PxCMD.CR not clear after 500 ms |
@@ -479,6 +494,9 @@ static void mtip_restart_port(struct mtip_port *port) | |||
479 | while (time_before(jiffies, timeout)) | 494 | while (time_before(jiffies, timeout)) |
480 | ; | 495 | ; |
481 | 496 | ||
497 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | ||
498 | return; | ||
499 | |||
482 | /* Clear PxSCTL.DET */ | 500 | /* Clear PxSCTL.DET */ |
483 | writel(readl(port->mmio + PORT_SCR_CTL) & ~1, | 501 | writel(readl(port->mmio + PORT_SCR_CTL) & ~1, |
484 | port->mmio + PORT_SCR_CTL); | 502 | port->mmio + PORT_SCR_CTL); |
@@ -490,6 +508,9 @@ static void mtip_restart_port(struct mtip_port *port) | |||
490 | && time_before(jiffies, timeout)) | 508 | && time_before(jiffies, timeout)) |
491 | ; | 509 | ; |
492 | 510 | ||
511 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | ||
512 | return; | ||
513 | |||
493 | if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) | 514 | if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) |
494 | dev_warn(&port->dd->pdev->dev, | 515 | dev_warn(&port->dd->pdev->dev, |
495 | "COM reset failed\n"); | 516 | "COM reset failed\n"); |
@@ -520,7 +541,7 @@ static void mtip_timeout_function(unsigned long int data) | |||
520 | if (unlikely(!port)) | 541 | if (unlikely(!port)) |
521 | return; | 542 | return; |
522 | 543 | ||
523 | if (atomic_read(&port->dd->resumeflag) == true) { | 544 | if (test_bit(MTIP_DD_FLAG_RESUME_BIT, &port->dd->dd_flag)) { |
524 | mod_timer(&port->cmd_timer, | 545 | mod_timer(&port->cmd_timer, |
525 | jiffies + msecs_to_jiffies(30000)); | 546 | jiffies + msecs_to_jiffies(30000)); |
526 | return; | 547 | return; |
@@ -970,6 +991,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) | |||
970 | /* don't proceed further */ | 991 | /* don't proceed further */ |
971 | return IRQ_HANDLED; | 992 | return IRQ_HANDLED; |
972 | } | 993 | } |
994 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
995 | &dd->dd_flag)) | ||
996 | return rv; | ||
973 | 997 | ||
974 | mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); | 998 | mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); |
975 | } | 999 | } |
@@ -1040,6 +1064,9 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) | |||
1040 | msleep(20); | 1064 | msleep(20); |
1041 | continue; /* svc thd is actively issuing commands */ | 1065 | continue; /* svc thd is actively issuing commands */ |
1042 | } | 1066 | } |
1067 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
1068 | &port->dd->dd_flag)) | ||
1069 | return -EFAULT; | ||
1043 | /* | 1070 | /* |
1044 | * Ignore s_active bit 0 of array element 0. | 1071 | * Ignore s_active bit 0 of array element 0. |
1045 | * This bit will always be set | 1072 | * This bit will always be set |
@@ -1161,6 +1188,12 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1161 | "Internal command did not complete [%d] " | 1188 | "Internal command did not complete [%d] " |
1162 | "within timeout of %lu ms\n", | 1189 | "within timeout of %lu ms\n", |
1163 | atomic, timeout); | 1190 | atomic, timeout); |
1191 | if (mtip_check_surprise_removal(port->dd->pdev) || | ||
1192 | test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
1193 | &port->dd->dd_flag)) { | ||
1194 | rv = -ENXIO; | ||
1195 | goto exec_ic_exit; | ||
1196 | } | ||
1164 | rv = -EAGAIN; | 1197 | rv = -EAGAIN; |
1165 | } | 1198 | } |
1166 | 1199 | ||
@@ -1168,6 +1201,15 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1168 | & (1 << MTIP_TAG_INTERNAL)) { | 1201 | & (1 << MTIP_TAG_INTERNAL)) { |
1169 | dev_warn(&port->dd->pdev->dev, | 1202 | dev_warn(&port->dd->pdev->dev, |
1170 | "Retiring internal command but CI is 1.\n"); | 1203 | "Retiring internal command but CI is 1.\n"); |
1204 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
1205 | &port->dd->dd_flag)) { | ||
1206 | hba_reset_nosleep(port->dd); | ||
1207 | rv = -ENXIO; | ||
1208 | } else { | ||
1209 | mtip_restart_port(port); | ||
1210 | rv = -EAGAIN; | ||
1211 | } | ||
1212 | goto exec_ic_exit; | ||
1171 | } | 1213 | } |
1172 | 1214 | ||
1173 | } else { | 1215 | } else { |
@@ -1177,8 +1219,14 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1177 | while ((readl( | 1219 | while ((readl( |
1178 | port->cmd_issue[MTIP_TAG_INTERNAL]) | 1220 | port->cmd_issue[MTIP_TAG_INTERNAL]) |
1179 | & (1 << MTIP_TAG_INTERNAL)) | 1221 | & (1 << MTIP_TAG_INTERNAL)) |
1180 | && time_before(jiffies, timeout)) | 1222 | && time_before(jiffies, timeout)) { |
1181 | ; | 1223 | if (mtip_check_surprise_removal(port->dd->pdev) || |
1224 | test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
1225 | &port->dd->dd_flag)) { | ||
1226 | rv = -ENXIO; | ||
1227 | goto exec_ic_exit; | ||
1228 | } | ||
1229 | } | ||
1182 | 1230 | ||
1183 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) | 1231 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) |
1184 | & (1 << MTIP_TAG_INTERNAL)) { | 1232 | & (1 << MTIP_TAG_INTERNAL)) { |
@@ -1186,9 +1234,17 @@ static int mtip_exec_internal_command(struct mtip_port *port, | |||
1186 | "Internal command did not complete [%d]\n", | 1234 | "Internal command did not complete [%d]\n", |
1187 | atomic); | 1235 | atomic); |
1188 | rv = -EAGAIN; | 1236 | rv = -EAGAIN; |
1237 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
1238 | &port->dd->dd_flag)) { | ||
1239 | hba_reset_nosleep(port->dd); | ||
1240 | rv = -ENXIO; | ||
1241 | } else { | ||
1242 | mtip_restart_port(port); | ||
1243 | rv = -EAGAIN; | ||
1244 | } | ||
1189 | } | 1245 | } |
1190 | } | 1246 | } |
1191 | 1247 | exec_ic_exit: | |
1192 | /* Clear the allocated and active bits for the internal command. */ | 1248 | /* Clear the allocated and active bits for the internal command. */ |
1193 | atomic_set(&int_cmd->active, 0); | 1249 | atomic_set(&int_cmd->active, 0); |
1194 | release_slot(port, MTIP_TAG_INTERNAL); | 1250 | release_slot(port, MTIP_TAG_INTERNAL); |
@@ -1242,6 +1298,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) | |||
1242 | int rv = 0; | 1298 | int rv = 0; |
1243 | struct host_to_dev_fis fis; | 1299 | struct host_to_dev_fis fis; |
1244 | 1300 | ||
1301 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &port->dd->dd_flag)) | ||
1302 | return -EFAULT; | ||
1303 | |||
1245 | /* Build the FIS. */ | 1304 | /* Build the FIS. */ |
1246 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); | 1305 | memset(&fis, 0, sizeof(struct host_to_dev_fis)); |
1247 | fis.type = 0x27; | 1306 | fis.type = 0x27; |
@@ -1507,9 +1566,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1507 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ | 1566 | fis.device = command[6] & ~0x10; /* Clear the dev bit*/ |
1508 | 1567 | ||
1509 | 1568 | ||
1510 | dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, " | 1569 | dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", |
1511 | "nsect %x, sect %x, lcyl %x, " | ||
1512 | "hcyl %x, sel %x\n", | ||
1513 | __func__, | 1570 | __func__, |
1514 | command[0], | 1571 | command[0], |
1515 | command[1], | 1572 | command[1], |
@@ -1536,8 +1593,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) | |||
1536 | command[4] = reply->cyl_low; | 1593 | command[4] = reply->cyl_low; |
1537 | command[5] = reply->cyl_hi; | 1594 | command[5] = reply->cyl_hi; |
1538 | 1595 | ||
1539 | dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, " | 1596 | dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", |
1540 | "err %x , cyl_lo %x cyl_hi %x\n", | ||
1541 | __func__, | 1597 | __func__, |
1542 | command[0], | 1598 | command[0], |
1543 | command[1], | 1599 | command[1], |
@@ -2082,14 +2138,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2082 | struct host_to_dev_fis *fis; | 2138 | struct host_to_dev_fis *fis; |
2083 | struct mtip_port *port = dd->port; | 2139 | struct mtip_port *port = dd->port; |
2084 | struct mtip_cmd *command = &port->commands[tag]; | 2140 | struct mtip_cmd *command = &port->commands[tag]; |
2141 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
2085 | 2142 | ||
2086 | /* Map the scatter list for DMA access */ | 2143 | /* Map the scatter list for DMA access */ |
2087 | if (dir == READ) | 2144 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); |
2088 | nents = dma_map_sg(&dd->pdev->dev, command->sg, | ||
2089 | nents, DMA_FROM_DEVICE); | ||
2090 | else | ||
2091 | nents = dma_map_sg(&dd->pdev->dev, command->sg, | ||
2092 | nents, DMA_TO_DEVICE); | ||
2093 | 2145 | ||
2094 | command->scatter_ents = nents; | 2146 | command->scatter_ents = nents; |
2095 | 2147 | ||
@@ -2129,7 +2181,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |||
2129 | */ | 2181 | */ |
2130 | command->comp_data = dd; | 2182 | command->comp_data = dd; |
2131 | command->comp_func = mtip_async_complete; | 2183 | command->comp_func = mtip_async_complete; |
2132 | command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 2184 | command->direction = dma_dir; |
2133 | 2185 | ||
2134 | /* | 2186 | /* |
2135 | * Set the completion function and data for the command passed | 2187 | * Set the completion function and data for the command passed |
@@ -2193,6 +2245,10 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, | |||
2193 | down(&dd->port->cmd_slot); | 2245 | down(&dd->port->cmd_slot); |
2194 | *tag = get_slot(dd->port); | 2246 | *tag = get_slot(dd->port); |
2195 | 2247 | ||
2248 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { | ||
2249 | up(&dd->port->cmd_slot); | ||
2250 | return NULL; | ||
2251 | } | ||
2196 | if (unlikely(*tag < 0)) | 2252 | if (unlikely(*tag < 0)) |
2197 | return NULL; | 2253 | return NULL; |
2198 | 2254 | ||
@@ -2209,7 +2265,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, | |||
2209 | * return value | 2265 | * return value |
2210 | * The size, in bytes, of the data copied into buf. | 2266 | * The size, in bytes, of the data copied into buf. |
2211 | */ | 2267 | */ |
2212 | static ssize_t hw_show_registers(struct device *dev, | 2268 | static ssize_t mtip_hw_show_registers(struct device *dev, |
2213 | struct device_attribute *attr, | 2269 | struct device_attribute *attr, |
2214 | char *buf) | 2270 | char *buf) |
2215 | { | 2271 | { |
@@ -2255,7 +2311,7 @@ static ssize_t hw_show_registers(struct device *dev, | |||
2255 | 2311 | ||
2256 | return size; | 2312 | return size; |
2257 | } | 2313 | } |
2258 | static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); | 2314 | static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); |
2259 | 2315 | ||
2260 | /* | 2316 | /* |
2261 | * Create the sysfs related attributes. | 2317 | * Create the sysfs related attributes. |
@@ -2386,10 +2442,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) | |||
2386 | "FTL rebuild in progress. Polling for completion.\n"); | 2442 | "FTL rebuild in progress. Polling for completion.\n"); |
2387 | 2443 | ||
2388 | start = jiffies; | 2444 | start = jiffies; |
2389 | dd->ftlrebuildflag = 1; | ||
2390 | timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); | 2445 | timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); |
2391 | 2446 | ||
2392 | do { | 2447 | do { |
2448 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
2449 | &dd->dd_flag))) | ||
2450 | return -EFAULT; | ||
2393 | if (mtip_check_surprise_removal(dd->pdev)) | 2451 | if (mtip_check_surprise_removal(dd->pdev)) |
2394 | return -EFAULT; | 2452 | return -EFAULT; |
2395 | 2453 | ||
@@ -2410,22 +2468,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) | |||
2410 | dev_warn(&dd->pdev->dev, | 2468 | dev_warn(&dd->pdev->dev, |
2411 | "FTL rebuild complete (%d secs).\n", | 2469 | "FTL rebuild complete (%d secs).\n", |
2412 | jiffies_to_msecs(jiffies - start) / 1000); | 2470 | jiffies_to_msecs(jiffies - start) / 1000); |
2413 | dd->ftlrebuildflag = 0; | ||
2414 | mtip_block_initialize(dd); | 2471 | mtip_block_initialize(dd); |
2415 | break; | 2472 | return 0; |
2416 | } | 2473 | } |
2417 | ssleep(10); | 2474 | ssleep(10); |
2418 | } while (time_before(jiffies, timeout)); | 2475 | } while (time_before(jiffies, timeout)); |
2419 | 2476 | ||
2420 | /* Check for timeout */ | 2477 | /* Check for timeout */ |
2421 | if (dd->ftlrebuildflag) { | 2478 | dev_err(&dd->pdev->dev, |
2422 | dev_err(&dd->pdev->dev, | ||
2423 | "Timed out waiting for FTL rebuild to complete (%d secs).\n", | 2479 | "Timed out waiting for FTL rebuild to complete (%d secs).\n", |
2424 | jiffies_to_msecs(jiffies - start) / 1000); | 2480 | jiffies_to_msecs(jiffies - start) / 1000); |
2425 | return -EFAULT; | 2481 | return -EFAULT; |
2426 | } | ||
2427 | |||
2428 | return 0; | ||
2429 | } | 2482 | } |
2430 | 2483 | ||
2431 | /* | 2484 | /* |
@@ -2456,6 +2509,9 @@ static int mtip_service_thread(void *data) | |||
2456 | if (kthread_should_stop()) | 2509 | if (kthread_should_stop()) |
2457 | break; | 2510 | break; |
2458 | 2511 | ||
2512 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, | ||
2513 | &dd->dd_flag))) | ||
2514 | break; | ||
2459 | set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); | 2515 | set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); |
2460 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { | 2516 | if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { |
2461 | slot = 1; | 2517 | slot = 1; |
@@ -2515,6 +2571,7 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2515 | int i; | 2571 | int i; |
2516 | int rv; | 2572 | int rv; |
2517 | unsigned int num_command_slots; | 2573 | unsigned int num_command_slots; |
2574 | unsigned long timeout, timetaken; | ||
2518 | 2575 | ||
2519 | dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; | 2576 | dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; |
2520 | 2577 | ||
@@ -2625,14 +2682,43 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2625 | dd->port->mmio + i*0x80 + PORT_SDBV; | 2682 | dd->port->mmio + i*0x80 + PORT_SDBV; |
2626 | } | 2683 | } |
2627 | 2684 | ||
2628 | /* Reset the HBA. */ | 2685 | timetaken = jiffies; |
2629 | if (mtip_hba_reset(dd) < 0) { | 2686 | timeout = jiffies + msecs_to_jiffies(30000); |
2630 | dev_err(&dd->pdev->dev, | 2687 | while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) && |
2631 | "Card did not reset within timeout\n"); | 2688 | time_before(jiffies, timeout)) { |
2632 | rv = -EIO; | 2689 | mdelay(100); |
2690 | } | ||
2691 | if (unlikely(mtip_check_surprise_removal(dd->pdev))) { | ||
2692 | timetaken = jiffies - timetaken; | ||
2693 | dev_warn(&dd->pdev->dev, | ||
2694 | "Surprise removal detected at %u ms\n", | ||
2695 | jiffies_to_msecs(timetaken)); | ||
2696 | rv = -ENODEV; | ||
2697 | goto out2 ; | ||
2698 | } | ||
2699 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) { | ||
2700 | timetaken = jiffies - timetaken; | ||
2701 | dev_warn(&dd->pdev->dev, | ||
2702 | "Removal detected at %u ms\n", | ||
2703 | jiffies_to_msecs(timetaken)); | ||
2704 | rv = -EFAULT; | ||
2633 | goto out2; | 2705 | goto out2; |
2634 | } | 2706 | } |
2635 | 2707 | ||
2708 | /* Conditionally reset the HBA. */ | ||
2709 | if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) { | ||
2710 | if (mtip_hba_reset(dd) < 0) { | ||
2711 | dev_err(&dd->pdev->dev, | ||
2712 | "Card did not reset within timeout\n"); | ||
2713 | rv = -EIO; | ||
2714 | goto out2; | ||
2715 | } | ||
2716 | } else { | ||
2717 | /* Clear any pending interrupts on the HBA */ | ||
2718 | writel(readl(dd->mmio + HOST_IRQ_STAT), | ||
2719 | dd->mmio + HOST_IRQ_STAT); | ||
2720 | } | ||
2721 | |||
2636 | mtip_init_port(dd->port); | 2722 | mtip_init_port(dd->port); |
2637 | mtip_start_port(dd->port); | 2723 | mtip_start_port(dd->port); |
2638 | 2724 | ||
@@ -2662,6 +2748,12 @@ static int mtip_hw_init(struct driver_data *dd) | |||
2662 | mod_timer(&dd->port->cmd_timer, | 2748 | mod_timer(&dd->port->cmd_timer, |
2663 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); | 2749 | jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); |
2664 | 2750 | ||
2751 | |||
2752 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { | ||
2753 | rv = -EFAULT; | ||
2754 | goto out3; | ||
2755 | } | ||
2756 | |||
2665 | if (mtip_get_identify(dd->port, NULL) < 0) { | 2757 | if (mtip_get_identify(dd->port, NULL) < 0) { |
2666 | rv = -EFAULT; | 2758 | rv = -EFAULT; |
2667 | goto out3; | 2759 | goto out3; |
@@ -2714,9 +2806,12 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
2714 | * Send standby immediate (E0h) to the drive so that it | 2806 | * Send standby immediate (E0h) to the drive so that it |
2715 | * saves its state. | 2807 | * saves its state. |
2716 | */ | 2808 | */ |
2717 | if (atomic_read(&dd->drv_cleanup_done) != true) { | 2809 | if (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { |
2718 | 2810 | ||
2719 | mtip_standby_immediate(dd->port); | 2811 | if (test_bit(MTIP_FLAG_REBUILD_BIT, &dd->dd_flag)) |
2812 | if (mtip_standby_immediate(dd->port)) | ||
2813 | dev_warn(&dd->pdev->dev, | ||
2814 | "STANDBY IMMEDIATE failed\n"); | ||
2720 | 2815 | ||
2721 | /* de-initialize the port. */ | 2816 | /* de-initialize the port. */ |
2722 | mtip_deinit_port(dd->port); | 2817 | mtip_deinit_port(dd->port); |
@@ -2894,6 +2989,9 @@ static int mtip_block_ioctl(struct block_device *dev, | |||
2894 | if (!dd) | 2989 | if (!dd) |
2895 | return -ENOTTY; | 2990 | return -ENOTTY; |
2896 | 2991 | ||
2992 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) | ||
2993 | return -ENOTTY; | ||
2994 | |||
2897 | switch (cmd) { | 2995 | switch (cmd) { |
2898 | case BLKFLSBUF: | 2996 | case BLKFLSBUF: |
2899 | return -ENOTTY; | 2997 | return -ENOTTY; |
@@ -2929,6 +3027,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev, | |||
2929 | if (!dd) | 3027 | if (!dd) |
2930 | return -ENOTTY; | 3028 | return -ENOTTY; |
2931 | 3029 | ||
3030 | if (unlikely(test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag))) | ||
3031 | return -ENOTTY; | ||
3032 | |||
2932 | switch (cmd) { | 3033 | switch (cmd) { |
2933 | case BLKFLSBUF: | 3034 | case BLKFLSBUF: |
2934 | return -ENOTTY; | 3035 | return -ENOTTY; |
@@ -3051,6 +3152,11 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3051 | int nents = 0; | 3152 | int nents = 0; |
3052 | int tag = 0; | 3153 | int tag = 0; |
3053 | 3154 | ||
3155 | if (test_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag)) { | ||
3156 | bio_endio(bio, -ENXIO); | ||
3157 | return; | ||
3158 | } | ||
3159 | |||
3054 | if (unlikely(!bio_has_data(bio))) { | 3160 | if (unlikely(!bio_has_data(bio))) { |
3055 | blk_queue_flush(queue, 0); | 3161 | blk_queue_flush(queue, 0); |
3056 | bio_endio(bio, 0); | 3162 | bio_endio(bio, 0); |
@@ -3063,7 +3169,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3063 | 3169 | ||
3064 | if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { | 3170 | if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { |
3065 | dev_warn(&dd->pdev->dev, | 3171 | dev_warn(&dd->pdev->dev, |
3066 | "Maximum number of SGL entries exceeded"); | 3172 | "Maximum number of SGL entries exceeded\n"); |
3067 | bio_io_error(bio); | 3173 | bio_io_error(bio); |
3068 | mtip_hw_release_scatterlist(dd, tag); | 3174 | mtip_hw_release_scatterlist(dd, tag); |
3069 | return; | 3175 | return; |
@@ -3212,8 +3318,10 @@ skip_create_disk: | |||
3212 | kobject_put(kobj); | 3318 | kobject_put(kobj); |
3213 | } | 3319 | } |
3214 | 3320 | ||
3215 | if (dd->mtip_svc_handler) | 3321 | if (dd->mtip_svc_handler) { |
3322 | set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); | ||
3216 | return rv; /* service thread created for handling rebuild */ | 3323 | return rv; /* service thread created for handling rebuild */ |
3324 | } | ||
3217 | 3325 | ||
3218 | start_service_thread: | 3326 | start_service_thread: |
3219 | sprintf(thd_name, "mtip_svc_thd_%02d", index); | 3327 | sprintf(thd_name, "mtip_svc_thd_%02d", index); |
@@ -3228,6 +3336,9 @@ start_service_thread: | |||
3228 | goto kthread_run_error; | 3336 | goto kthread_run_error; |
3229 | } | 3337 | } |
3230 | 3338 | ||
3339 | if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) | ||
3340 | rv = wait_for_rebuild; | ||
3341 | |||
3231 | return rv; | 3342 | return rv; |
3232 | 3343 | ||
3233 | kthread_run_error: | 3344 | kthread_run_error: |
@@ -3274,10 +3385,12 @@ static int mtip_block_remove(struct driver_data *dd) | |||
3274 | } | 3385 | } |
3275 | 3386 | ||
3276 | /* Clean up the sysfs attributes managed by the protocol layer. */ | 3387 | /* Clean up the sysfs attributes managed by the protocol layer. */ |
3277 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); | 3388 | if (test_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag)) { |
3278 | if (kobj) { | 3389 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); |
3279 | mtip_hw_sysfs_exit(dd, kobj); | 3390 | if (kobj) { |
3280 | kobject_put(kobj); | 3391 | mtip_hw_sysfs_exit(dd, kobj); |
3392 | kobject_put(kobj); | ||
3393 | } | ||
3281 | } | 3394 | } |
3282 | 3395 | ||
3283 | /* | 3396 | /* |
@@ -3361,8 +3474,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
3361 | return -ENOMEM; | 3474 | return -ENOMEM; |
3362 | } | 3475 | } |
3363 | 3476 | ||
3364 | atomic_set(&dd->resumeflag, false); | ||
3365 | |||
3366 | /* Attach the private data to this PCI device. */ | 3477 | /* Attach the private data to this PCI device. */ |
3367 | pci_set_drvdata(pdev, dd); | 3478 | pci_set_drvdata(pdev, dd); |
3368 | 3479 | ||
@@ -3419,7 +3530,8 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
3419 | * instance number. | 3530 | * instance number. |
3420 | */ | 3531 | */ |
3421 | instance++; | 3532 | instance++; |
3422 | 3533 | if (rv != MTIP_FTL_REBUILD_MAGIC) | |
3534 | set_bit(MTIP_DD_FLAG_INIT_DONE_BIT, &dd->dd_flag); | ||
3423 | goto done; | 3535 | goto done; |
3424 | 3536 | ||
3425 | block_initialize_err: | 3537 | block_initialize_err: |
@@ -3433,9 +3545,6 @@ iomap_err: | |||
3433 | pci_set_drvdata(pdev, NULL); | 3545 | pci_set_drvdata(pdev, NULL); |
3434 | return rv; | 3546 | return rv; |
3435 | done: | 3547 | done: |
3436 | /* Set the atomic variable as 0 */ | ||
3437 | atomic_set(&dd->drv_cleanup_done, false); | ||
3438 | |||
3439 | return rv; | 3548 | return rv; |
3440 | } | 3549 | } |
3441 | 3550 | ||
@@ -3451,8 +3560,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
3451 | struct driver_data *dd = pci_get_drvdata(pdev); | 3560 | struct driver_data *dd = pci_get_drvdata(pdev); |
3452 | int counter = 0; | 3561 | int counter = 0; |
3453 | 3562 | ||
3563 | set_bit(MTIP_DD_FLAG_REMOVE_PENDING_BIT, &dd->dd_flag); | ||
3564 | |||
3454 | if (mtip_check_surprise_removal(pdev)) { | 3565 | if (mtip_check_surprise_removal(pdev)) { |
3455 | while (atomic_read(&dd->drv_cleanup_done) == false) { | 3566 | while (!test_bit(MTIP_DD_FLAG_CLEANUP_BIT, &dd->dd_flag)) { |
3456 | counter++; | 3567 | counter++; |
3457 | msleep(20); | 3568 | msleep(20); |
3458 | if (counter == 10) { | 3569 | if (counter == 10) { |
@@ -3490,7 +3601,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) | |||
3490 | return -EFAULT; | 3601 | return -EFAULT; |
3491 | } | 3602 | } |
3492 | 3603 | ||
3493 | atomic_set(&dd->resumeflag, true); | 3604 | set_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); |
3494 | 3605 | ||
3495 | /* Disable ports & interrupts then send standby immediate */ | 3606 | /* Disable ports & interrupts then send standby immediate */ |
3496 | rv = mtip_block_suspend(dd); | 3607 | rv = mtip_block_suspend(dd); |
@@ -3556,7 +3667,7 @@ static int mtip_pci_resume(struct pci_dev *pdev) | |||
3556 | dev_err(&pdev->dev, "Unable to resume\n"); | 3667 | dev_err(&pdev->dev, "Unable to resume\n"); |
3557 | 3668 | ||
3558 | err: | 3669 | err: |
3559 | atomic_set(&dd->resumeflag, false); | 3670 | clear_bit(MTIP_DD_FLAG_RESUME_BIT, &dd->dd_flag); |
3560 | 3671 | ||
3561 | return rv; | 3672 | return rv; |
3562 | } | 3673 | } |