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); }
/* Main request processing thread */ static int r592_process_thread(void *data) { int error; struct r592_device *dev = (struct r592_device *)data; unsigned long flags; while (!kthread_should_stop()) { spin_lock_irqsave(&dev->io_thread_lock, flags); set_current_state(TASK_INTERRUPTIBLE); error = memstick_next_req(dev->host, &dev->req); spin_unlock_irqrestore(&dev->io_thread_lock, flags); if (error) { if (error == -ENXIO || error == -EAGAIN) { dbg_verbose("IO: done IO, sleeping"); } else { dbg("IO: unknown error from " "memstick_next_req %d", error); } if (kthread_should_stop()) set_current_state(TASK_RUNNING); schedule(); } else { set_current_state(TASK_RUNNING); r592_execute_tpc(dev); } } return 0; }
static void rtsx_pci_ms_handle_req(struct work_struct *work) { struct realtek_pci_ms *host = container_of(work, struct realtek_pci_ms, handle_req); struct rtsx_pcr *pcr = host->pcr; struct memstick_host *msh = host->msh; int rc; mutex_lock(&pcr->pcr_mutex); rtsx_pci_start_run(pcr); rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth, false, true, false); rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL); rtsx_pci_write_register(pcr, CARD_SHARE_MODE, CARD_SHARE_MASK, CARD_SHARE_48_MS); if (!host->req) { do { rc = memstick_next_req(msh, &host->req); dev_dbg(ms_dev(host), "next req %d\n", rc); if (!rc) host->req->error = rtsx_pci_ms_issue_cmd(host); } while (!rc); } mutex_unlock(&pcr->pcr_mutex); }
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; }