1 /*
2 * mr_sas_tbolt.c: source for mr_sas driver for New Generation.
3 * i.e. Thunderbolt and Invader
4 *
5 * Solaris MegaRAID device driver for SAS2.0 controllers
6 * Copyright (c) 2008-2012, LSI Logic Corporation.
7 * All rights reserved.
8 *
9 * Version:
10 * Author:
11 * Swaminathan K S
12 * Arun Chandrashekhar
13 * Manju R
14 * Rasheed
15 * Shakeel Bukhari
16 */
17
18 /*
19 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
20 * Copyright 2015, 2017 Citrus IT Limited. All rights reserved.
21 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
22 */
23
24
25 #include <sys/types.h>
26 #include <sys/file.h>
27 #include <sys/atomic.h>
28 #include <sys/scsi/scsi.h>
29 #include <sys/byteorder.h>
30 #include <sys/sdt.h>
31 #include "ld_pd_map.h"
32 #include "mr_sas.h"
33 #include "fusion.h"
34
35 /*
36 * FMA header files
37 */
38 #include <sys/ddifm.h>
39 #include <sys/fm/protocol.h>
1091 fail_ioc_init:
1092
1093 (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
1094
1095 return (DDI_FAILURE);
1096 }
1097
1098 int
1099 wait_for_outstanding_poll_io(struct mrsas_instance *instance)
1100 {
1101 int i;
1102 uint32_t wait_time = dump_io_wait_time;
1103 for (i = 0; i < wait_time; i++) {
1104 /*
1105 * Check For Outstanding poll Commands
1106 * except ldsync command and aen command
1107 */
1108 if (instance->fw_outstanding <= 2) {
1109 break;
1110 }
1111 drv_usecwait(10*MILLISEC);
1112 /* complete commands from reply queue */
1113 (void) mr_sas_tbolt_process_outstanding_cmd(instance);
1114 }
1115 if (instance->fw_outstanding > 2) {
1116 return (1);
1117 }
1118 return (0);
1119 }
1120 /*
1121 * scsi_pkt handling
1122 *
1123 * Visible to the external world via the transport structure.
1124 */
1125
1126 int
1127 mrsas_tbolt_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
1128 {
1129 struct mrsas_instance *instance = ADDR2MR(ap);
1130 struct scsa_cmd *acmd = PKT2CMD(pkt);
1131 struct mrsas_cmd *cmd = NULL;
2366 STATE_SENT_CMD | STATE_XFERRED_DATA | STATE_GOT_STATUS;
2367
2368 con_log(CL_ANN, (CE_CONT, " CDB[0] = %x completed for %s: "
2369 "size %lx SMID %x cmd_status %x", pkt->pkt_cdbp[0],
2370 ((acmd->islogical) ? "LD" : "PD"),
2371 acmd->cmd_dmacount, cmd->SMID, status));
2372
2373 if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) {
2374 struct scsi_inquiry *inq;
2375
2376 if (acmd->cmd_dmacount != 0) {
2377 bp_mapin(acmd->cmd_buf);
2378 inq = (struct scsi_inquiry *)
2379 acmd->cmd_buf->b_un.b_addr;
2380
2381 /* don't expose physical drives to OS */
2382 if (acmd->islogical &&
2383 (status == MFI_STAT_OK)) {
2384 display_scsi_inquiry((caddr_t)inq);
2385 } else if ((status == MFI_STAT_OK) &&
2386 inq->inq_dtype == DTYPE_DIRECT) {
2387 display_scsi_inquiry((caddr_t)inq);
2388 } else {
2389 /* for physical disk */
2390 status = MFI_STAT_DEVICE_NOT_FOUND;
2391 }
2392 }
2393 }
2394
2395 switch (status) {
2396 case MFI_STAT_OK:
2397 pkt->pkt_scbp[0] = STATUS_GOOD;
2398 break;
2399 case MFI_STAT_LD_CC_IN_PROGRESS:
2400 case MFI_STAT_LD_RECON_IN_PROGRESS:
2401 pkt->pkt_scbp[0] = STATUS_GOOD;
2402 break;
2403 case MFI_STAT_LD_INIT_IN_PROGRESS:
2404 pkt->pkt_reason = CMD_TRAN_ERR;
2405 break;
2406 case MFI_STAT_SCSI_IO_FAILED:
3542 if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
3543 if (ldip) {
3544 *ldip = child;
3545 }
3546 if (instance->mr_tbolt_pd_list[tgt].flag != MRDRV_TGT_VALID) {
3547 rval = mrsas_service_evt(instance, tgt, 1,
3548 MRSAS_EVT_UNCONFIG_TGT, NULL);
3549 con_log(CL_ANN1, (CE_WARN,
3550 "mr_sas:DELETING STALE ENTRY rval = %d "
3551 "tgt id = %d", rval, tgt));
3552 return (NDI_FAILURE);
3553 }
3554 return (NDI_SUCCESS);
3555 }
3556
3557 pds = (struct mrsas_tbolt_pd_info *)
3558 kmem_zalloc(sizeof (struct mrsas_tbolt_pd_info), KM_SLEEP);
3559 mrsas_tbolt_get_pd_info(instance, pds, tgt);
3560 dtype = pds->scsiDevType;
3561
3562 /* Check for Disk */
3563 if ((dtype == DTYPE_DIRECT)) {
3564 if ((dtype == DTYPE_DIRECT) &&
3565 (LE_16(pds->fwState) != PD_SYSTEM)) {
3566 kmem_free(pds, sizeof (struct mrsas_tbolt_pd_info));
3567 return (NDI_FAILURE);
3568 }
3569 sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
3570 sd->sd_address.a_hba_tran = instance->tran;
3571 sd->sd_address.a_target = (uint16_t)tgt;
3572 sd->sd_address.a_lun = (uint8_t)lun;
3573
3574 if (scsi_hba_probe(sd, NULL) == SCSIPROBE_EXISTS) {
3575 rval = mrsas_config_scsi_device(instance, sd, ldip);
3576 dev_err(instance->dip, CE_CONT,
3577 "?Phys. device found: tgt %d dtype %d: %s\n",
3578 tgt, dtype, sd->sd_inq->inq_vid);
3579 } else {
3580 rval = NDI_FAILURE;
3581 con_log(CL_DLEVEL1, (CE_NOTE, "Phys. device Not found "
3582 "scsi_hba_probe Failed: tgt %d dtype %d: %s",
3583 tgt, dtype, sd->sd_inq->inq_vid));
|
1 /*
2 * mr_sas_tbolt.c: source for mr_sas driver for New Generation.
3 * i.e. Thunderbolt and Invader
4 *
5 * Solaris MegaRAID device driver for SAS2.0 controllers
6 * Copyright (c) 2008-2012, LSI Logic Corporation.
7 * All rights reserved.
8 *
9 * Version:
10 * Author:
11 * Swaminathan K S
12 * Arun Chandrashekhar
13 * Manju R
14 * Rasheed
15 * Shakeel Bukhari
16 */
17
18 /*
19 * Copyright 2018 Nexenta Systems, Inc.
20 * Copyright 2015, 2017 Citrus IT Limited. All rights reserved.
21 * Copyright 2015 Garrett D'Amore <garrett@damore.org>
22 */
23
24
25 #include <sys/types.h>
26 #include <sys/file.h>
27 #include <sys/atomic.h>
28 #include <sys/scsi/scsi.h>
29 #include <sys/byteorder.h>
30 #include <sys/sdt.h>
31 #include "ld_pd_map.h"
32 #include "mr_sas.h"
33 #include "fusion.h"
34
35 /*
36 * FMA header files
37 */
38 #include <sys/ddifm.h>
39 #include <sys/fm/protocol.h>
1091 fail_ioc_init:
1092
1093 (void) mrsas_free_dma_obj(instance, instance->drv_ver_dma_obj);
1094
1095 return (DDI_FAILURE);
1096 }
1097
1098 int
1099 wait_for_outstanding_poll_io(struct mrsas_instance *instance)
1100 {
1101 int i;
1102 uint32_t wait_time = dump_io_wait_time;
1103 for (i = 0; i < wait_time; i++) {
1104 /*
1105 * Check For Outstanding poll Commands
1106 * except ldsync command and aen command
1107 */
1108 if (instance->fw_outstanding <= 2) {
1109 break;
1110 }
1111 drv_usecwait(MILLISEC);
1112 /* complete commands from reply queue */
1113 (void) mr_sas_tbolt_process_outstanding_cmd(instance);
1114 }
1115 if (instance->fw_outstanding > 2) {
1116 return (1);
1117 }
1118 return (0);
1119 }
1120 /*
1121 * scsi_pkt handling
1122 *
1123 * Visible to the external world via the transport structure.
1124 */
1125
1126 int
1127 mrsas_tbolt_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
1128 {
1129 struct mrsas_instance *instance = ADDR2MR(ap);
1130 struct scsa_cmd *acmd = PKT2CMD(pkt);
1131 struct mrsas_cmd *cmd = NULL;
2366 STATE_SENT_CMD | STATE_XFERRED_DATA | STATE_GOT_STATUS;
2367
2368 con_log(CL_ANN, (CE_CONT, " CDB[0] = %x completed for %s: "
2369 "size %lx SMID %x cmd_status %x", pkt->pkt_cdbp[0],
2370 ((acmd->islogical) ? "LD" : "PD"),
2371 acmd->cmd_dmacount, cmd->SMID, status));
2372
2373 if (pkt->pkt_cdbp[0] == SCMD_INQUIRY) {
2374 struct scsi_inquiry *inq;
2375
2376 if (acmd->cmd_dmacount != 0) {
2377 bp_mapin(acmd->cmd_buf);
2378 inq = (struct scsi_inquiry *)
2379 acmd->cmd_buf->b_un.b_addr;
2380
2381 /* don't expose physical drives to OS */
2382 if (acmd->islogical &&
2383 (status == MFI_STAT_OK)) {
2384 display_scsi_inquiry((caddr_t)inq);
2385 } else if ((status == MFI_STAT_OK) &&
2386 (inq->inq_dtype == DTYPE_DIRECT ||
2387 inq->inq_dtype == DTYPE_ESI)) {
2388 display_scsi_inquiry((caddr_t)inq);
2389 } else {
2390 /* for physical disk */
2391 status = MFI_STAT_DEVICE_NOT_FOUND;
2392 }
2393 }
2394 }
2395
2396 switch (status) {
2397 case MFI_STAT_OK:
2398 pkt->pkt_scbp[0] = STATUS_GOOD;
2399 break;
2400 case MFI_STAT_LD_CC_IN_PROGRESS:
2401 case MFI_STAT_LD_RECON_IN_PROGRESS:
2402 pkt->pkt_scbp[0] = STATUS_GOOD;
2403 break;
2404 case MFI_STAT_LD_INIT_IN_PROGRESS:
2405 pkt->pkt_reason = CMD_TRAN_ERR;
2406 break;
2407 case MFI_STAT_SCSI_IO_FAILED:
3543 if ((child = mrsas_find_child(instance, tgt, lun)) != NULL) {
3544 if (ldip) {
3545 *ldip = child;
3546 }
3547 if (instance->mr_tbolt_pd_list[tgt].flag != MRDRV_TGT_VALID) {
3548 rval = mrsas_service_evt(instance, tgt, 1,
3549 MRSAS_EVT_UNCONFIG_TGT, NULL);
3550 con_log(CL_ANN1, (CE_WARN,
3551 "mr_sas:DELETING STALE ENTRY rval = %d "
3552 "tgt id = %d", rval, tgt));
3553 return (NDI_FAILURE);
3554 }
3555 return (NDI_SUCCESS);
3556 }
3557
3558 pds = (struct mrsas_tbolt_pd_info *)
3559 kmem_zalloc(sizeof (struct mrsas_tbolt_pd_info), KM_SLEEP);
3560 mrsas_tbolt_get_pd_info(instance, pds, tgt);
3561 dtype = pds->scsiDevType;
3562
3563 /* Check for disk/enclosure */
3564 if (dtype == DTYPE_DIRECT || dtype == DTYPE_ESI) {
3565 if ((dtype == DTYPE_DIRECT) &&
3566 (LE_16(pds->fwState) != PD_SYSTEM)) {
3567 kmem_free(pds, sizeof (struct mrsas_tbolt_pd_info));
3568 return (NDI_FAILURE);
3569 }
3570 sd = kmem_zalloc(sizeof (struct scsi_device), KM_SLEEP);
3571 sd->sd_address.a_hba_tran = instance->tran;
3572 sd->sd_address.a_target = (uint16_t)tgt;
3573 sd->sd_address.a_lun = (uint8_t)lun;
3574
3575 if (scsi_hba_probe(sd, NULL) == SCSIPROBE_EXISTS) {
3576 rval = mrsas_config_scsi_device(instance, sd, ldip);
3577 dev_err(instance->dip, CE_CONT,
3578 "?Phys. device found: tgt %d dtype %d: %s\n",
3579 tgt, dtype, sd->sd_inq->inq_vid);
3580 } else {
3581 rval = NDI_FAILURE;
3582 con_log(CL_DLEVEL1, (CE_NOTE, "Phys. device Not found "
3583 "scsi_hba_probe Failed: tgt %d dtype %d: %s",
3584 tgt, dtype, sd->sd_inq->inq_vid));
|