⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ibmvscsi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
			       "ibmvscsi: partner initialization complete\n");			/* Now login */			send_srp_login(hostdata);			break;		default:			printk(KERN_ERR "ibmvscsi: unknown crq message type\n");		}		return;	case 0xFF:		/* Hypervisor telling us the connection is closed */		printk(KERN_INFO "ibmvscsi: Virtual adapter failed!\n");		atomic_set(&hostdata->request_limit, -1);		purge_requests(hostdata);		ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata);		return;	case 0x80:		/* real payload */		break;	default:		printk(KERN_ERR		       "ibmvscsi: got an invalid message type 0x%02x\n",		       crq->valid);		return;	}	/* The only kind of payload CRQs we should get are responses to	 * things we send. Make sure this response is to something we	 * actually sent	 */	if (!valid_event_struct(&hostdata->pool, evt_struct)) {		printk(KERN_ERR		       "ibmvscsi: returned correlation_token 0x%p is invalid!\n",		       (void *)crq->IU_data_ptr);		return;	}	if (atomic_read(&evt_struct->free)) {		printk(KERN_ERR		       "ibmvscsi: received duplicate  correlation_token 0x%p!\n",		       (void *)crq->IU_data_ptr);		return;	}	if (crq->format == VIOSRP_SRP_FORMAT)		atomic_add(evt_struct->xfer_iu->srp.rsp.request_limit_delta,			   &hostdata->request_limit);	if (evt_struct->done)		evt_struct->done(evt_struct);	else		printk(KERN_ERR		       "ibmvscsi: returned done() is NULL; not running it!\n");	/*	 * Lock the host_lock before messing with these structures, since we	 * are running in a task context	 */	spin_lock_irqsave(evt_struct->hostdata->host->host_lock, flags);	list_del(&evt_struct->list);	free_event_struct(&evt_struct->hostdata->pool, evt_struct);	spin_unlock_irqrestore(evt_struct->hostdata->host->host_lock, flags);}/** * ibmvscsi_get_host_config: Send the command to the server to get host * configuration data.  The data is opaque to us. */static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,				   unsigned char *buffer, int length){	struct viosrp_host_config *host_config;	struct srp_event_struct *evt_struct;	int rc;	evt_struct = get_event_struct(&hostdata->pool);	if (!evt_struct) {		printk(KERN_ERR		       "ibmvscsi: could't allocate event for HOST_CONFIG!\n");		return -1;	}	init_event_struct(evt_struct,			  sync_completion,			  VIOSRP_MAD_FORMAT,			  init_timeout * HZ);	host_config = &evt_struct->iu.mad.host_config;	/* Set up a lun reset SRP command */	memset(host_config, 0x00, sizeof(*host_config));	host_config->common.type = VIOSRP_HOST_CONFIG_TYPE;	host_config->common.length = length;	host_config->buffer = dma_map_single(hostdata->dev, buffer, length,					    DMA_BIDIRECTIONAL);	if (dma_mapping_error(host_config->buffer)) {		printk(KERN_ERR		       "ibmvscsi: dma_mapping error " "getting host config\n");		free_event_struct(&hostdata->pool, evt_struct);		return -1;	}	init_completion(&evt_struct->comp);	rc = ibmvscsi_send_srp_event(evt_struct, hostdata);	if (rc == 0) {		wait_for_completion(&evt_struct->comp);		dma_unmap_single(hostdata->dev, host_config->buffer,				 length, DMA_BIDIRECTIONAL);	}	return rc;}/* ------------------------------------------------------------ * sysfs attributes */static ssize_t show_host_srp_version(struct class_device *class_dev, char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	int len;	len = snprintf(buf, PAGE_SIZE, "%s\n",		       hostdata->madapter_info.srp_version);	return len;}static struct class_device_attribute ibmvscsi_host_srp_version = {	.attr = {		 .name = "srp_version",		 .mode = S_IRUGO,		 },	.show = show_host_srp_version,};static ssize_t show_host_partition_name(struct class_device *class_dev,					char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	int len;	len = snprintf(buf, PAGE_SIZE, "%s\n",		       hostdata->madapter_info.partition_name);	return len;}static struct class_device_attribute ibmvscsi_host_partition_name = {	.attr = {		 .name = "partition_name",		 .mode = S_IRUGO,		 },	.show = show_host_partition_name,};static ssize_t show_host_partition_number(struct class_device *class_dev,					  char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	int len;	len = snprintf(buf, PAGE_SIZE, "%d\n",		       hostdata->madapter_info.partition_number);	return len;}static struct class_device_attribute ibmvscsi_host_partition_number = {	.attr = {		 .name = "partition_number",		 .mode = S_IRUGO,		 },	.show = show_host_partition_number,};static ssize_t show_host_mad_version(struct class_device *class_dev, char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	int len;	len = snprintf(buf, PAGE_SIZE, "%d\n",		       hostdata->madapter_info.mad_version);	return len;}static struct class_device_attribute ibmvscsi_host_mad_version = {	.attr = {		 .name = "mad_version",		 .mode = S_IRUGO,		 },	.show = show_host_mad_version,};static ssize_t show_host_os_type(struct class_device *class_dev, char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	int len;	len = snprintf(buf, PAGE_SIZE, "%d\n", hostdata->madapter_info.os_type);	return len;}static struct class_device_attribute ibmvscsi_host_os_type = {	.attr = {		 .name = "os_type",		 .mode = S_IRUGO,		 },	.show = show_host_os_type,};static ssize_t show_host_config(struct class_device *class_dev, char *buf){	struct Scsi_Host *shost = class_to_shost(class_dev);	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)shost->hostdata;	/* returns null-terminated host config data */	if (ibmvscsi_do_host_config(hostdata, buf, PAGE_SIZE) == 0)		return strlen(buf);	else		return 0;}static struct class_device_attribute ibmvscsi_host_config = {	.attr = {		 .name = "config",		 .mode = S_IRUGO,		 },	.show = show_host_config,};static struct class_device_attribute *ibmvscsi_attrs[] = {	&ibmvscsi_host_srp_version,	&ibmvscsi_host_partition_name,	&ibmvscsi_host_partition_number,	&ibmvscsi_host_mad_version,	&ibmvscsi_host_os_type,	&ibmvscsi_host_config,	NULL};/* ------------------------------------------------------------ * SCSI driver registration */static struct scsi_host_template driver_template = {	.module = THIS_MODULE,	.name = "IBM POWER Virtual SCSI Adapter " IBMVSCSI_VERSION,	.proc_name = "ibmvscsi",	.queuecommand = ibmvscsi_queuecommand,	.eh_abort_handler = ibmvscsi_eh_abort_handler,	.eh_device_reset_handler = ibmvscsi_eh_device_reset_handler,	.cmd_per_lun = 16,	.can_queue = 1,		/* Updated after SRP_LOGIN */	.this_id = -1,	.sg_tablesize = SG_ALL,	.use_clustering = ENABLE_CLUSTERING,	.shost_attrs = ibmvscsi_attrs,};/** * Called by bus code for each adapter */static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id){	struct ibmvscsi_host_data *hostdata;	struct Scsi_Host *host;	struct device *dev = &vdev->dev;	unsigned long wait_switch = 0;	vdev->dev.driver_data = NULL;	host = scsi_host_alloc(&driver_template, sizeof(*hostdata));	if (!host) {		printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n");		goto scsi_host_alloc_failed;	}	hostdata = (struct ibmvscsi_host_data *)host->hostdata;	memset(hostdata, 0x00, sizeof(*hostdata));	INIT_LIST_HEAD(&hostdata->sent);	hostdata->host = host;	hostdata->dev = dev;	atomic_set(&hostdata->request_limit, -1);	hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */	if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata,				    max_requests) != 0) {		printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n");		goto init_crq_failed;	}	if (initialize_event_pool(&hostdata->pool, max_requests, hostdata) != 0) {		printk(KERN_ERR "ibmvscsi: couldn't initialize event pool\n");		goto init_pool_failed;	}	host->max_lun = 8;	host->max_id = max_id;	host->max_channel = max_channel;	if (scsi_add_host(hostdata->host, hostdata->dev))		goto add_host_failed;	/* Try to send an initialization message.  Note that this is allowed	 * to fail if the other end is not acive.  In that case we don't	 * want to scan	 */	if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0) {		/*		 * Wait around max init_timeout secs for the adapter to finish		 * initializing. When we are done initializing, we will have a		 * valid request_limit.  We don't want Linux scanning before		 * we are ready.		 */		for (wait_switch = jiffies + (init_timeout * HZ);		     time_before(jiffies, wait_switch) &&		     atomic_read(&hostdata->request_limit) < 2;) {			msleep(10);		}		/* if we now have a valid request_limit, initiate a scan */		if (atomic_read(&hostdata->request_limit) > 0)			scsi_scan_host(host);	}	vdev->dev.driver_data = hostdata;	return 0;      add_host_failed:	release_event_pool(&hostdata->pool, hostdata);      init_pool_failed:	ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests);      init_crq_failed:	scsi_host_put(host);      scsi_host_alloc_failed:	return -1;}static int ibmvscsi_remove(struct vio_dev *vdev){	struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data;	release_event_pool(&hostdata->pool, hostdata);	ibmvscsi_release_crq_queue(&hostdata->queue, hostdata,				   max_requests);		scsi_remove_host(hostdata->host);	scsi_host_put(hostdata->host);	return 0;}/** * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we  * support. */static struct vio_device_id ibmvscsi_device_table[] __devinitdata = {	{"vscsi", "IBM,v-scsi"},	{ "", "" }};MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table);static struct vio_driver ibmvscsi_driver = {	.id_table = ibmvscsi_device_table,	.probe = ibmvscsi_probe,	.remove = ibmvscsi_remove,	.driver = {		.name = "ibmvscsi",		.owner = THIS_MODULE,	}};int __init ibmvscsi_module_init(void){	return vio_register_driver(&ibmvscsi_driver);}void __exit ibmvscsi_module_exit(void){	vio_unregister_driver(&ibmvscsi_driver);}module_init(ibmvscsi_module_init);module_exit(ibmvscsi_module_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -