diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 314 |
1 files changed, 295 insertions, 19 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index d4b003a618a1..9ec50729d535 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -79,6 +79,9 @@ static u8 transport_cb_idx = -1; | |||
79 | static u8 config_cb_idx = -1; | 79 | static u8 config_cb_idx = -1; |
80 | static int mpt_ids; | 80 | static int mpt_ids; |
81 | 81 | ||
82 | static u8 tm_tr_cb_idx = -1 ; | ||
83 | static u8 tm_sas_control_cb_idx = -1; | ||
84 | |||
82 | /* command line options */ | 85 | /* command line options */ |
83 | static u32 logging_level; | 86 | static u32 logging_level; |
84 | MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " | 87 | MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " |
@@ -1641,17 +1644,18 @@ _scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code) | |||
1641 | * | 1644 | * |
1642 | * The callback handler when using scsih_issue_tm. | 1645 | * The callback handler when using scsih_issue_tm. |
1643 | * | 1646 | * |
1644 | * Return nothing. | 1647 | * Return 1 meaning mf should be freed from _base_interrupt |
1648 | * 0 means the mf is freed from this function. | ||
1645 | */ | 1649 | */ |
1646 | static void | 1650 | static u8 |
1647 | _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | 1651 | _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) |
1648 | { | 1652 | { |
1649 | MPI2DefaultReply_t *mpi_reply; | 1653 | MPI2DefaultReply_t *mpi_reply; |
1650 | 1654 | ||
1651 | if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) | 1655 | if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) |
1652 | return; | 1656 | return 1; |
1653 | if (ioc->tm_cmds.smid != smid) | 1657 | if (ioc->tm_cmds.smid != smid) |
1654 | return; | 1658 | return 1; |
1655 | ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; | 1659 | ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; |
1656 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 1660 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
1657 | if (mpi_reply) { | 1661 | if (mpi_reply) { |
@@ -1660,6 +1664,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
1660 | } | 1664 | } |
1661 | ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; | 1665 | ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; |
1662 | complete(&ioc->tm_cmds.done); | 1666 | complete(&ioc->tm_cmds.done); |
1667 | return 1; | ||
1663 | } | 1668 | } |
1664 | 1669 | ||
1665 | /** | 1670 | /** |
@@ -2312,6 +2317,231 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, | |||
2312 | } | 2317 | } |
2313 | 2318 | ||
2314 | /** | 2319 | /** |
2320 | * _scsih_tm_tr_send - send task management request | ||
2321 | * @ioc: per adapter object | ||
2322 | * @handle: device handle | ||
2323 | * Context: interrupt time. | ||
2324 | * | ||
2325 | * This code is to initiate the device removal handshake protocal | ||
2326 | * with controller firmware. This function will issue target reset | ||
2327 | * using high priority request queue. It will send a sas iounit | ||
2328 | * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. | ||
2329 | * | ||
2330 | * This is designed to send muliple task management request at the same | ||
2331 | * time to the fifo. If the fifo is full, we will append the request, | ||
2332 | * and process it in a future completion. | ||
2333 | */ | ||
2334 | static void | ||
2335 | _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
2336 | { | ||
2337 | Mpi2SCSITaskManagementRequest_t *mpi_request; | ||
2338 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
2339 | u16 smid; | ||
2340 | struct _sas_device *sas_device; | ||
2341 | unsigned long flags; | ||
2342 | struct _tr_list *delayed_tr; | ||
2343 | |||
2344 | if (ioc->shost_recovery) { | ||
2345 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
2346 | __func__, ioc->name); | ||
2347 | return; | ||
2348 | } | ||
2349 | |||
2350 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
2351 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
2352 | if (!sas_device) { | ||
2353 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2354 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
2355 | ioc->name, __func__); | ||
2356 | return; | ||
2357 | } | ||
2358 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2359 | |||
2360 | /* skip is hidden raid component */ | ||
2361 | if (sas_device->hidden_raid_component) | ||
2362 | return; | ||
2363 | |||
2364 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); | ||
2365 | if (!smid) { | ||
2366 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); | ||
2367 | if (!delayed_tr) | ||
2368 | return; | ||
2369 | INIT_LIST_HEAD(&delayed_tr->list); | ||
2370 | delayed_tr->handle = handle; | ||
2371 | delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; | ||
2372 | list_add_tail(&delayed_tr->list, | ||
2373 | &ioc->delayed_tr_list); | ||
2374 | if (sas_device->starget) | ||
2375 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
2376 | sas_device->starget, "DELAYED:tr:handle(0x%04x), " | ||
2377 | "(open)\n", sas_device->handle)); | ||
2378 | return; | ||
2379 | } | ||
2380 | |||
2381 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
2382 | sas_target_priv_data = sas_device->starget->hostdata; | ||
2383 | sas_target_priv_data->tm_busy = 1; | ||
2384 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
2385 | "tr:handle(0x%04x), (open)\n", sas_device->handle)); | ||
2386 | } | ||
2387 | |||
2388 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | ||
2389 | memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); | ||
2390 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; | ||
2391 | mpi_request->DevHandle = cpu_to_le16(handle); | ||
2392 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | ||
2393 | sas_device->state |= MPTSAS_STATE_TR_SEND; | ||
2394 | sas_device->state |= MPT2SAS_REQ_SAS_CNTRL; | ||
2395 | mpt2sas_base_put_smid_hi_priority(ioc, smid); | ||
2396 | } | ||
2397 | |||
2398 | |||
2399 | |||
2400 | /** | ||
2401 | * _scsih_sas_control_complete - completion routine | ||
2402 | * @ioc: per adapter object | ||
2403 | * @smid: system request message index | ||
2404 | * @msix_index: MSIX table index supplied by the OS | ||
2405 | * @reply: reply message frame(lower 32bit addr) | ||
2406 | * Context: interrupt time. | ||
2407 | * | ||
2408 | * This is the sas iounit controll completion routine. | ||
2409 | * This code is part of the code to initiate the device removal | ||
2410 | * handshake protocal with controller firmware. | ||
2411 | * | ||
2412 | * Return 1 meaning mf should be freed from _base_interrupt | ||
2413 | * 0 means the mf is freed from this function. | ||
2414 | */ | ||
2415 | static u8 | ||
2416 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | ||
2417 | u8 msix_index, u32 reply) | ||
2418 | { | ||
2419 | unsigned long flags; | ||
2420 | u16 handle; | ||
2421 | struct _sas_device *sas_device; | ||
2422 | Mpi2SasIoUnitControlReply_t *mpi_reply = | ||
2423 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
2424 | |||
2425 | handle = le16_to_cpu(mpi_reply->DevHandle); | ||
2426 | |||
2427 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
2428 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
2429 | if (!sas_device) { | ||
2430 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2431 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
2432 | ioc->name, __func__); | ||
2433 | return 1; | ||
2434 | } | ||
2435 | sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE; | ||
2436 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2437 | |||
2438 | if (sas_device->starget) | ||
2439 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
2440 | "sc_complete:handle(0x%04x), " | ||
2441 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
2442 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
2443 | le32_to_cpu(mpi_reply->IOCLogInfo))); | ||
2444 | return 1; | ||
2445 | } | ||
2446 | |||
2447 | /** | ||
2448 | * _scsih_tm_tr_complete - | ||
2449 | * @ioc: per adapter object | ||
2450 | * @smid: system request message index | ||
2451 | * @msix_index: MSIX table index supplied by the OS | ||
2452 | * @reply: reply message frame(lower 32bit addr) | ||
2453 | * Context: interrupt time. | ||
2454 | * | ||
2455 | * This is the target reset completion routine. | ||
2456 | * This code is part of the code to initiate the device removal | ||
2457 | * handshake protocal with controller firmware. | ||
2458 | * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE) | ||
2459 | * | ||
2460 | * Return 1 meaning mf should be freed from _base_interrupt | ||
2461 | * 0 means the mf is freed from this function. | ||
2462 | */ | ||
2463 | static u8 | ||
2464 | _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | ||
2465 | u32 reply) | ||
2466 | { | ||
2467 | unsigned long flags; | ||
2468 | u16 handle; | ||
2469 | struct _sas_device *sas_device; | ||
2470 | Mpi2SCSITaskManagementReply_t *mpi_reply = | ||
2471 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
2472 | Mpi2SasIoUnitControlRequest_t *mpi_request; | ||
2473 | u16 smid_sas_ctrl; | ||
2474 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
2475 | struct _tr_list *delayed_tr; | ||
2476 | u8 rc; | ||
2477 | |||
2478 | handle = le16_to_cpu(mpi_reply->DevHandle); | ||
2479 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
2480 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
2481 | if (!sas_device) { | ||
2482 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2483 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
2484 | ioc->name, __func__); | ||
2485 | return 1; | ||
2486 | } | ||
2487 | sas_device->state |= MPTSAS_STATE_TR_COMPLETE; | ||
2488 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2489 | |||
2490 | if (sas_device->starget) | ||
2491 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
2492 | "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " | ||
2493 | "loginfo(0x%08x), completed(%d)\n", | ||
2494 | sas_device->handle, (sas_device->state & | ||
2495 | MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", | ||
2496 | le16_to_cpu(mpi_reply->IOCStatus), | ||
2497 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
2498 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
2499 | |||
2500 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
2501 | sas_target_priv_data = sas_device->starget->hostdata; | ||
2502 | sas_target_priv_data->tm_busy = 0; | ||
2503 | } | ||
2504 | |||
2505 | if (!list_empty(&ioc->delayed_tr_list)) { | ||
2506 | delayed_tr = list_entry(ioc->delayed_tr_list.next, | ||
2507 | struct _tr_list, list); | ||
2508 | mpt2sas_base_free_smid(ioc, smid); | ||
2509 | if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL) | ||
2510 | _scsih_tm_tr_send(ioc, delayed_tr->handle); | ||
2511 | list_del(&delayed_tr->list); | ||
2512 | kfree(delayed_tr); | ||
2513 | rc = 0; /* tells base_interrupt not to free mf */ | ||
2514 | } else | ||
2515 | rc = 1; | ||
2516 | |||
2517 | |||
2518 | if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL)) | ||
2519 | return rc; | ||
2520 | |||
2521 | if (ioc->shost_recovery) { | ||
2522 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
2523 | __func__, ioc->name); | ||
2524 | return rc; | ||
2525 | } | ||
2526 | |||
2527 | smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); | ||
2528 | if (!smid_sas_ctrl) { | ||
2529 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | ||
2530 | ioc->name, __func__); | ||
2531 | return rc; | ||
2532 | } | ||
2533 | |||
2534 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); | ||
2535 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); | ||
2536 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | ||
2537 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | ||
2538 | mpi_request->DevHandle = mpi_reply->DevHandle; | ||
2539 | sas_device->state |= MPTSAS_STATE_CNTRL_SEND; | ||
2540 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); | ||
2541 | return rc; | ||
2542 | } | ||
2543 | |||
2544 | /** | ||
2315 | * _scsih_check_topo_delete_events - sanity check on topo events | 2545 | * _scsih_check_topo_delete_events - sanity check on topo events |
2316 | * @ioc: per adapter object | 2546 | * @ioc: per adapter object |
2317 | * @event_data: the event data payload | 2547 | * @event_data: the event data payload |
@@ -2333,6 +2563,21 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
2333 | u16 expander_handle; | 2563 | u16 expander_handle; |
2334 | struct _sas_node *sas_expander; | 2564 | struct _sas_node *sas_expander; |
2335 | unsigned long flags; | 2565 | unsigned long flags; |
2566 | int i, reason_code; | ||
2567 | u16 handle; | ||
2568 | |||
2569 | for (i = 0 ; i < event_data->NumEntries; i++) { | ||
2570 | if (event_data->PHY[i].PhyStatus & | ||
2571 | MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) | ||
2572 | continue; | ||
2573 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | ||
2574 | if (!handle) | ||
2575 | continue; | ||
2576 | reason_code = event_data->PHY[i].PhyStatus & | ||
2577 | MPI2_EVENT_SAS_TOPO_RC_MASK; | ||
2578 | if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING) | ||
2579 | _scsih_tm_tr_send(ioc, handle); | ||
2580 | } | ||
2336 | 2581 | ||
2337 | expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); | 2582 | expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); |
2338 | if (expander_handle < ioc->sas_hba.num_phys) { | 2583 | if (expander_handle < ioc->sas_hba.num_phys) { |
@@ -2915,11 +3160,12 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
2915 | * @msix_index: MSIX table index supplied by the OS | 3160 | * @msix_index: MSIX table index supplied by the OS |
2916 | * @reply: reply message frame(lower 32bit addr) | 3161 | * @reply: reply message frame(lower 32bit addr) |
2917 | * | 3162 | * |
2918 | * Callback handler when using scsih_qcmd. | 3163 | * Callback handler when using _scsih_qcmd. |
2919 | * | 3164 | * |
2920 | * Return nothing. | 3165 | * Return 1 meaning mf should be freed from _base_interrupt |
3166 | * 0 means the mf is freed from this function. | ||
2921 | */ | 3167 | */ |
2922 | static void | 3168 | static u8 |
2923 | _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | 3169 | _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) |
2924 | { | 3170 | { |
2925 | Mpi2SCSIIORequest_t *mpi_request; | 3171 | Mpi2SCSIIORequest_t *mpi_request; |
@@ -2936,7 +3182,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
2936 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3182 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
2937 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3183 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
2938 | if (scmd == NULL) | 3184 | if (scmd == NULL) |
2939 | return; | 3185 | return 1; |
2940 | 3186 | ||
2941 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 3187 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
2942 | 3188 | ||
@@ -3092,6 +3338,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3092 | out: | 3338 | out: |
3093 | scsi_dma_unmap(scmd); | 3339 | scsi_dma_unmap(scmd); |
3094 | scmd->scsi_done(scmd); | 3340 | scmd->scsi_done(scmd); |
3341 | return 1; | ||
3095 | } | 3342 | } |
3096 | 3343 | ||
3097 | /** | 3344 | /** |
@@ -3623,6 +3870,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3623 | if (ioc->remove_host) | 3870 | if (ioc->remove_host) |
3624 | goto out; | 3871 | goto out; |
3625 | 3872 | ||
3873 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { | ||
3874 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | ||
3875 | "target_reset handle(0x%04x)\n", ioc->name, handle)); | ||
3876 | goto skip_tr; | ||
3877 | } | ||
3878 | |||
3626 | /* Target Reset to flush out all the outstanding IO */ | 3879 | /* Target Reset to flush out all the outstanding IO */ |
3627 | device_handle = (sas_device->hidden_raid_component) ? | 3880 | device_handle = (sas_device->hidden_raid_component) ? |
3628 | sas_device->volume_handle : handle; | 3881 | sas_device->volume_handle : handle; |
@@ -3639,6 +3892,13 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3639 | if (ioc->shost_recovery) | 3892 | if (ioc->shost_recovery) |
3640 | goto out; | 3893 | goto out; |
3641 | } | 3894 | } |
3895 | skip_tr: | ||
3896 | |||
3897 | if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) { | ||
3898 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | ||
3899 | "sas_cntrl handle(0x%04x)\n", ioc->name, handle)); | ||
3900 | goto out; | ||
3901 | } | ||
3642 | 3902 | ||
3643 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ | 3903 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ |
3644 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" | 3904 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" |
@@ -4829,6 +5089,10 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
4829 | if (sas_device->sas_address == sas_address && | 5089 | if (sas_device->sas_address == sas_address && |
4830 | sas_device->slot == slot && sas_device->starget) { | 5090 | sas_device->slot == slot && sas_device->starget) { |
4831 | sas_device->responding = 1; | 5091 | sas_device->responding = 1; |
5092 | sas_device->state = 0; | ||
5093 | starget = sas_device->starget; | ||
5094 | sas_target_priv_data = starget->hostdata; | ||
5095 | sas_target_priv_data->tm_busy = 0; | ||
4832 | starget_printk(KERN_INFO, sas_device->starget, | 5096 | starget_printk(KERN_INFO, sas_device->starget, |
4833 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " | 5097 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " |
4834 | "logical id(0x%016llx), slot(%d)\n", handle, | 5098 | "logical id(0x%016llx), slot(%d)\n", handle, |
@@ -4841,8 +5105,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
4841 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 5105 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
4842 | sas_device->handle); | 5106 | sas_device->handle); |
4843 | sas_device->handle = handle; | 5107 | sas_device->handle = handle; |
4844 | starget = sas_device->starget; | ||
4845 | sas_target_priv_data = starget->hostdata; | ||
4846 | sas_target_priv_data->handle = handle; | 5108 | sas_target_priv_data->handle = handle; |
4847 | goto out; | 5109 | goto out; |
4848 | } | 5110 | } |
@@ -5235,9 +5497,10 @@ _firmware_event_work(struct work_struct *work) | |||
5235 | * This function merely adds a new work task into ioc->firmware_event_thread. | 5497 | * This function merely adds a new work task into ioc->firmware_event_thread. |
5236 | * The tasks are worked from _firmware_event_work in user context. | 5498 | * The tasks are worked from _firmware_event_work in user context. |
5237 | * | 5499 | * |
5238 | * Return nothing. | 5500 | * Return 1 meaning mf should be freed from _base_interrupt |
5501 | * 0 means the mf is freed from this function. | ||
5239 | */ | 5502 | */ |
5240 | void | 5503 | u8 |
5241 | mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | 5504 | mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, |
5242 | u32 reply) | 5505 | u32 reply) |
5243 | { | 5506 | { |
@@ -5250,11 +5513,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
5250 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 5513 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
5251 | if (ioc->fw_events_off || ioc->remove_host) { | 5514 | if (ioc->fw_events_off || ioc->remove_host) { |
5252 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 5515 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
5253 | return; | 5516 | return 1; |
5254 | } | 5517 | } |
5255 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 5518 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
5256 | 5519 | ||
5257 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 5520 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
5258 | event = le16_to_cpu(mpi_reply->Event); | 5521 | event = le16_to_cpu(mpi_reply->Event); |
5259 | 5522 | ||
5260 | switch (event) { | 5523 | switch (event) { |
@@ -5268,7 +5531,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
5268 | if (baen_data->Primitive != | 5531 | if (baen_data->Primitive != |
5269 | MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || | 5532 | MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || |
5270 | ioc->broadcast_aen_busy) | 5533 | ioc->broadcast_aen_busy) |
5271 | return; | 5534 | return 1; |
5272 | ioc->broadcast_aen_busy = 1; | 5535 | ioc->broadcast_aen_busy = 1; |
5273 | break; | 5536 | break; |
5274 | } | 5537 | } |
@@ -5290,14 +5553,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
5290 | break; | 5553 | break; |
5291 | 5554 | ||
5292 | default: /* ignore the rest */ | 5555 | default: /* ignore the rest */ |
5293 | return; | 5556 | return 1; |
5294 | } | 5557 | } |
5295 | 5558 | ||
5296 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 5559 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); |
5297 | if (!fw_event) { | 5560 | if (!fw_event) { |
5298 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 5561 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
5299 | ioc->name, __FILE__, __LINE__, __func__); | 5562 | ioc->name, __FILE__, __LINE__, __func__); |
5300 | return; | 5563 | return 1; |
5301 | } | 5564 | } |
5302 | fw_event->event_data = | 5565 | fw_event->event_data = |
5303 | kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); | 5566 | kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); |
@@ -5305,7 +5568,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
5305 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 5568 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
5306 | ioc->name, __FILE__, __LINE__, __func__); | 5569 | ioc->name, __FILE__, __LINE__, __func__); |
5307 | kfree(fw_event); | 5570 | kfree(fw_event); |
5308 | return; | 5571 | return 1; |
5309 | } | 5572 | } |
5310 | 5573 | ||
5311 | memcpy(fw_event->event_data, mpi_reply->EventData, | 5574 | memcpy(fw_event->event_data, mpi_reply->EventData, |
@@ -5315,6 +5578,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
5315 | fw_event->VP_ID = mpi_reply->VP_ID; | 5578 | fw_event->VP_ID = mpi_reply->VP_ID; |
5316 | fw_event->event = event; | 5579 | fw_event->event = event; |
5317 | _scsih_fw_event_add(ioc, fw_event); | 5580 | _scsih_fw_event_add(ioc, fw_event); |
5581 | return 1; | ||
5318 | } | 5582 | } |
5319 | 5583 | ||
5320 | /* shost template */ | 5584 | /* shost template */ |
@@ -5574,7 +5838,7 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc) | |||
5574 | } | 5838 | } |
5575 | 5839 | ||
5576 | /** | 5840 | /** |
5577 | * _scsih_probe_sas - reporting raid volumes to sas transport | 5841 | * _scsih_probe_sas - reporting sas devices to sas transport |
5578 | * @ioc: per adapter object | 5842 | * @ioc: per adapter object |
5579 | * | 5843 | * |
5580 | * Called during initial loading of the driver. | 5844 | * Called during initial loading of the driver. |
@@ -5671,6 +5935,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
5671 | ioc->base_cb_idx = base_cb_idx; | 5935 | ioc->base_cb_idx = base_cb_idx; |
5672 | ioc->transport_cb_idx = transport_cb_idx; | 5936 | ioc->transport_cb_idx = transport_cb_idx; |
5673 | ioc->config_cb_idx = config_cb_idx; | 5937 | ioc->config_cb_idx = config_cb_idx; |
5938 | ioc->tm_tr_cb_idx = tm_tr_cb_idx; | ||
5939 | ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; | ||
5674 | ioc->logging_level = logging_level; | 5940 | ioc->logging_level = logging_level; |
5675 | /* misc semaphores and spin locks */ | 5941 | /* misc semaphores and spin locks */ |
5676 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); | 5942 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); |
@@ -5686,6 +5952,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
5686 | INIT_LIST_HEAD(&ioc->fw_event_list); | 5952 | INIT_LIST_HEAD(&ioc->fw_event_list); |
5687 | INIT_LIST_HEAD(&ioc->raid_device_list); | 5953 | INIT_LIST_HEAD(&ioc->raid_device_list); |
5688 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); | 5954 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); |
5955 | INIT_LIST_HEAD(&ioc->delayed_tr_list); | ||
5689 | 5956 | ||
5690 | /* init shost parameters */ | 5957 | /* init shost parameters */ |
5691 | shost->max_cmd_len = 16; | 5958 | shost->max_cmd_len = 16; |
@@ -5702,6 +5969,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
5702 | 5969 | ||
5703 | scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION | 5970 | scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION |
5704 | | SHOST_DIF_TYPE3_PROTECTION); | 5971 | | SHOST_DIF_TYPE3_PROTECTION); |
5972 | scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); | ||
5705 | 5973 | ||
5706 | /* event thread */ | 5974 | /* event thread */ |
5707 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), | 5975 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), |
@@ -5851,6 +6119,11 @@ _scsih_init(void) | |||
5851 | /* ctl module callback handler */ | 6119 | /* ctl module callback handler */ |
5852 | ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); | 6120 | ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); |
5853 | 6121 | ||
6122 | tm_tr_cb_idx = mpt2sas_base_register_callback_handler( | ||
6123 | _scsih_tm_tr_complete); | ||
6124 | tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( | ||
6125 | _scsih_sas_control_complete); | ||
6126 | |||
5854 | mpt2sas_ctl_init(); | 6127 | mpt2sas_ctl_init(); |
5855 | 6128 | ||
5856 | error = pci_register_driver(&scsih_driver); | 6129 | error = pci_register_driver(&scsih_driver); |
@@ -5881,6 +6154,9 @@ _scsih_exit(void) | |||
5881 | mpt2sas_base_release_callback_handler(config_cb_idx); | 6154 | mpt2sas_base_release_callback_handler(config_cb_idx); |
5882 | mpt2sas_base_release_callback_handler(ctl_cb_idx); | 6155 | mpt2sas_base_release_callback_handler(ctl_cb_idx); |
5883 | 6156 | ||
6157 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); | ||
6158 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); | ||
6159 | |||
5884 | mpt2sas_ctl_exit(); | 6160 | mpt2sas_ctl_exit(); |
5885 | } | 6161 | } |
5886 | 6162 | ||