FreeBSD/sys/dev/qlxge/qls_os.c
/*
 * Name:	qls_pci_attach
 * Function:	attaches the device to the operating system
 */
qls_pci_attach
Function:    attaches the device to the operating system
qls_pci_attach Function : attaches the device to the operating system
static int
qls_pci_attach(device_t dev)
{
	qla_host_t *ha = NULL;
	int i;
	QL_DPRINT2((dev, "%s: enter\n", __func__));
        if ((ha = device_get_softc(dev)) == NULL) {
                device_printf(dev, "cannot get softc\n");
                return (ENOMEM);
        }
        memset(ha, 0, sizeof (qla_host_t));
        if (pci_get_device(dev) != PCI_DEVICE_QLOGIC_8000) {
                device_printf(dev, "device is not QLE8000\n");
                return (ENXIO);
	}
        ha->pci_func = pci_get_function(dev);
        ha->pci_dev = dev;
	pci_enable_busmaster(dev);
	ha->reg_rid = PCIR_BAR(1);
	ha->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ha->reg_rid,
				RF_ACTIVE);
        if (ha->pci_reg == NULL) {
                device_printf(dev, "unable to map any ports\n");
                goto qls_pci_attach_err;
        }
	ha->reg_rid1 = PCIR_BAR(3);
	ha->pci_reg1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
			&ha->reg_rid1, RF_ACTIVE);
        if (ha->pci_reg1 == NULL) {
                device_printf(dev, "unable to map any ports\n");
                goto qls_pci_attach_err;
        }
	mtx_init(&ha->hw_lock, "qla80xx_hw_lock", MTX_NETWORK_LOCK, MTX_DEF);
	mtx_init(&ha->tx_lock, "qla80xx_tx_lock", MTX_NETWORK_LOCK, MTX_DEF);
	qls_add_sysctls(ha);
	qls_hw_add_sysctls(ha);
	ha->flags.lock_init = 1;
	ha->msix_count = pci_msix_count(dev);
	if (ha->msix_count < qls_get_msix_count(ha)) {
		device_printf(dev, "%s: msix_count[%d] not enough\n", __func__,
			ha->msix_count);
		goto qls_pci_attach_err;
	}
	ha->msix_count = qls_get_msix_count(ha);
	device_printf(dev, "\n%s: ha %p pci_func 0x%x  msix_count 0x%x"
		" pci_reg %p pci_reg1 %p\n", __func__, ha,
		ha->pci_func, ha->msix_count, ha->pci_reg, ha->pci_reg1);
	if (pci_alloc_msix(dev, &ha->msix_count)) {
		device_printf(dev, "%s: pci_alloc_msi[%d] failed\n", __func__,
			ha->msix_count);
		ha->msix_count = 0;
		goto qls_pci_attach_err;
	}
        for (i = 0; i < ha->num_rx_rings; i++) {
                ha->irq_vec[i].cq_idx = i;
                ha->irq_vec[i].ha = ha;
                ha->irq_vec[i].irq_rid = 1 + i;
                ha->irq_vec[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
                                &ha->irq_vec[i].irq_rid,
                                (RF_ACTIVE | RF_SHAREABLE));
                if (ha->irq_vec[i].irq == NULL) {
                        device_printf(dev, "could not allocate interrupt\n");
                        goto qls_pci_attach_err;
                }
		if (bus_setup_intr(dev, ha->irq_vec[i].irq,
			(INTR_TYPE_NET | INTR_MPSAFE), NULL, qls_isr,
			&ha->irq_vec[i], &ha->irq_vec[i].handle)) {
				device_printf(dev,
					"could not setup interrupt\n");
			goto qls_pci_attach_err;
		}
        }
	qls_rd_nic_params(ha);
	if (qls_alloc_parent_dma_tag(ha)) {
		device_printf(dev, "%s: qls_alloc_parent_dma_tag failed\n",
			__func__);
		goto qls_pci_attach_err;
	}
	if (qls_alloc_dma(ha)) {
		device_printf(dev, "%s: qls_alloc_dma failed\n", __func__);
		goto qls_pci_attach_err;
	}
	qls_init_ifnet(dev, ha);
	ha->flags.qla_watchdog_active = 1;
	ha->flags.qla_watchdog_pause = 1;
	TASK_INIT(&ha->tx_task, 0, qls_tx_done, ha);
	ha->tx_tq = taskqueue_create_fast("qla_txq", M_NOWAIT,
			taskqueue_thread_enqueue, &ha->tx_tq);
	taskqueue_start_threads(&ha->tx_tq, 1, PI_NET, "%s txq",
		device_get_nameunit(ha->pci_dev));
	callout_init(&ha->tx_callout, 1);
	ha->flags.qla_callout_init = 1;
        if (qls_make_cdev(ha)) {
                device_printf(dev, "%s: qls_make_cdev failed\n", __func__);
                goto qls_pci_attach_err;
        }
	callout_reset(&ha->tx_callout, QLA_WATCHDOG_CALLOUT_TICKS,
		qls_watchdog, ha);
        TASK_INIT(&ha->err_task, 0, qls_error_recovery, ha);
        ha->err_tq = taskqueue_create_fast("qla_errq", M_NOWAIT,
                        taskqueue_thread_enqueue, &ha->err_tq);
        taskqueue_start_threads(&ha->err_tq, 1, PI_NET, "%s errq",
                device_get_nameunit(ha->pci_dev));
	QL_DPRINT2((dev, "%s: exit 0\n", __func__));
        return (0);
qls_pci_attach_err:
	qls_release(ha);
	QL_DPRINT2((dev, "%s: exit ENXIO\n", __func__));
        return (ENXIO);
}
static int qls_pci_attach ( device_t dev ) { qla_host_t * ha = NULL ; int i ; QL_DPRINT2 ( ( dev , " \n " , __func__ ) ) ; if ( ( ha = device_get_softc ( dev ) ) == NULL ) { device_printf ( dev , " \n " ) ; return ( ENOMEM ) ; } memset ( ha , 0 , sizeof ( qla_host_t ) ) ; if ( pci_get_device ( dev ) != PCI_DEVICE_QLOGIC_8000 ) { device_printf ( dev , " \n " ) ; return ( ENXIO ) ; } ha -> pci_func = pci_get_function ( dev ) ; ha -> pci_dev = dev ; pci_enable_busmaster ( dev ) ; ha -> reg_rid = PCIR_BAR ( 1 ) ; ha -> pci_reg = bus_alloc_resource_any ( dev , SYS_RES_MEMORY , & ha -> reg_rid , RF_ACTIVE ) ; if ( ha -> pci_reg == NULL ) { device_printf ( dev , " \n " ) ; goto qls_pci_attach_err ; } ha -> reg_rid1 = PCIR_BAR ( 3 ) ; ha -> pci_reg1 = bus_alloc_resource_any ( dev , SYS_RES_MEMORY , & ha -> reg_rid1 , RF_ACTIVE ) ; if ( ha -> pci_reg1 == NULL ) { device_printf ( dev , " \n " ) ; goto qls_pci_attach_err ; } mtx_init ( & ha -> hw_lock , " " , MTX_NETWORK_LOCK , MTX_DEF ) ; mtx_init ( & ha -> tx_lock , " " , MTX_NETWORK_LOCK , MTX_DEF ) ; qls_add_sysctls ( ha ) ; qls_hw_add_sysctls ( ha ) ; ha -> flags . lock_init = 1 ; ha -> msix_count = pci_msix_count ( dev ) ; if ( ha -> msix_count < qls_get_msix_count ( ha ) ) { device_printf ( dev , " \n " , __func__ , ha -> msix_count ) ; goto qls_pci_attach_err ; } ha -> msix_count = qls_get_msix_count ( ha ) ; device_printf ( dev , " \n " " \n " , __func__ , ha , ha -> pci_func , ha -> msix_count , ha -> pci_reg , ha -> pci_reg1 ) ; if ( pci_alloc_msix ( dev , & ha -> msix_count ) ) { device_printf ( dev , " \n " , __func__ , ha -> msix_count ) ; ha -> msix_count = 0 ; goto qls_pci_attach_err ; } for ( i = 0 ; i < ha -> num_rx_rings ; i ++ ) { ha -> irq_vec [ i ] . cq_idx = i ; ha -> irq_vec [ i ] . ha = ha ; ha -> irq_vec [ i ] . irq_rid = 1 + i ; ha -> irq_vec [ i ] . irq = bus_alloc_resource_any ( dev , SYS_RES_IRQ , & ha -> irq_vec [ i ] . irq_rid , ( RF_ACTIVE | RF_SHAREABLE ) ) ; if ( ha -> irq_vec [ i ] . irq == NULL ) { device_printf ( dev , " \n " ) ; goto qls_pci_attach_err ; } if ( bus_setup_intr ( dev , ha -> irq_vec [ i ] . irq , ( INTR_TYPE_NET | INTR_MPSAFE ) , NULL , qls_isr , & ha -> irq_vec [ i ] , & ha -> irq_vec [ i ] . handle ) ) { device_printf ( dev , " \n " ) ; goto qls_pci_attach_err ; } } qls_rd_nic_params ( ha ) ; if ( qls_alloc_parent_dma_tag ( ha ) ) { device_printf ( dev , " \n " , __func__ ) ; goto qls_pci_attach_err ; } if ( qls_alloc_dma ( ha ) ) { device_printf ( dev , " \n " , __func__ ) ; goto qls_pci_attach_err ; } qls_init_ifnet ( dev , ha ) ; ha -> flags . qla_watchdog_active = 1 ; ha -> flags . qla_watchdog_pause = 1 ; TASK_INIT ( & ha -> tx_task , 0 , qls_tx_done , ha ) ; ha -> tx_tq = taskqueue_create_fast ( " " , M_NOWAIT , taskqueue_thread_enqueue , & ha -> tx_tq ) ; taskqueue_start_threads ( & ha -> tx_tq , 1 , PI_NET , " " , device_get_nameunit ( ha -> pci_dev ) ) ; callout_init ( & ha -> tx_callout , 1 ) ; ha -> flags . qla_callout_init = 1 ; if ( qls_make_cdev ( ha ) ) { device_printf ( dev , " \n " , __func__ ) ; goto qls_pci_attach_err ; } callout_reset ( & ha -> tx_callout , QLA_WATCHDOG_CALLOUT_TICKS , qls_watchdog , ha ) ; TASK_INIT ( & ha -> err_task , 0 , qls_error_recovery , ha ) ; ha -> err_tq = taskqueue_create_fast ( " " , M_NOWAIT , taskqueue_thread_enqueue , & ha -> err_tq ) ; taskqueue_start_threads ( & ha -> err_tq , 1 , PI_NET , " " , device_get_nameunit ( ha -> pci_dev ) ) ; QL_DPRINT2 ( ( dev , " \n " , __func__ ) ) ; return ( 0 ) ; qls_pci_attach_err : qls_release ( ha ) ; QL_DPRINT2 ( ( dev , " \n " , __func__ ) ) ; return ( ENXIO ) ; }
Name:        qls_pci_attach
 Function:    attaches the device to the operating system
Name : qls_pci_attach Function : attaches the device to the operating system
/* allocate parent dma tag */ /* alloc all dma buffers */ /* create the o.s ethernet interface */ /* create ioctl device interface */