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

📄 ibmvscsi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (ibmvscsi_send_srp_event(evt_struct, hostdata))		printk(KERN_ERR "ibmvscsi: couldn't send ADAPTER_INFO_REQ!\n");};/** * login_rsp: - Handle response to SRP login request * @evt_struct:	srp_event_struct with the response * * Used as a "done" callback by when sending srp_login. Gets called * by ibmvscsi_handle_crq()*/static void login_rsp(struct srp_event_struct *evt_struct){	struct ibmvscsi_host_data *hostdata = evt_struct->hostdata;	switch (evt_struct->xfer_iu->srp.generic.type) {	case SRP_LOGIN_RSP_TYPE:	/* it worked! */		break;	case SRP_LOGIN_REJ_TYPE:	/* refused! */		printk(KERN_INFO "ibmvscsi: SRP_LOGIN_REQ rejected\n");		/* Login failed.  */		atomic_set(&hostdata->request_limit, -1);		return;	default:		printk(KERN_ERR		       "ibmvscsi: Invalid login response typecode 0x%02x!\n",		       evt_struct->xfer_iu->srp.generic.type);		/* Login failed.  */		atomic_set(&hostdata->request_limit, -1);		return;	}	printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n");	if (evt_struct->xfer_iu->srp.login_rsp.request_limit_delta >	    (max_requests - 2))		evt_struct->xfer_iu->srp.login_rsp.request_limit_delta =		    max_requests - 2;	/* Now we know what the real request-limit is */	atomic_set(&hostdata->request_limit,		   evt_struct->xfer_iu->srp.login_rsp.request_limit_delta);	hostdata->host->can_queue =	    evt_struct->xfer_iu->srp.login_rsp.request_limit_delta - 2;	if (hostdata->host->can_queue < 1) {		printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n");		return;	}	send_mad_adapter_info(hostdata);	return;}/** * send_srp_login: - Sends the srp login * @hostdata:	ibmvscsi_host_data of host *  * Returns zero if successful.*/static int send_srp_login(struct ibmvscsi_host_data *hostdata){	int rc;	unsigned long flags;	struct srp_login_req *login;	struct srp_event_struct *evt_struct = get_event_struct(&hostdata->pool);	if (!evt_struct) {		printk(KERN_ERR		       "ibmvscsi: couldn't allocate an event for login req!\n");		return FAILED;	}	init_event_struct(evt_struct,			  login_rsp,			  VIOSRP_SRP_FORMAT,			  init_timeout * HZ);	login = &evt_struct->iu.srp.login_req;	login->type = SRP_LOGIN_REQ_TYPE;	login->max_requested_initiator_to_target_iulen = sizeof(union srp_iu);	login->required_buffer_formats = 0x0006;		/* Start out with a request limit of 1, since this is negotiated in	 * the login request we are just sending	 */	atomic_set(&hostdata->request_limit, 1);	spin_lock_irqsave(hostdata->host->host_lock, flags);	rc = ibmvscsi_send_srp_event(evt_struct, hostdata);	spin_unlock_irqrestore(hostdata->host->host_lock, flags);	return rc;};/** * sync_completion: Signal that a synchronous command has completed * Note that after returning from this call, the evt_struct is freed. * the caller waiting on this completion shouldn't touch the evt_struct * again. */static void sync_completion(struct srp_event_struct *evt_struct){	/* copy the response back */	if (evt_struct->sync_srp)		*evt_struct->sync_srp = *evt_struct->xfer_iu;		complete(&evt_struct->comp);}/** * ibmvscsi_abort: Abort a command...from scsi host template * send this over to the server and wait synchronously for the response */static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd){	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)cmd->device->host->hostdata;	struct srp_tsk_mgmt *tsk_mgmt;	struct srp_event_struct *evt;	struct srp_event_struct *tmp_evt, *found_evt;	union viosrp_iu srp_rsp;	int rsp_rc;	unsigned long flags;	u16 lun = lun_from_dev(cmd->device);	/* First, find this command in our sent list so we can figure	 * out the correct tag	 */	spin_lock_irqsave(hostdata->host->host_lock, flags);	found_evt = NULL;	list_for_each_entry(tmp_evt, &hostdata->sent, list) {		if (tmp_evt->cmnd == cmd) {			found_evt = tmp_evt;			break;		}	}	if (!found_evt) {		spin_unlock_irqrestore(hostdata->host->host_lock, flags);		return FAILED;	}	evt = get_event_struct(&hostdata->pool);	if (evt == NULL) {		spin_unlock_irqrestore(hostdata->host->host_lock, flags);		printk(KERN_ERR "ibmvscsi: failed to allocate abort event\n");		return FAILED;	}		init_event_struct(evt,			  sync_completion,			  VIOSRP_SRP_FORMAT,			  init_timeout * HZ);	tsk_mgmt = &evt->iu.srp.tsk_mgmt;		/* Set up an abort SRP command */	memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));	tsk_mgmt->type = SRP_TSK_MGMT_TYPE;	tsk_mgmt->lun = ((u64) lun) << 48;	tsk_mgmt->task_mgmt_flags = 0x01;	/* ABORT TASK */	tsk_mgmt->managed_task_tag = (u64) found_evt;	printk(KERN_INFO "ibmvscsi: aborting command. lun 0x%lx, tag 0x%lx\n",	       tsk_mgmt->lun, tsk_mgmt->managed_task_tag);	evt->sync_srp = &srp_rsp;	init_completion(&evt->comp);	rsp_rc = ibmvscsi_send_srp_event(evt, hostdata);	spin_unlock_irqrestore(hostdata->host->host_lock, flags);	if (rsp_rc != 0) {		printk(KERN_ERR "ibmvscsi: failed to send abort() event\n");		return FAILED;	}	wait_for_completion(&evt->comp);	/* make sure we got a good response */	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {		if (printk_ratelimit())			printk(KERN_WARNING 			       "ibmvscsi: abort bad SRP RSP type %d\n",			       srp_rsp.srp.generic.type);		return FAILED;	}	if (srp_rsp.srp.rsp.rspvalid)		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);	else		rsp_rc = srp_rsp.srp.rsp.status;	if (rsp_rc) {		if (printk_ratelimit())			printk(KERN_WARNING 		       "ibmvscsi: abort code %d for task tag 0x%lx\n",			       rsp_rc,			       tsk_mgmt->managed_task_tag);		return FAILED;	}	/* Because we dropped the spinlock above, it's possible	 * The event is no longer in our list.  Make sure it didn't	 * complete while we were aborting	 */	spin_lock_irqsave(hostdata->host->host_lock, flags);	found_evt = NULL;	list_for_each_entry(tmp_evt, &hostdata->sent, list) {		if (tmp_evt->cmnd == cmd) {			found_evt = tmp_evt;			break;		}	}	if (found_evt == NULL) {		spin_unlock_irqrestore(hostdata->host->host_lock, flags);		printk(KERN_INFO		       "ibmvscsi: aborted task tag 0x%lx completed\n",		       tsk_mgmt->managed_task_tag);		return SUCCESS;	}	printk(KERN_INFO	       "ibmvscsi: successfully aborted task tag 0x%lx\n",	       tsk_mgmt->managed_task_tag);	cmd->result = (DID_ABORT << 16);	list_del(&found_evt->list);	unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt,		       found_evt->hostdata->dev);	free_event_struct(&found_evt->hostdata->pool, found_evt);	spin_unlock_irqrestore(hostdata->host->host_lock, flags);	atomic_inc(&hostdata->request_limit);	return SUCCESS;}/** * ibmvscsi_eh_device_reset_handler: Reset a single LUN...from scsi host  * template send this over to the server and wait synchronously for the  * response */static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd){	struct ibmvscsi_host_data *hostdata =	    (struct ibmvscsi_host_data *)cmd->device->host->hostdata;	struct srp_tsk_mgmt *tsk_mgmt;	struct srp_event_struct *evt;	struct srp_event_struct *tmp_evt, *pos;	union viosrp_iu srp_rsp;	int rsp_rc;	unsigned long flags;	u16 lun = lun_from_dev(cmd->device);	spin_lock_irqsave(hostdata->host->host_lock, flags);	evt = get_event_struct(&hostdata->pool);	if (evt == NULL) {		spin_unlock_irqrestore(hostdata->host->host_lock, flags);		printk(KERN_ERR "ibmvscsi: failed to allocate reset event\n");		return FAILED;	}		init_event_struct(evt,			  sync_completion,			  VIOSRP_SRP_FORMAT,			  init_timeout * HZ);	tsk_mgmt = &evt->iu.srp.tsk_mgmt;	/* Set up a lun reset SRP command */	memset(tsk_mgmt, 0x00, sizeof(*tsk_mgmt));	tsk_mgmt->type = SRP_TSK_MGMT_TYPE;	tsk_mgmt->lun = ((u64) lun) << 48;	tsk_mgmt->task_mgmt_flags = 0x08;	/* LUN RESET */	printk(KERN_INFO "ibmvscsi: resetting device. lun 0x%lx\n",	       tsk_mgmt->lun);	evt->sync_srp = &srp_rsp;	init_completion(&evt->comp);	rsp_rc = ibmvscsi_send_srp_event(evt, hostdata);	spin_unlock_irqrestore(hostdata->host->host_lock, flags);	if (rsp_rc != 0) {		printk(KERN_ERR "ibmvscsi: failed to send reset event\n");		return FAILED;	}	wait_for_completion(&evt->comp);	/* make sure we got a good response */	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {		if (printk_ratelimit())			printk(KERN_WARNING 			       "ibmvscsi: reset bad SRP RSP type %d\n",			       srp_rsp.srp.generic.type);		return FAILED;	}	if (srp_rsp.srp.rsp.rspvalid)		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);	else		rsp_rc = srp_rsp.srp.rsp.status;	if (rsp_rc) {		if (printk_ratelimit())			printk(KERN_WARNING 			       "ibmvscsi: reset code %d for task tag 0x%lx\n",		       rsp_rc,			       tsk_mgmt->managed_task_tag);		return FAILED;	}	/* We need to find all commands for this LUN that have not yet been	 * responded to, and fail them with DID_RESET	 */	spin_lock_irqsave(hostdata->host->host_lock, flags);	list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) {		if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == cmd->device)) {			if (tmp_evt->cmnd)				tmp_evt->cmnd->result = (DID_RESET << 16);			list_del(&tmp_evt->list);			unmap_cmd_data(&tmp_evt->iu.srp.cmd, tmp_evt,				       tmp_evt->hostdata->dev);			free_event_struct(&tmp_evt->hostdata->pool,						   tmp_evt);			atomic_inc(&hostdata->request_limit);			if (tmp_evt->cmnd_done)				tmp_evt->cmnd_done(tmp_evt->cmnd);			else if (tmp_evt->done)				tmp_evt->done(tmp_evt);		}	}	spin_unlock_irqrestore(hostdata->host->host_lock, flags);	return SUCCESS;}/** * purge_requests: Our virtual adapter just shut down.  purge any sent requests * @hostdata:    the adapter */static void purge_requests(struct ibmvscsi_host_data *hostdata){	struct srp_event_struct *tmp_evt, *pos;	unsigned long flags;	spin_lock_irqsave(hostdata->host->host_lock, flags);	list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) {		list_del(&tmp_evt->list);		if (tmp_evt->cmnd) {			tmp_evt->cmnd->result = (DID_ERROR << 16);			unmap_cmd_data(&tmp_evt->iu.srp.cmd, 				       tmp_evt,					       tmp_evt->hostdata->dev);			if (tmp_evt->cmnd_done)				tmp_evt->cmnd_done(tmp_evt->cmnd);		} else {			if (tmp_evt->done) {				tmp_evt->done(tmp_evt);			}		}		free_event_struct(&tmp_evt->hostdata->pool, tmp_evt);	}	spin_unlock_irqrestore(hostdata->host->host_lock, flags);}/** * ibmvscsi_handle_crq: - Handles and frees received events in the CRQ * @crq:	Command/Response queue * @hostdata:	ibmvscsi_host_data of host **/void ibmvscsi_handle_crq(struct viosrp_crq *crq,			 struct ibmvscsi_host_data *hostdata){	unsigned long flags;	struct srp_event_struct *evt_struct =	    (struct srp_event_struct *)crq->IU_data_ptr;	switch (crq->valid) {	case 0xC0:		/* initialization */		switch (crq->format) {		case 0x01:	/* Initialization message */			printk(KERN_INFO "ibmvscsi: partner initialized\n");			/* Send back a response */			if (ibmvscsi_send_crq(hostdata,					      0xC002000000000000LL, 0) == 0) {				/* Now login */				send_srp_login(hostdata);			} else {				printk(KERN_ERR				       "ibmvscsi: Unable to send init rsp\n");			}			break;		case 0x02:	/* Initialization response */			printk(KERN_INFO

⌨️ 快捷键说明

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