/* Release all our dynamic resources */ static void rtsx_release_resources(struct rtsx_dev *dev) { dev_info(&dev->pci->dev, "-- %s\n", __func__); /* Tell the control thread to exit. The SCSI host must * already have been removed so it won't try to queue * any more commands. */ dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); complete(&dev->cmnd_ready); if (dev->ctl_thread) wait_for_completion(&dev->control_exit); if (dev->polling_thread) wait_for_completion(&dev->polling_exit); wait_timeout(200); if (dev->rtsx_resv_buf) { dev->chip->host_cmds_ptr = NULL; dev->chip->host_sg_tbl_ptr = NULL; } if (dev->irq > 0) free_irq(dev->irq, (void *)dev); if (dev->chip->msi_en) pci_disable_msi(dev->pci); if (dev->remap_addr) iounmap(dev->remap_addr); rtsx_release_chip(dev->chip); kfree(dev->chip); }
int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt) { int retval; unsigned int lun = SCSI_LUN(srb); int i; if (chip->rw_card[lun] == NULL) TRACE_RET(chip, STATUS_FAIL); for (i = 0; i < 3; i++) { chip->rw_need_retry = 0; retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); if (retval != STATUS_SUCCESS) { if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { rtsx_release_chip(chip); TRACE_RET(chip, STATUS_FAIL); } if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); if (!chip->rw_need_retry) { RTSX_DEBUGP("RW fail, but no need to retry\n"); break; } } else { chip->rw_need_retry = 0; break; } RTSX_DEBUGP("Retry RW, (i = %d)\n", i); } return retval; }
static int rtsx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { struct Scsi_Host *host; struct rtsx_dev *dev; int err = 0; struct task_struct *th; dev_dbg(&pci->dev, "Realtek PCI-E card reader detected\n"); err = pcim_enable_device(pci); if (err < 0) { dev_err(&pci->dev, "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { dev_err(&pci->dev, "PCI request regions for %s failed!\n", CR_DRIVER_NAME); return err; } /* * Ask the SCSI layer to allocate a host structure, with extra * space at the end for our private rtsx_dev structure. */ host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); if (!host) { dev_err(&pci->dev, "Unable to allocate the scsi host\n"); return -ENOMEM; } dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); dev->chip = kzalloc(sizeof(*dev->chip), GFP_KERNEL); if (!dev->chip) { err = -ENOMEM; goto chip_alloc_fail; } spin_lock_init(&dev->reg_lock); mutex_init(&dev->dev_mutex); init_completion(&dev->cmnd_ready); init_completion(&dev->control_exit); init_completion(&dev->polling_exit); init_completion(&dev->notify); init_completion(&dev->scanning_done); init_waitqueue_head(&dev->delay_wait); dev->pci = pci; dev->irq = -1; dev_info(&pci->dev, "Resource length: 0x%x\n", (unsigned int)pci_resource_len(pci, 0)); dev->addr = pci_resource_start(pci, 0); dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); if (!dev->remap_addr) { dev_err(&pci->dev, "ioremap error\n"); err = -ENXIO; goto ioremap_fail; } /* * Using "unsigned long" cast here to eliminate gcc warning in * 64-bit system */ dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dmam_alloc_coherent(&pci->dev, RTSX_RESV_BUF_LEN, &dev->rtsx_resv_buf_addr, GFP_KERNEL); if (!dev->rtsx_resv_buf) { dev_err(&pci->dev, "alloc dma buffer fail\n"); err = -ENXIO; goto dma_alloc_fail; } dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; dev->chip->rtsx = dev; rtsx_init_options(dev->chip); dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); if (dev->chip->msi_en) { if (pci_enable_msi(pci) < 0) dev->chip->msi_en = 0; } if (rtsx_acquire_irq(dev) < 0) { err = -EBUSY; goto irq_acquire_fail; } pci_set_master(pci); synchronize_irq(dev->irq); rtsx_init_chip(dev->chip); /* * set the supported max_lun and max_id for the scsi host * NOTE: the minimal value of max_id is 1 */ host->max_id = 1; host->max_lun = dev->chip->max_lun; /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start control thread\n"); err = PTR_ERR(th); goto control_thread_fail; } dev->ctl_thread = th; err = scsi_add_host(host, &pci->dev); if (err) { dev_err(&pci->dev, "Unable to add the scsi host\n"); goto scsi_add_host_fail; } /* Start up the thread for delayed SCSI-device scanning */ th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); complete(&dev->scanning_done); err = PTR_ERR(th); goto scan_thread_fail; } /* Start up the thread for polling thread */ th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { dev_err(&pci->dev, "Unable to start the device-polling thread\n"); err = PTR_ERR(th); goto scan_thread_fail; } dev->polling_thread = th; pci_set_drvdata(pci, dev); return 0; /* We come here if there are any problems */ scan_thread_fail: quiesce_and_remove_host(dev); scsi_add_host_fail: complete(&dev->cmnd_ready); wait_for_completion(&dev->control_exit); control_thread_fail: free_irq(dev->irq, (void *)dev); rtsx_release_chip(dev->chip); irq_acquire_fail: dev->chip->host_cmds_ptr = NULL; dev->chip->host_sg_tbl_ptr = NULL; if (dev->chip->msi_en) pci_disable_msi(dev->pci); dma_alloc_fail: iounmap(dev->remap_addr); ioremap_fail: kfree(dev->chip); chip_alloc_fail: dev_err(&pci->dev, "%s failed\n", __func__); return err; }