const char *esas2r_info(struct Scsi_Host *sh) { struct esas2r_adapter *a = (struct esas2r_adapter *)sh->hostdata; static char esas2r_info_str[512]; esas2r_log_dev(ESAS2R_LOG_INFO, &(sh->shost_gendev), "esas2r_info() called"); /* * if we haven't done so already, register as a char driver * and stick a node under "/proc/scsi/esas2r/ATTOnode" */ if (esas2r_proc_major <= 0) { esas2r_proc_host = sh; esas2r_proc_major = register_chrdev(0, ESAS2R_DRVR_NAME, &esas2r_proc_fops); esas2r_log_dev(ESAS2R_LOG_DEBG, &(sh->shost_gendev), "register_chrdev (major %d)", esas2r_proc_major); if (esas2r_proc_major > 0) { struct proc_dir_entry *pde; pde = proc_create(ATTONODE_NAME, 0, sh->hostt->proc_dir, &esas2r_proc_fops); if (!pde) { esas2r_log_dev(ESAS2R_LOG_WARN, &(sh->shost_gendev), "failed to create_proc_entry"); esas2r_proc_major = -1; } } } sprintf(esas2r_info_str, ESAS2R_LONGNAME " (bus 0x%02X, device 0x%02X, IRQ 0x%02X)" " driver version: "ESAS2R_VERSION_STR " firmware version: " "%s\n", a->pcid->bus->number, a->pcid->devfn, a->pcid->irq, a->fw_rev[0] ? a->fw_rev : "(none)"); return esas2r_info_str; }
int esas2r_release(struct Scsi_Host *sh) { esas2r_log_dev(ESAS2R_LOG_INFO, &(sh->shost_gendev), "esas2r_release() called"); esas2r_cleanup(sh); if (sh->irq) free_irq(sh->irq, NULL); scsi_unregister(sh); return 0; }
static void esas2r_remove(struct pci_dev *pdev) { struct Scsi_Host *host; int index; if (pdev == NULL) { esas2r_log(ESAS2R_LOG_WARN, "esas2r_remove pdev==NULL"); return; } host = pci_get_drvdata(pdev); if (host == NULL) { /* * this can happen if pci_set_drvdata was already called * to clear the host pointer. if this is the case, we * are okay; this channel has already been cleaned up. */ return; } esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), "esas2r_remove(%p) called; " "host:%p", pdev, host); index = esas2r_cleanup(host); if (index < 0) esas2r_log_dev(ESAS2R_LOG_WARN, &(pdev->dev), "unknown host in %s", __func__); found_adapters--; /* if this was the last adapter, clean up the rest of the driver */ if (found_adapters == 0) esas2r_cleanup(NULL); }
static void esas2r_remove(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata; esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), "esas2r_remove(%p) called; " "host:%p", pdev, host); esas2r_kill_adapter(a->index); found_adapters--; }
/** * Searches the specified queue for the specified queue for the command * to abort. * * @param [in] a * @param [in] abort_request * @param [in] cmd * t * @return 0 on failure, 1 if command was not found, 2 if command was found */ static int esas2r_check_active_queue(struct esas2r_adapter *a, struct esas2r_request **abort_request, struct scsi_cmnd *cmd, struct list_head *queue) { bool found = false; struct esas2r_request *ar = *abort_request; struct esas2r_request *rq; struct list_head *element, *next; list_for_each_safe(element, next, queue) { rq = list_entry(element, struct esas2r_request, req_list); if (rq->cmd == cmd) { /* Found the request. See what to do with it. */ if (queue == &a->active_list) { /* * We are searching the active queue, which * means that we need to send an abort request * to the firmware. */ ar = esas2r_alloc_request(a); if (ar == NULL) { esas2r_log_dev(ESAS2R_LOG_WARN, &(a->host->shost_gendev), "unable to allocate an abort request for cmd %p", cmd); return 0; /* Failure */ } /* * Task management request must be formatted * with a lock held. */ ar->sense_len = 0; ar->vrq->scsi.length = 0; ar->target_id = rq->target_id; ar->vrq->scsi.flags |= cpu_to_le32( (u8)le32_to_cpu(rq->vrq->scsi.flags)); memset(ar->vrq->scsi.cdb, 0, sizeof(ar->vrq->scsi.cdb)); ar->vrq->scsi.flags |= cpu_to_le32( FCP_CMND_TRM); ar->vrq->scsi.u.abort_handle = rq->vrq->scsi.handle; } else { /* * The request is pending but not active on * the firmware. Just free it now and we'll * report the successful abort below. */ list_del_init(&rq->req_list); esas2r_free_request(a, rq); } found = true; break; } }
static int esas2r_probe(struct pci_dev *pcid, const struct pci_device_id *id) { struct Scsi_Host *host = NULL; struct esas2r_adapter *a; int err; size_t host_alloc_size = sizeof(struct esas2r_adapter) + ((num_requests) + 1) * sizeof(struct esas2r_request); esas2r_log_dev(ESAS2R_LOG_DEBG, &(pcid->dev), "esas2r_probe() 0x%02x 0x%02x 0x%02x 0x%02x", pcid->vendor, pcid->device, pcid->subsystem_vendor, pcid->subsystem_device); esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev), "before pci_enable_device() " "enable_cnt: %d", pcid->enable_cnt.counter); err = pci_enable_device(pcid); if (err != 0) { esas2r_log_dev(ESAS2R_LOG_CRIT, &(pcid->dev), "pci_enable_device() FAIL (%d)", err); return -ENODEV; } esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev), "pci_enable_device() OK"); esas2r_log_dev(ESAS2R_LOG_INFO, &(pcid->dev), "after pci_enable_device() enable_cnt: %d", pcid->enable_cnt.counter); host = scsi_host_alloc(&driver_template, host_alloc_size); if (host == NULL) { esas2r_log(ESAS2R_LOG_CRIT, "scsi_host_alloc() FAIL"); return -ENODEV; } memset(host->hostdata, 0, host_alloc_size); a = (struct esas2r_adapter *)host->hostdata; esas2r_log(ESAS2R_LOG_INFO, "scsi_host_alloc() OK host: %p", host); /* override max LUN and max target id */ host->max_id = ESAS2R_MAX_ID + 1; host->max_lun = 255; /* we can handle 16-byte CDbs */ host->max_cmd_len = 16; host->can_queue = can_queue; host->cmd_per_lun = cmd_per_lun; host->this_id = host->max_id + 1; host->max_channel = 0; host->unique_id = found_adapters; host->sg_tablesize = sg_tablesize; host->max_sectors = esas2r_max_sectors; /* set to bus master for BIOses that don't do it for us */ esas2r_log(ESAS2R_LOG_INFO, "pci_set_master() called"); pci_set_master(pcid); if (!esas2r_init_adapter(host, pcid, found_adapters)) { esas2r_log(ESAS2R_LOG_CRIT, "unable to initialize device at PCI bus %x:%x", pcid->bus->number, pcid->devfn); esas2r_log_dev(ESAS2R_LOG_INFO, &(host->shost_gendev), "scsi_host_put() called"); scsi_host_put(host); return 0; } esas2r_log(ESAS2R_LOG_INFO, "pci_set_drvdata(%p, %p) called", pcid, host->hostdata); pci_set_drvdata(pcid, host); esas2r_log(ESAS2R_LOG_INFO, "scsi_add_host() called"); err = scsi_add_host(host, &pcid->dev); if (err) { esas2r_log(ESAS2R_LOG_CRIT, "scsi_add_host returned %d", err); esas2r_log_dev(ESAS2R_LOG_CRIT, &(host->shost_gendev), "scsi_add_host() FAIL"); esas2r_log_dev(ESAS2R_LOG_INFO, &(host->shost_gendev), "scsi_host_put() called"); scsi_host_put(host); esas2r_log_dev(ESAS2R_LOG_INFO, &(host->shost_gendev), "pci_set_drvdata(%p, NULL) called", pcid); pci_set_drvdata(pcid, NULL); return -ENODEV; } esas2r_fw_event_on(a); esas2r_log_dev(ESAS2R_LOG_INFO, &(host->shost_gendev), "scsi_scan_host() called"); scsi_scan_host(host); /* Add sysfs binary files */ if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_fw)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: fw"); else a->sysfs_fw_created = 1; if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_fs)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: fs"); else a->sysfs_fs_created = 1; if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_vda)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: vda"); else a->sysfs_vda_created = 1; if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_hw)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: hw"); else a->sysfs_hw_created = 1; if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_live_nvram)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: live_nvram"); else a->sysfs_live_nvram_created = 1; if (sysfs_create_bin_file(&host->shost_dev.kobj, &bin_attr_default_nvram)) esas2r_log_dev(ESAS2R_LOG_WARN, &(host->shost_gendev), "Failed to create sysfs binary file: default_nvram"); else a->sysfs_default_nvram_created = 1; found_adapters++; return 0; }