1*17fcb3dcSFan Gong // SPDX-License-Identifier: GPL-2.0 2*17fcb3dcSFan Gong // Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. 3*17fcb3dcSFan Gong 4*17fcb3dcSFan Gong #include <linux/delay.h> 5*17fcb3dcSFan Gong #include <linux/iopoll.h> 6*17fcb3dcSFan Gong 7*17fcb3dcSFan Gong #include "hinic3_hw_cfg.h" 8*17fcb3dcSFan Gong #include "hinic3_hwdev.h" 9*17fcb3dcSFan Gong #include "hinic3_lld.h" 10*17fcb3dcSFan Gong #include "hinic3_mgmt.h" 11*17fcb3dcSFan Gong 12*17fcb3dcSFan Gong #define HINIC3_VF_PCI_CFG_REG_BAR 0 13*17fcb3dcSFan Gong #define HINIC3_PCI_INTR_REG_BAR 2 14*17fcb3dcSFan Gong #define HINIC3_PCI_DB_BAR 4 15*17fcb3dcSFan Gong 16*17fcb3dcSFan Gong #define HINIC3_EVENT_POLL_SLEEP_US 1000 17*17fcb3dcSFan Gong #define HINIC3_EVENT_POLL_TIMEOUT_US 10000000 18*17fcb3dcSFan Gong 19*17fcb3dcSFan Gong static struct hinic3_adev_device { 20*17fcb3dcSFan Gong const char *name; 21*17fcb3dcSFan Gong } hinic3_adev_devices[HINIC3_SERVICE_T_MAX] = { 22*17fcb3dcSFan Gong [HINIC3_SERVICE_T_NIC] = { 23*17fcb3dcSFan Gong .name = "nic", 24*17fcb3dcSFan Gong }, 25*17fcb3dcSFan Gong }; 26*17fcb3dcSFan Gong 27*17fcb3dcSFan Gong static bool hinic3_adev_svc_supported(struct hinic3_hwdev *hwdev, 28*17fcb3dcSFan Gong enum hinic3_service_type svc_type) 29*17fcb3dcSFan Gong { 30*17fcb3dcSFan Gong switch (svc_type) { 31*17fcb3dcSFan Gong case HINIC3_SERVICE_T_NIC: 32*17fcb3dcSFan Gong return hinic3_support_nic(hwdev); 33*17fcb3dcSFan Gong default: 34*17fcb3dcSFan Gong break; 35*17fcb3dcSFan Gong } 36*17fcb3dcSFan Gong 37*17fcb3dcSFan Gong return false; 38*17fcb3dcSFan Gong } 39*17fcb3dcSFan Gong 40*17fcb3dcSFan Gong static void hinic3_comm_adev_release(struct device *dev) 41*17fcb3dcSFan Gong { 42*17fcb3dcSFan Gong struct hinic3_adev *hadev = container_of(dev, struct hinic3_adev, 43*17fcb3dcSFan Gong adev.dev); 44*17fcb3dcSFan Gong 45*17fcb3dcSFan Gong kfree(hadev); 46*17fcb3dcSFan Gong } 47*17fcb3dcSFan Gong 48*17fcb3dcSFan Gong static struct hinic3_adev *hinic3_add_one_adev(struct hinic3_hwdev *hwdev, 49*17fcb3dcSFan Gong enum hinic3_service_type svc_type) 50*17fcb3dcSFan Gong { 51*17fcb3dcSFan Gong struct hinic3_adev *hadev; 52*17fcb3dcSFan Gong const char *svc_name; 53*17fcb3dcSFan Gong int ret; 54*17fcb3dcSFan Gong 55*17fcb3dcSFan Gong hadev = kzalloc(sizeof(*hadev), GFP_KERNEL); 56*17fcb3dcSFan Gong if (!hadev) 57*17fcb3dcSFan Gong return NULL; 58*17fcb3dcSFan Gong 59*17fcb3dcSFan Gong svc_name = hinic3_adev_devices[svc_type].name; 60*17fcb3dcSFan Gong hadev->adev.name = svc_name; 61*17fcb3dcSFan Gong hadev->adev.id = hwdev->dev_id; 62*17fcb3dcSFan Gong hadev->adev.dev.parent = hwdev->dev; 63*17fcb3dcSFan Gong hadev->adev.dev.release = hinic3_comm_adev_release; 64*17fcb3dcSFan Gong hadev->svc_type = svc_type; 65*17fcb3dcSFan Gong hadev->hwdev = hwdev; 66*17fcb3dcSFan Gong 67*17fcb3dcSFan Gong ret = auxiliary_device_init(&hadev->adev); 68*17fcb3dcSFan Gong if (ret) { 69*17fcb3dcSFan Gong dev_err(hwdev->dev, "failed init adev %s %u\n", 70*17fcb3dcSFan Gong svc_name, hwdev->dev_id); 71*17fcb3dcSFan Gong kfree(hadev); 72*17fcb3dcSFan Gong return NULL; 73*17fcb3dcSFan Gong } 74*17fcb3dcSFan Gong 75*17fcb3dcSFan Gong ret = auxiliary_device_add(&hadev->adev); 76*17fcb3dcSFan Gong if (ret) { 77*17fcb3dcSFan Gong dev_err(hwdev->dev, "failed to add adev %s %u\n", 78*17fcb3dcSFan Gong svc_name, hwdev->dev_id); 79*17fcb3dcSFan Gong auxiliary_device_uninit(&hadev->adev); 80*17fcb3dcSFan Gong return NULL; 81*17fcb3dcSFan Gong } 82*17fcb3dcSFan Gong 83*17fcb3dcSFan Gong return hadev; 84*17fcb3dcSFan Gong } 85*17fcb3dcSFan Gong 86*17fcb3dcSFan Gong static void hinic3_del_one_adev(struct hinic3_hwdev *hwdev, 87*17fcb3dcSFan Gong enum hinic3_service_type svc_type) 88*17fcb3dcSFan Gong { 89*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = hwdev->adapter; 90*17fcb3dcSFan Gong struct hinic3_adev *hadev; 91*17fcb3dcSFan Gong int timeout; 92*17fcb3dcSFan Gong bool state; 93*17fcb3dcSFan Gong 94*17fcb3dcSFan Gong timeout = read_poll_timeout(test_and_set_bit, state, !state, 95*17fcb3dcSFan Gong HINIC3_EVENT_POLL_SLEEP_US, 96*17fcb3dcSFan Gong HINIC3_EVENT_POLL_TIMEOUT_US, 97*17fcb3dcSFan Gong false, svc_type, &pci_adapter->state); 98*17fcb3dcSFan Gong 99*17fcb3dcSFan Gong hadev = pci_adapter->hadev[svc_type]; 100*17fcb3dcSFan Gong auxiliary_device_delete(&hadev->adev); 101*17fcb3dcSFan Gong auxiliary_device_uninit(&hadev->adev); 102*17fcb3dcSFan Gong pci_adapter->hadev[svc_type] = NULL; 103*17fcb3dcSFan Gong if (!timeout) 104*17fcb3dcSFan Gong clear_bit(svc_type, &pci_adapter->state); 105*17fcb3dcSFan Gong } 106*17fcb3dcSFan Gong 107*17fcb3dcSFan Gong static int hinic3_attach_aux_devices(struct hinic3_hwdev *hwdev) 108*17fcb3dcSFan Gong { 109*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = hwdev->adapter; 110*17fcb3dcSFan Gong enum hinic3_service_type svc_type; 111*17fcb3dcSFan Gong 112*17fcb3dcSFan Gong mutex_lock(&pci_adapter->pdev_mutex); 113*17fcb3dcSFan Gong 114*17fcb3dcSFan Gong for (svc_type = 0; svc_type < HINIC3_SERVICE_T_MAX; svc_type++) { 115*17fcb3dcSFan Gong if (!hinic3_adev_svc_supported(hwdev, svc_type)) 116*17fcb3dcSFan Gong continue; 117*17fcb3dcSFan Gong 118*17fcb3dcSFan Gong pci_adapter->hadev[svc_type] = hinic3_add_one_adev(hwdev, 119*17fcb3dcSFan Gong svc_type); 120*17fcb3dcSFan Gong if (!pci_adapter->hadev[svc_type]) 121*17fcb3dcSFan Gong goto err_del_adevs; 122*17fcb3dcSFan Gong } 123*17fcb3dcSFan Gong mutex_unlock(&pci_adapter->pdev_mutex); 124*17fcb3dcSFan Gong return 0; 125*17fcb3dcSFan Gong 126*17fcb3dcSFan Gong err_del_adevs: 127*17fcb3dcSFan Gong while (svc_type > 0) { 128*17fcb3dcSFan Gong svc_type--; 129*17fcb3dcSFan Gong if (pci_adapter->hadev[svc_type]) { 130*17fcb3dcSFan Gong hinic3_del_one_adev(hwdev, svc_type); 131*17fcb3dcSFan Gong pci_adapter->hadev[svc_type] = NULL; 132*17fcb3dcSFan Gong } 133*17fcb3dcSFan Gong } 134*17fcb3dcSFan Gong mutex_unlock(&pci_adapter->pdev_mutex); 135*17fcb3dcSFan Gong return -ENOMEM; 136*17fcb3dcSFan Gong } 137*17fcb3dcSFan Gong 138*17fcb3dcSFan Gong static void hinic3_detach_aux_devices(struct hinic3_hwdev *hwdev) 139*17fcb3dcSFan Gong { 140*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = hwdev->adapter; 141*17fcb3dcSFan Gong int i; 142*17fcb3dcSFan Gong 143*17fcb3dcSFan Gong mutex_lock(&pci_adapter->pdev_mutex); 144*17fcb3dcSFan Gong for (i = 0; i < ARRAY_SIZE(hinic3_adev_devices); i++) { 145*17fcb3dcSFan Gong if (pci_adapter->hadev[i]) 146*17fcb3dcSFan Gong hinic3_del_one_adev(hwdev, i); 147*17fcb3dcSFan Gong } 148*17fcb3dcSFan Gong mutex_unlock(&pci_adapter->pdev_mutex); 149*17fcb3dcSFan Gong } 150*17fcb3dcSFan Gong 151*17fcb3dcSFan Gong struct hinic3_hwdev *hinic3_adev_get_hwdev(struct auxiliary_device *adev) 152*17fcb3dcSFan Gong { 153*17fcb3dcSFan Gong struct hinic3_adev *hadev; 154*17fcb3dcSFan Gong 155*17fcb3dcSFan Gong hadev = container_of(adev, struct hinic3_adev, adev); 156*17fcb3dcSFan Gong return hadev->hwdev; 157*17fcb3dcSFan Gong } 158*17fcb3dcSFan Gong 159*17fcb3dcSFan Gong void hinic3_adev_event_register(struct auxiliary_device *adev, 160*17fcb3dcSFan Gong void (*event_handler)(struct auxiliary_device *adev, 161*17fcb3dcSFan Gong struct hinic3_event_info *event)) 162*17fcb3dcSFan Gong { 163*17fcb3dcSFan Gong struct hinic3_adev *hadev; 164*17fcb3dcSFan Gong 165*17fcb3dcSFan Gong hadev = container_of(adev, struct hinic3_adev, adev); 166*17fcb3dcSFan Gong hadev->event = event_handler; 167*17fcb3dcSFan Gong } 168*17fcb3dcSFan Gong 169*17fcb3dcSFan Gong void hinic3_adev_event_unregister(struct auxiliary_device *adev) 170*17fcb3dcSFan Gong { 171*17fcb3dcSFan Gong struct hinic3_adev *hadev; 172*17fcb3dcSFan Gong 173*17fcb3dcSFan Gong hadev = container_of(adev, struct hinic3_adev, adev); 174*17fcb3dcSFan Gong hadev->event = NULL; 175*17fcb3dcSFan Gong } 176*17fcb3dcSFan Gong 177*17fcb3dcSFan Gong static int hinic3_mapping_bar(struct pci_dev *pdev, 178*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter) 179*17fcb3dcSFan Gong { 180*17fcb3dcSFan Gong pci_adapter->cfg_reg_base = pci_ioremap_bar(pdev, 181*17fcb3dcSFan Gong HINIC3_VF_PCI_CFG_REG_BAR); 182*17fcb3dcSFan Gong if (!pci_adapter->cfg_reg_base) { 183*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to map configuration regs\n"); 184*17fcb3dcSFan Gong return -ENOMEM; 185*17fcb3dcSFan Gong } 186*17fcb3dcSFan Gong 187*17fcb3dcSFan Gong pci_adapter->intr_reg_base = pci_ioremap_bar(pdev, 188*17fcb3dcSFan Gong HINIC3_PCI_INTR_REG_BAR); 189*17fcb3dcSFan Gong if (!pci_adapter->intr_reg_base) { 190*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to map interrupt regs\n"); 191*17fcb3dcSFan Gong goto err_unmap_cfg_reg_base; 192*17fcb3dcSFan Gong } 193*17fcb3dcSFan Gong 194*17fcb3dcSFan Gong pci_adapter->db_base_phy = pci_resource_start(pdev, HINIC3_PCI_DB_BAR); 195*17fcb3dcSFan Gong pci_adapter->db_dwqe_len = pci_resource_len(pdev, HINIC3_PCI_DB_BAR); 196*17fcb3dcSFan Gong pci_adapter->db_base = pci_ioremap_bar(pdev, HINIC3_PCI_DB_BAR); 197*17fcb3dcSFan Gong if (!pci_adapter->db_base) { 198*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to map doorbell regs\n"); 199*17fcb3dcSFan Gong goto err_unmap_intr_reg_base; 200*17fcb3dcSFan Gong } 201*17fcb3dcSFan Gong 202*17fcb3dcSFan Gong return 0; 203*17fcb3dcSFan Gong 204*17fcb3dcSFan Gong err_unmap_intr_reg_base: 205*17fcb3dcSFan Gong iounmap(pci_adapter->intr_reg_base); 206*17fcb3dcSFan Gong 207*17fcb3dcSFan Gong err_unmap_cfg_reg_base: 208*17fcb3dcSFan Gong iounmap(pci_adapter->cfg_reg_base); 209*17fcb3dcSFan Gong 210*17fcb3dcSFan Gong return -ENOMEM; 211*17fcb3dcSFan Gong } 212*17fcb3dcSFan Gong 213*17fcb3dcSFan Gong static void hinic3_unmapping_bar(struct hinic3_pcidev *pci_adapter) 214*17fcb3dcSFan Gong { 215*17fcb3dcSFan Gong iounmap(pci_adapter->db_base); 216*17fcb3dcSFan Gong iounmap(pci_adapter->intr_reg_base); 217*17fcb3dcSFan Gong iounmap(pci_adapter->cfg_reg_base); 218*17fcb3dcSFan Gong } 219*17fcb3dcSFan Gong 220*17fcb3dcSFan Gong static int hinic3_pci_init(struct pci_dev *pdev) 221*17fcb3dcSFan Gong { 222*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter; 223*17fcb3dcSFan Gong int err; 224*17fcb3dcSFan Gong 225*17fcb3dcSFan Gong pci_adapter = kzalloc(sizeof(*pci_adapter), GFP_KERNEL); 226*17fcb3dcSFan Gong if (!pci_adapter) 227*17fcb3dcSFan Gong return -ENOMEM; 228*17fcb3dcSFan Gong 229*17fcb3dcSFan Gong pci_adapter->pdev = pdev; 230*17fcb3dcSFan Gong mutex_init(&pci_adapter->pdev_mutex); 231*17fcb3dcSFan Gong 232*17fcb3dcSFan Gong pci_set_drvdata(pdev, pci_adapter); 233*17fcb3dcSFan Gong 234*17fcb3dcSFan Gong err = pci_enable_device(pdev); 235*17fcb3dcSFan Gong if (err) { 236*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to enable PCI device\n"); 237*17fcb3dcSFan Gong goto err_free_pci_adapter; 238*17fcb3dcSFan Gong } 239*17fcb3dcSFan Gong 240*17fcb3dcSFan Gong err = pci_request_regions(pdev, HINIC3_NIC_DRV_NAME); 241*17fcb3dcSFan Gong if (err) { 242*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to request regions\n"); 243*17fcb3dcSFan Gong goto err_disable_device; 244*17fcb3dcSFan Gong } 245*17fcb3dcSFan Gong 246*17fcb3dcSFan Gong pci_set_master(pdev); 247*17fcb3dcSFan Gong 248*17fcb3dcSFan Gong err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 249*17fcb3dcSFan Gong if (err) { 250*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to set DMA mask\n"); 251*17fcb3dcSFan Gong goto err_release_regions; 252*17fcb3dcSFan Gong } 253*17fcb3dcSFan Gong 254*17fcb3dcSFan Gong return 0; 255*17fcb3dcSFan Gong 256*17fcb3dcSFan Gong err_release_regions: 257*17fcb3dcSFan Gong pci_clear_master(pdev); 258*17fcb3dcSFan Gong pci_release_regions(pdev); 259*17fcb3dcSFan Gong 260*17fcb3dcSFan Gong err_disable_device: 261*17fcb3dcSFan Gong pci_disable_device(pdev); 262*17fcb3dcSFan Gong 263*17fcb3dcSFan Gong err_free_pci_adapter: 264*17fcb3dcSFan Gong pci_set_drvdata(pdev, NULL); 265*17fcb3dcSFan Gong mutex_destroy(&pci_adapter->pdev_mutex); 266*17fcb3dcSFan Gong kfree(pci_adapter); 267*17fcb3dcSFan Gong 268*17fcb3dcSFan Gong return err; 269*17fcb3dcSFan Gong } 270*17fcb3dcSFan Gong 271*17fcb3dcSFan Gong static void hinic3_pci_uninit(struct pci_dev *pdev) 272*17fcb3dcSFan Gong { 273*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev); 274*17fcb3dcSFan Gong 275*17fcb3dcSFan Gong pci_clear_master(pdev); 276*17fcb3dcSFan Gong pci_release_regions(pdev); 277*17fcb3dcSFan Gong pci_disable_device(pdev); 278*17fcb3dcSFan Gong pci_set_drvdata(pdev, NULL); 279*17fcb3dcSFan Gong mutex_destroy(&pci_adapter->pdev_mutex); 280*17fcb3dcSFan Gong kfree(pci_adapter); 281*17fcb3dcSFan Gong } 282*17fcb3dcSFan Gong 283*17fcb3dcSFan Gong static int hinic3_func_init(struct pci_dev *pdev, 284*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter) 285*17fcb3dcSFan Gong { 286*17fcb3dcSFan Gong int err; 287*17fcb3dcSFan Gong 288*17fcb3dcSFan Gong err = hinic3_init_hwdev(pdev); 289*17fcb3dcSFan Gong if (err) { 290*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to initialize hardware device\n"); 291*17fcb3dcSFan Gong return err; 292*17fcb3dcSFan Gong } 293*17fcb3dcSFan Gong 294*17fcb3dcSFan Gong err = hinic3_attach_aux_devices(pci_adapter->hwdev); 295*17fcb3dcSFan Gong if (err) 296*17fcb3dcSFan Gong goto err_free_hwdev; 297*17fcb3dcSFan Gong 298*17fcb3dcSFan Gong return 0; 299*17fcb3dcSFan Gong 300*17fcb3dcSFan Gong err_free_hwdev: 301*17fcb3dcSFan Gong hinic3_free_hwdev(pci_adapter->hwdev); 302*17fcb3dcSFan Gong 303*17fcb3dcSFan Gong return err; 304*17fcb3dcSFan Gong } 305*17fcb3dcSFan Gong 306*17fcb3dcSFan Gong static void hinic3_func_uninit(struct pci_dev *pdev) 307*17fcb3dcSFan Gong { 308*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev); 309*17fcb3dcSFan Gong 310*17fcb3dcSFan Gong hinic3_detach_aux_devices(pci_adapter->hwdev); 311*17fcb3dcSFan Gong hinic3_free_hwdev(pci_adapter->hwdev); 312*17fcb3dcSFan Gong } 313*17fcb3dcSFan Gong 314*17fcb3dcSFan Gong static int hinic3_probe_func(struct hinic3_pcidev *pci_adapter) 315*17fcb3dcSFan Gong { 316*17fcb3dcSFan Gong struct pci_dev *pdev = pci_adapter->pdev; 317*17fcb3dcSFan Gong int err; 318*17fcb3dcSFan Gong 319*17fcb3dcSFan Gong err = hinic3_mapping_bar(pdev, pci_adapter); 320*17fcb3dcSFan Gong if (err) { 321*17fcb3dcSFan Gong dev_err(&pdev->dev, "Failed to map bar\n"); 322*17fcb3dcSFan Gong goto err_out; 323*17fcb3dcSFan Gong } 324*17fcb3dcSFan Gong 325*17fcb3dcSFan Gong err = hinic3_func_init(pdev, pci_adapter); 326*17fcb3dcSFan Gong if (err) 327*17fcb3dcSFan Gong goto err_unmap_bar; 328*17fcb3dcSFan Gong 329*17fcb3dcSFan Gong return 0; 330*17fcb3dcSFan Gong 331*17fcb3dcSFan Gong err_unmap_bar: 332*17fcb3dcSFan Gong hinic3_unmapping_bar(pci_adapter); 333*17fcb3dcSFan Gong 334*17fcb3dcSFan Gong err_out: 335*17fcb3dcSFan Gong dev_err(&pdev->dev, "PCIe device probe function failed\n"); 336*17fcb3dcSFan Gong return err; 337*17fcb3dcSFan Gong } 338*17fcb3dcSFan Gong 339*17fcb3dcSFan Gong static void hinic3_remove_func(struct hinic3_pcidev *pci_adapter) 340*17fcb3dcSFan Gong { 341*17fcb3dcSFan Gong struct pci_dev *pdev = pci_adapter->pdev; 342*17fcb3dcSFan Gong 343*17fcb3dcSFan Gong hinic3_func_uninit(pdev); 344*17fcb3dcSFan Gong hinic3_unmapping_bar(pci_adapter); 345*17fcb3dcSFan Gong } 346*17fcb3dcSFan Gong 347*17fcb3dcSFan Gong static int hinic3_probe(struct pci_dev *pdev, const struct pci_device_id *id) 348*17fcb3dcSFan Gong { 349*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter; 350*17fcb3dcSFan Gong int err; 351*17fcb3dcSFan Gong 352*17fcb3dcSFan Gong err = hinic3_pci_init(pdev); 353*17fcb3dcSFan Gong if (err) 354*17fcb3dcSFan Gong goto err_out; 355*17fcb3dcSFan Gong 356*17fcb3dcSFan Gong pci_adapter = pci_get_drvdata(pdev); 357*17fcb3dcSFan Gong err = hinic3_probe_func(pci_adapter); 358*17fcb3dcSFan Gong if (err) 359*17fcb3dcSFan Gong goto err_uninit_pci; 360*17fcb3dcSFan Gong 361*17fcb3dcSFan Gong return 0; 362*17fcb3dcSFan Gong 363*17fcb3dcSFan Gong err_uninit_pci: 364*17fcb3dcSFan Gong hinic3_pci_uninit(pdev); 365*17fcb3dcSFan Gong 366*17fcb3dcSFan Gong err_out: 367*17fcb3dcSFan Gong dev_err(&pdev->dev, "PCIe device probe failed\n"); 368*17fcb3dcSFan Gong return err; 369*17fcb3dcSFan Gong } 370*17fcb3dcSFan Gong 371*17fcb3dcSFan Gong static void hinic3_remove(struct pci_dev *pdev) 372*17fcb3dcSFan Gong { 373*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev); 374*17fcb3dcSFan Gong 375*17fcb3dcSFan Gong hinic3_remove_func(pci_adapter); 376*17fcb3dcSFan Gong hinic3_pci_uninit(pdev); 377*17fcb3dcSFan Gong } 378*17fcb3dcSFan Gong 379*17fcb3dcSFan Gong static const struct pci_device_id hinic3_pci_table[] = { 380*17fcb3dcSFan Gong /* Completed by later submission due to LoC limit. */ 381*17fcb3dcSFan Gong {0, 0} 382*17fcb3dcSFan Gong 383*17fcb3dcSFan Gong }; 384*17fcb3dcSFan Gong 385*17fcb3dcSFan Gong MODULE_DEVICE_TABLE(pci, hinic3_pci_table); 386*17fcb3dcSFan Gong 387*17fcb3dcSFan Gong static void hinic3_shutdown(struct pci_dev *pdev) 388*17fcb3dcSFan Gong { 389*17fcb3dcSFan Gong struct hinic3_pcidev *pci_adapter = pci_get_drvdata(pdev); 390*17fcb3dcSFan Gong 391*17fcb3dcSFan Gong pci_disable_device(pdev); 392*17fcb3dcSFan Gong 393*17fcb3dcSFan Gong if (pci_adapter) 394*17fcb3dcSFan Gong hinic3_set_api_stop(pci_adapter->hwdev); 395*17fcb3dcSFan Gong } 396*17fcb3dcSFan Gong 397*17fcb3dcSFan Gong static struct pci_driver hinic3_driver = { 398*17fcb3dcSFan Gong .name = HINIC3_NIC_DRV_NAME, 399*17fcb3dcSFan Gong .id_table = hinic3_pci_table, 400*17fcb3dcSFan Gong .probe = hinic3_probe, 401*17fcb3dcSFan Gong .remove = hinic3_remove, 402*17fcb3dcSFan Gong .shutdown = hinic3_shutdown, 403*17fcb3dcSFan Gong .sriov_configure = pci_sriov_configure_simple 404*17fcb3dcSFan Gong }; 405*17fcb3dcSFan Gong 406*17fcb3dcSFan Gong int hinic3_lld_init(void) 407*17fcb3dcSFan Gong { 408*17fcb3dcSFan Gong return pci_register_driver(&hinic3_driver); 409*17fcb3dcSFan Gong } 410*17fcb3dcSFan Gong 411*17fcb3dcSFan Gong void hinic3_lld_exit(void) 412*17fcb3dcSFan Gong { 413*17fcb3dcSFan Gong pci_unregister_driver(&hinic3_driver); 414*17fcb3dcSFan Gong } 415