/* This is always called with scsi_lock(host) held */ static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *)) { struct rtsx_dev *dev = host_to_rtsx(srb->device->host); struct rtsx_chip *chip = dev->chip; /* check for state-transition errors */ if (chip->srb) { dev_err(&dev->pci->dev, "Error: chip->srb = %p\n", chip->srb); return SCSI_MLQUEUE_HOST_BUSY; } /* fail the command if we are disconnecting */ if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { dev_info(&dev->pci->dev, "Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); return 0; } /* enqueue the command and wake up the control thread */ srb->scsi_done = done; chip->srb = srb; complete(&dev->cmnd_ready); return 0; }
/* Command timeout and abort */ static int command_abort(struct scsi_cmnd *srb) { struct Scsi_Host *host = srb->device->host; struct rtsx_dev *dev = host_to_rtsx(host); struct rtsx_chip *chip = dev->chip; dev_info(&dev->pci->dev, "%s called\n", __func__); scsi_lock(host); /* Is this command still active? */ if (chip->srb != srb) { scsi_unlock(host); dev_info(&dev->pci->dev, "-- nothing to abort\n"); return FAILED; } rtsx_set_stat(chip, RTSX_STAT_ABORT); scsi_unlock(host); /* Wait for the aborted command to finish */ wait_for_completion(&dev->notify); return SUCCESS; }
static int command_abort(struct scsi_cmnd *srb) { struct Scsi_Host *host = srb->device->host; struct rtsx_dev *dev = host_to_rtsx(host); struct rtsx_chip *chip = dev->chip; printk(KERN_INFO "%s called\n", __FUNCTION__); scsi_lock(host); if (chip->srb != srb) { scsi_unlock(host); printk(KERN_INFO "-- nothing to abort\n"); return FAILED; } rtsx_set_stat(chip, RTSX_STAT_ABORT); scsi_unlock(host); wait_for_completion(&dev->notify); return SUCCESS; }
static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *)) { struct rtsx_dev *dev = host_to_rtsx(srb->device->host); struct rtsx_chip *chip = dev->chip; if (chip->srb != NULL) { printk(KERN_ERR "Error in %s: chip->srb = %p\n", __FUNCTION__, chip->srb); return SCSI_MLQUEUE_HOST_BUSY; } if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { printk(KERN_INFO "Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); return 0; } srb->scsi_done = done; chip->srb = srb; up(&(dev->sema)); return 0; }
/* This is always called with scsi_lock(host) held */ static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *)) { struct rtsx_dev *dev = host_to_rtsx(srb->device->host); struct rtsx_chip *chip = dev->chip; /* check for state-transition errors */ if (chip->srb != NULL) { printk(KERN_ERR "Error in %s: chip->srb = %p\n", __func__, chip->srb); return SCSI_MLQUEUE_HOST_BUSY; } /* fail the command if we are disconnecting */ if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { printk(KERN_INFO "Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); return 0; } /* enqueue the command and wake up the control thread */ srb->scsi_done = done; chip->srb = srb; up(&(dev->sema)); return 0; }
/* * This invokes the transport reset mechanism to reset the state of the * device */ static int device_reset(struct scsi_cmnd *srb) { struct rtsx_dev *dev = host_to_rtsx(srb->device->host); dev_info(&dev->pci->dev, "%s called\n", __func__); return SUCCESS; }
/* Simulate a SCSI bus reset by resetting the device's USB port. */ static int bus_reset(struct scsi_cmnd *srb) { int result = 0; struct rtsx_dev *dev = host_to_rtsx(srb->device->host); dev_info(&dev->pci->dev, "%s called\n", __func__); return result < 0 ? FAILED : SUCCESS; }
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(struct rtsx_chip), GFP_KERNEL); if (!dev->chip) { err = -ENOMEM; goto errout; } 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 errout; } /* * 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 errout; } 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 errout; } 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 errout; } 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 errout; } /* 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); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* 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"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } dev->polling_thread = th; pci_set_drvdata(pci, dev); return 0; /* We come here if there are any problems */ errout: dev_err(&pci->dev, "rtsx_probe() failed\n"); release_everything(dev); return err; }
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; printk(KERN_INFO "--- %s ---\n", DRIVER_MAKE_TIME); err = pci_enable_device(pci); if (err < 0) { printk(KERN_ERR "PCI enable device failed!\n"); return err; } err = pci_request_regions(pci, CR_DRIVER_NAME); if (err < 0) { printk(KERN_ERR "PCI request regions for %s failed!\n", CR_DRIVER_NAME); pci_disable_device(pci); 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) { printk(KERN_ERR "Unable to allocate the scsi host\n"); pci_release_regions(pci); pci_disable_device(pci); return -ENOMEM; } dev = host_to_rtsx(host); memset(dev, 0, sizeof(struct rtsx_dev)); dev->chip = (struct rtsx_chip *)kmalloc(sizeof(struct rtsx_chip), GFP_KERNEL); if (dev->chip == NULL) { goto errout; } memset(dev->chip, 0, sizeof(struct rtsx_chip)); spin_lock_init(&dev->reg_lock); mutex_init(&(dev->dev_mutex)); sema_init(&(dev->sema), 0); init_completion(&(dev->notify)); init_waitqueue_head(&dev->delay_wait); dev->pci = pci; dev->irq = -1; printk(KERN_INFO "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 == NULL) { printk(KERN_ERR "ioremap error\n"); err = -ENXIO; goto errout; } printk(KERN_INFO "Original address: 0x%lx, remapped address: 0x%lx\n", (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, &(dev->rtsx_resv_buf_addr), GFP_KERNEL); if (dev->rtsx_resv_buf == NULL) { printk(KERN_ERR "alloc dma buffer fail\n"); err = -ENXIO; goto errout; } 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); printk(KERN_INFO "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 errout; } pci_set_master(pci); synchronize_irq(dev->irq); err = scsi_add_host(host, &pci->dev); if (err) { printk(KERN_ERR "Unable to add the scsi host\n"); goto errout; } rtsx_init_chip(dev->chip); th = kthread_create(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start control thread\n"); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the control thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the scanning thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); th = kthread_create(rtsx_polling_thread, dev, "rtsx-polling"); if (IS_ERR(th)) { printk(KERN_ERR "Unable to start the device-polling thread\n"); quiesce_and_remove_host(dev); err = PTR_ERR(th); goto errout; } /* Take a reference to the host for the polling thread and * count it among all the threads we have launched. Then * start it up. */ scsi_host_get(rtsx_to_host(dev)); atomic_inc(&total_threads); wake_up_process(th); pci_set_drvdata(pci, dev); return 0; errout: printk(KERN_ERR "rtsx_probe() failed\n"); release_everything(dev); return err; }