2490 }
2491
2492 static int
2493 nvme_fm_errcb(dev_info_t *dip, ddi_fm_error_t *fm_error, const void *arg)
2494 {
2495 _NOTE(ARGUNUSED(arg));
2496
2497 pci_ereport_post(dip, fm_error, NULL);
2498 return (fm_error->fme_status);
2499 }
2500
2501 static int
2502 nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2503 {
2504 nvme_t *nvme;
2505 int instance;
2506 int nregs;
2507 off_t regsize;
2508 int i;
2509 char name[32];
2510
2511 if (cmd != DDI_ATTACH)
2512 return (DDI_FAILURE);
2513
2514 instance = ddi_get_instance(dip);
2515
2516 if (ddi_soft_state_zalloc(nvme_state, instance) != DDI_SUCCESS)
2517 return (DDI_FAILURE);
2518
2519 nvme = ddi_get_soft_state(nvme_state, instance);
2520 ddi_set_driver_private(dip, nvme);
2521 nvme->n_dip = dip;
2522
2523 nvme->n_strict_version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2524 DDI_PROP_DONTPASS, "strict-version", 1) == 1 ? B_TRUE : B_FALSE;
2525 nvme->n_ignore_unknown_vendor_status = ddi_prop_get_int(DDI_DEV_T_ANY,
2526 dip, DDI_PROP_DONTPASS, "ignore-unknown-vendor-status", 0) == 1 ?
2527 B_TRUE : B_FALSE;
2528 nvme->n_admin_queue_len = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2529 DDI_PROP_DONTPASS, "admin-queue-len", NVME_DEFAULT_ADMIN_QUEUE_LEN);
2626
2627 /*
2628 * Create PRP DMA cache
2629 */
2630 (void) snprintf(name, sizeof (name), "%s%d_prp_cache",
2631 ddi_driver_name(dip), ddi_get_instance(dip));
2632 nvme->n_prp_cache = kmem_cache_create(name, sizeof (nvme_dma_t),
2633 0, nvme_prp_dma_constructor, nvme_prp_dma_destructor,
2634 NULL, (void *)nvme, NULL, 0);
2635
2636 if (nvme_init(nvme) != DDI_SUCCESS)
2637 goto fail;
2638
2639 /*
2640 * Attach the blkdev driver for each namespace.
2641 */
2642 for (i = 0; i != nvme->n_namespace_count; i++) {
2643 if (nvme->n_ns[i].ns_ignore)
2644 continue;
2645
2646 nvme->n_ns[i].ns_bd_hdl = bd_alloc_handle(&nvme->n_ns[i],
2647 &nvme_bd_ops, &nvme->n_prp_dma_attr, KM_SLEEP);
2648
2649 if (nvme->n_ns[i].ns_bd_hdl == NULL) {
2650 dev_err(dip, CE_WARN,
2651 "!failed to get blkdev handle for namespace %d", i);
2652 goto fail;
2653 }
2654
2655 if (bd_attach_handle(dip, nvme->n_ns[i].ns_bd_hdl)
2656 != DDI_SUCCESS) {
2657 dev_err(dip, CE_WARN,
2658 "!failed to attach blkdev handle for namespace %d",
2659 i);
2660 goto fail;
2661 }
2662 }
2663
2664 return (DDI_SUCCESS);
2665
2666 fail:
2667 /* attach successful anyway so that FMA can retire the device */
|
2490 }
2491
2492 static int
2493 nvme_fm_errcb(dev_info_t *dip, ddi_fm_error_t *fm_error, const void *arg)
2494 {
2495 _NOTE(ARGUNUSED(arg));
2496
2497 pci_ereport_post(dip, fm_error, NULL);
2498 return (fm_error->fme_status);
2499 }
2500
2501 static int
2502 nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2503 {
2504 nvme_t *nvme;
2505 int instance;
2506 int nregs;
2507 off_t regsize;
2508 int i;
2509 char name[32];
2510 bd_ops_t l_bd_ops = nvme_bd_ops;
2511
2512 if (cmd != DDI_ATTACH)
2513 return (DDI_FAILURE);
2514
2515 instance = ddi_get_instance(dip);
2516
2517 if (ddi_soft_state_zalloc(nvme_state, instance) != DDI_SUCCESS)
2518 return (DDI_FAILURE);
2519
2520 nvme = ddi_get_soft_state(nvme_state, instance);
2521 ddi_set_driver_private(dip, nvme);
2522 nvme->n_dip = dip;
2523
2524 nvme->n_strict_version = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2525 DDI_PROP_DONTPASS, "strict-version", 1) == 1 ? B_TRUE : B_FALSE;
2526 nvme->n_ignore_unknown_vendor_status = ddi_prop_get_int(DDI_DEV_T_ANY,
2527 dip, DDI_PROP_DONTPASS, "ignore-unknown-vendor-status", 0) == 1 ?
2528 B_TRUE : B_FALSE;
2529 nvme->n_admin_queue_len = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
2530 DDI_PROP_DONTPASS, "admin-queue-len", NVME_DEFAULT_ADMIN_QUEUE_LEN);
2627
2628 /*
2629 * Create PRP DMA cache
2630 */
2631 (void) snprintf(name, sizeof (name), "%s%d_prp_cache",
2632 ddi_driver_name(dip), ddi_get_instance(dip));
2633 nvme->n_prp_cache = kmem_cache_create(name, sizeof (nvme_dma_t),
2634 0, nvme_prp_dma_constructor, nvme_prp_dma_destructor,
2635 NULL, (void *)nvme, NULL, 0);
2636
2637 if (nvme_init(nvme) != DDI_SUCCESS)
2638 goto fail;
2639
2640 /*
2641 * Attach the blkdev driver for each namespace.
2642 */
2643 for (i = 0; i != nvme->n_namespace_count; i++) {
2644 if (nvme->n_ns[i].ns_ignore)
2645 continue;
2646
2647 if (!nvme->n_write_cache_present) {
2648 l_bd_ops.o_sync_cache = NULL;
2649 }
2650
2651 nvme->n_ns[i].ns_bd_hdl = bd_alloc_handle(&nvme->n_ns[i],
2652 &l_bd_ops, &nvme->n_prp_dma_attr, KM_SLEEP);
2653
2654 if (nvme->n_ns[i].ns_bd_hdl == NULL) {
2655 dev_err(dip, CE_WARN,
2656 "!failed to get blkdev handle for namespace %d", i);
2657 goto fail;
2658 }
2659
2660 if (bd_attach_handle(dip, nvme->n_ns[i].ns_bd_hdl)
2661 != DDI_SUCCESS) {
2662 dev_err(dip, CE_WARN,
2663 "!failed to attach blkdev handle for namespace %d",
2664 i);
2665 goto fail;
2666 }
2667 }
2668
2669 return (DDI_SUCCESS);
2670
2671 fail:
2672 /* attach successful anyway so that FMA can retire the device */
|