static void r592_remove(struct pci_dev *pdev) { int error = 0; struct r592_device *dev = pci_get_drvdata(pdev); /* Stop the processing thread. That ensures that we won't take any more requests */ kthread_stop(dev->io_thread); r592_enable_device(dev, false); while (!error && dev->req) { dev->req->error = -ETIME; error = memstick_next_req(dev->host, &dev->req); } memstick_remove_host(dev->host); free_irq(dev->irq, dev); iounmap(dev->mmio); pci_release_regions(pdev); pci_disable_device(pdev); memstick_free_host(dev->host); if (dev->dummy_dma_page) pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page, dev->dummy_dma_page_physical_address); }
static int rtsx_pci_ms_drv_probe(struct platform_device *pdev) { struct memstick_host *msh; struct realtek_pci_ms *host; struct rtsx_pcr *pcr; struct pcr_handle *handle = pdev->dev.platform_data; int rc; if (!handle) return -ENXIO; pcr = handle->pcr; if (!pcr) return -ENXIO; dev_dbg(&(pdev->dev), ": Realtek PCI-E Memstick controller found\n"); msh = memstick_alloc_host(sizeof(*host), &pdev->dev); if (!msh) return -ENOMEM; host = memstick_priv(msh); host->pcr = pcr; host->msh = msh; host->pdev = pdev; platform_set_drvdata(pdev, host); pcr->slots[RTSX_MS_CARD].p_dev = pdev; pcr->slots[RTSX_MS_CARD].card_event = rtsx_pci_ms_card_event; mutex_init(&host->host_mutex); INIT_WORK(&host->handle_req, rtsx_pci_ms_handle_req); msh->request = rtsx_pci_ms_request; msh->set_param = rtsx_pci_ms_set_param; msh->caps = MEMSTICK_CAP_PAR4; rc = memstick_add_host(msh); if (rc) { memstick_free_host(msh); return rc; } return 0; }
static int rtsx_pci_ms_drv_remove(struct platform_device *pdev) { struct realtek_pci_ms *host = platform_get_drvdata(pdev); struct rtsx_pcr *pcr; struct memstick_host *msh; int rc; if (!host) return 0; pcr = host->pcr; pcr->slots[RTSX_MS_CARD].p_dev = NULL; pcr->slots[RTSX_MS_CARD].card_event = NULL; msh = host->msh; host->eject = true; mutex_lock(&host->host_mutex); if (host->req) { dev_dbg(&(pdev->dev), "%s: Controller removed during transfer\n", dev_name(&msh->dev)); rtsx_pci_complete_unfinished_transfer(pcr); host->req->error = -ENOMEDIUM; do { rc = memstick_next_req(msh, &host->req); if (!rc) host->req->error = -ENOMEDIUM; } while (!rc); } mutex_unlock(&host->host_mutex); memstick_remove_host(msh); memstick_free_host(msh); platform_set_drvdata(pdev, NULL); dev_dbg(&(pdev->dev), ": Realtek PCI-E Memstick controller has been removed\n"); return 0; }
/* Main entry */ static int r592_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int error = -ENOMEM; struct memstick_host *host; struct r592_device *dev; /* Allocate memory */ host = memstick_alloc_host(sizeof(struct r592_device), &pdev->dev); if (!host) goto error1; dev = memstick_priv(host); dev->host = host; dev->pci_dev = pdev; pci_set_drvdata(pdev, dev); /* pci initialization */ error = pci_enable_device(pdev); if (error) goto error2; pci_set_master(pdev); error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (error) goto error3; error = pci_request_regions(pdev, DRV_NAME); if (error) goto error3; dev->mmio = pci_ioremap_bar(pdev, 0); if (!dev->mmio) goto error4; dev->irq = pdev->irq; spin_lock_init(&dev->irq_lock); spin_lock_init(&dev->io_thread_lock); init_completion(&dev->dma_done); INIT_KFIFO(dev->pio_fifo); setup_timer(&dev->detect_timer, r592_detect_timer, (long unsigned int)dev); /* Host initialization */ host->caps = MEMSTICK_CAP_PAR4; host->request = r592_submit_req; host->set_param = r592_set_param; r592_check_dma(dev); dev->io_thread = kthread_run(r592_process_thread, dev, "r592_io"); if (IS_ERR(dev->io_thread)) { error = PTR_ERR(dev->io_thread); goto error5; } /* This is just a precation, so don't fail */ dev->dummy_dma_page = pci_alloc_consistent(pdev, PAGE_SIZE, &dev->dummy_dma_page_physical_address); r592_stop_dma(dev , 0); if (request_irq(dev->irq, &r592_irq, IRQF_SHARED, DRV_NAME, dev)) goto error6; r592_update_card_detect(dev); if (memstick_add_host(host)) goto error7; message("driver successfully loaded"); return 0; error7: free_irq(dev->irq, dev); error6: if (dev->dummy_dma_page) pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page, dev->dummy_dma_page_physical_address); kthread_stop(dev->io_thread); error5: iounmap(dev->mmio); error4: pci_release_regions(pdev); error3: pci_disable_device(pdev); error2: memstick_free_host(host); error1: return error; }