📄 linit.c
字号:
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128); else scsi_adjust_queue_depth(sdev, 0, 1); return 0;}static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg){ struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata; return aac_do_ioctl(dev, cmd, arg);}/* * XXX: does aac really need no error handling?? */static int aac_eh_abort(struct scsi_cmnd *cmd){ return FAILED;}/* * aac_eh_reset - Reset command handling * @scsi_cmd: SCSI command block causing the reset * */static int aac_eh_reset(struct scsi_cmnd* cmd){ struct scsi_device * dev = cmd->device; struct Scsi_Host * host = dev->host; struct scsi_cmnd * command; int count; struct aac_dev * aac; unsigned long flags; printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); aac = (struct aac_dev *)host->hostdata; if (aac_adapter_check_health(aac)) { printk(KERN_ERR "%s: Host adapter appears dead\n", AAC_DRIVERNAME); return -ENODEV; } /* * Wait for all commands to complete to this specific * target (block maximum 60 seconds). */ for (count = 60; count; --count) { int active = 0; __shost_for_each_device(dev, host) { spin_lock_irqsave(&dev->list_lock, flags); list_for_each_entry(command, &dev->cmd_list, list) { if (command->serial_number) { active++; break; } } spin_unlock_irqrestore(&dev->list_lock, flags); if (active) break; } /* * We can exit If all the commands are complete */ if (active == 0) return SUCCESS; spin_unlock_irq(host->host_lock); ssleep(1); spin_lock_irq(host->host_lock); } printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); return -ETIMEDOUT;}/** * aac_cfg_open - open a configuration file * @inode: inode being opened * @file: file handle attached * * Called when the configuration device is opened. Does the needed * set up on the handle and then returns * * Bugs: This needs extending to check a given adapter is present * so we can support hot plugging, and to ref count adapters. */static int aac_cfg_open(struct inode *inode, struct file *file){ struct aac_dev *aac; unsigned minor = iminor(inode); int err = -ENODEV; list_for_each_entry(aac, &aac_devices, entry) { if (aac->id == minor) { file->private_data = aac; err = 0; break; } } return 0;}/** * aac_cfg_ioctl - AAC configuration request * @inode: inode of device * @file: file handle * @cmd: ioctl command code * @arg: argument * * Handles a configuration ioctl. Currently this involves wrapping it * up and feeding it into the nasty windowsalike glue layer. * * Bugs: Needs locking against parallel ioctls lower down * Bugs: Needs to handle hot plugging */ static int aac_cfg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ return aac_do_ioctl(file->private_data, cmd, (void __user *)arg);}static struct file_operations aac_cfg_fops = { .owner = THIS_MODULE, .ioctl = aac_cfg_ioctl, .open = aac_cfg_open,};static struct scsi_host_template aac_driver_template = { .module = THIS_MODULE, .name = "AAC", .proc_name = "aacraid", .info = aac_info, .ioctl = aac_ioctl, .queuecommand = aac_queuecommand, .bios_param = aac_biosparm, .slave_configure = aac_slave_configure, .eh_abort_handler = aac_eh_abort, .eh_host_reset_handler = aac_eh_reset, .can_queue = AAC_NUM_IO_FIB, .this_id = 16, .sg_tablesize = 16, .max_sectors = 128,#if (AAC_NUM_IO_FIB > 256) .cmd_per_lun = 256,#else .cmd_per_lun = AAC_NUM_IO_FIB, #endif .use_clustering = ENABLE_CLUSTERING,};static int __devinit aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id){ unsigned index = id->driver_data; struct Scsi_Host *shost; struct aac_dev *aac; struct list_head *insert = &aac_devices; int error = -ENODEV; int unique_id = 0; list_for_each_entry(aac, &aac_devices, entry) { if (aac->id > unique_id) { insert = &aac->entry; break; } unique_id++; } if (pci_enable_device(pdev)) goto out; if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL) || pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL)) goto out; /* * If the quirk31 bit is set, the adapter needs adapter * to driver communication memory to be allocated below 2gig */ if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) if (pci_set_dma_mask(pdev, 0x7FFFFFFFULL) || pci_set_consistent_dma_mask(pdev, 0x7FFFFFFFULL)) goto out; pci_set_master(pdev); shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev)); if (!shost) goto out_disable_pdev; shost->irq = pdev->irq; shost->base = pci_resource_start(pdev, 0); shost->unique_id = unique_id; aac = (struct aac_dev *)shost->hostdata; aac->scsi_host_ptr = shost; aac->pdev = pdev; aac->name = aac_driver_template.name; aac->id = shost->unique_id; aac->cardtype = index; INIT_LIST_HEAD(&aac->entry); aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL); if (!aac->fibs) goto out_free_host; spin_lock_init(&aac->fib_lock); if ((*aac_drivers[index].init)(aac)) goto out_free_fibs; /* * If we had set a smaller DMA mask earlier, set it to 4gig * now since the adapter can dma data to at least a 4gig * address space. */ if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL)) goto out_free_fibs; aac_get_adapter_info(aac); /* * max channel will be the physical channels plus 1 virtual channel * all containers are on the virtual channel 0 * physical channels are address by their actual physical number+1 */ if (aac->nondasd_support == 1) shost->max_channel = aac_drivers[index].channels+1; else shost->max_channel = 1; aac_get_config_status(aac); aac_get_containers(aac); list_add(&aac->entry, insert); shost->max_id = aac->maximum_num_containers; if (shost->max_id < MAXIMUM_NUM_CONTAINERS) shost->max_id = MAXIMUM_NUM_CONTAINERS; else shost->this_id = shost->max_id; /* * dmb - we may need to move the setting of these parms somewhere else once * we get a fib that can report the actual numbers */ shost->max_lun = AAC_MAX_LUN; pci_set_drvdata(pdev, shost); error = scsi_add_host(shost, &pdev->dev); if (error) goto out_deinit; scsi_scan_host(shost); return 0;out_deinit: kill_proc(aac->thread_pid, SIGKILL, 0); wait_for_completion(&aac->aif_completion); aac_send_shutdown(aac); fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); free_irq(pdev->irq, aac); iounmap(aac->regs.sa); out_free_fibs: kfree(aac->fibs); kfree(aac->fsa_dev); out_free_host: scsi_host_put(shost); out_disable_pdev: pci_disable_device(pdev); out: return error;}static void __devexit aac_remove_one(struct pci_dev *pdev){ struct Scsi_Host *shost = pci_get_drvdata(pdev); struct aac_dev *aac = (struct aac_dev *)shost->hostdata; scsi_remove_host(shost); kill_proc(aac->thread_pid, SIGKILL, 0); wait_for_completion(&aac->aif_completion); aac_send_shutdown(aac); fib_map_free(aac); pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys); kfree(aac->queues); free_irq(pdev->irq, aac); iounmap(aac->regs.sa); kfree(aac->fibs); list_del(&aac->entry); scsi_host_put(shost); pci_disable_device(pdev);}static struct pci_driver aac_pci_driver = { .name = AAC_DRIVERNAME, .id_table = aac_pci_tbl, .probe = aac_probe_one, .remove = __devexit_p(aac_remove_one),};static int __init aac_init(void){ int error; printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE); error = pci_module_init(&aac_pci_driver); if (error) return error; aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops); if (aac_cfg_major < 0) { printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n"); }#ifdef CONFIG_COMPAT register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL); register_ioctl32_conversion(FSACTL_SENDFIB, NULL); register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL); register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, aac_get_next_adapter_fib_ioctl); register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL); register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL); register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL); register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL); register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL); register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL); register_ioctl32_conversion(FSACTL_GET_CONTAINERS, NULL);#endif return 0;}static void __exit aac_exit(void){#ifdef CONFIG_COMPAT unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK); unregister_ioctl32_conversion(FSACTL_SENDFIB); unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB); unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB); unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB); unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB); unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO); unregister_ioctl32_conversion(FSACTL_QUERY_DISK); unregister_ioctl32_conversion(FSACTL_DELETE_DISK); unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK); unregister_ioctl32_conversion(FSACTL_GET_CONTAINERS);#endif unregister_chrdev(aac_cfg_major, "aac"); pci_unregister_driver(&aac_pci_driver);}module_init(aac_init);module_exit(aac_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -