ibmvscsi: handle re-enable firmware message
Subsystems (3)
PATCH 1/1 ibmvscsi: handle re-enable firmware message
New versions of the Power5 firmware can send a "re-enable" message to the virtual scsi adapter. This fix makes us handle the message correctly. Without it, the driver goes catatonic and the system crashes unpleasantly.
drivers/scsi/ibmvscsi/ibmvscsi.c | 68 ++++++++++++++++++---------------- drivers/scsi/ibmvscsi/ibmvscsi.h | 3 + drivers/scsi/ibmvscsi/iseries_vscsi.c | 13 ++++++ drivers/scsi/ibmvscsi/rpa_vscsi.c | 22 +++++++++++ 4 files changed, 74 insertions(+), 32 deletions(-)
drivers/scsi/ibmvscsi/ibmvscsi.c +36 -31
@@ -87,7 +87,7 @@static int init_timeout =5 ;static int max_requests =50 ; -#define IBMVSCSI_VERSION "1.5.7" +#define IBMVSCSI_VERSION "1.5.8"MODULE_DESCRIPTION ("IBM Virtual SCSI" );MODULE_AUTHOR ("Dave Boutcher" );
@@ -534,7 +534,6 @@static int ibmvscsi_send_srp_event (struct srp_event_struct *evt_struct,struct ibmvscsi_host_data *hostdata) { -struct scsi_cmnd *cmnd;u64 *crq_as_u64 = (u64 *) &evt_struct->crq;int rc;
@@ -544,19 +543,8 @@* can handle more requests (can_queue) when we actually can't */ if ((evt_struct->crq.format ==VIOSRP_SRP_FORMAT ) && - (atomic_dec_if_positive (&hostdata->request_limit) <0 )) { -/* See if the adapter is disabled */ -if (atomic_read (&hostdata->request_limit) <0 ) - goto send_error; - -printk (KERN_WARNING -"ibmvscsi: Warning, request_limit exceeded\n" ); -unmap_cmd_data (&evt_struct->iu.srp.cmd, - evt_struct, - hostdata->dev); -free_event_struct (&hostdata->pool, evt_struct); -return SCSI_MLQUEUE_HOST_BUSY ; - } + (atomic_dec_if_positive (&hostdata->request_limit) <0 )) + goto send_error;/* Copy the IU into the transfer area */ *evt_struct->xfer_iu = evt_struct->iu;
@@ -572,7 +560,7 @@ ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {list_del (&evt_struct->list); -printk (KERN_ERR "ibmvscsi: failed to send event struct rc %d\n" , +printk (KERN_ERR "ibmvscsi: send error %d\n" , rc); goto send_error; }
@@ -582,14 +570,8 @@ send_error:unmap_cmd_data (&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); -if ((cmnd = evt_struct->cmnd) !=NULL ) { - cmnd->result =DID_ERROR <<16 ; - evt_struct->cmnd_done (cmnd); - }else if (evt_struct->done) - evt_struct->done (evt_struct); -free_event_struct (&hostdata->pool, evt_struct); -return 0 ; +return SCSI_MLQUEUE_HOST_BUSY ; }/**
@@ -802,7 +784,8 @@case SRP_LOGIN_RSP_TYPE :/* it worked! */ break ;case SRP_LOGIN_REJ_TYPE :/* refused! */ -printk (KERN_INFO "ibmvscsi: SRP_LOGIN_REQ rejected\n" ); +printk (KERN_INFO "ibmvscsi: SRP_LOGIN_REJ reason %u\n" , + evt_struct->xfer_iu->srp.login_rej.reason);/* Login failed. */ atomic_set (&hostdata->request_limit,-1 );return ;
@@ -834,6 +817,9 @@return ; } +/* If we had any pending I/Os, kick them */ +scsi_unblock_requests (hostdata->host); +send_mad_adapter_info (hostdata);return ; }
@@ -862,6 +848,7 @@ init_timeout * HZ); login = &evt_struct->iu.srp.login_req; +memset (login,0x00 ,sizeof (struct 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 ;
@@ -1122,7 +1109,7 @@* purge_requests: Our virtual adapter just shut down. purge any sent requests * @hostdata: the adapter */ -static void purge_requests (struct ibmvscsi_host_data *hostdata) +static void purge_requests (struct ibmvscsi_host_data *hostdata,int error_code) {struct srp_event_struct *tmp_evt, *pos;unsigned long flags;
@@ -1131,7 +1118,7 @@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 ); + tmp_evt->cmnd->result = (error_code <<16 );unmap_cmd_data (&tmp_evt->iu.srp.cmd, tmp_evt, tmp_evt->hostdata->dev);
@@ -1186,12 +1173,30 @@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" ); +case 0xFF :/* Hypervisor telling us the connection is closed */ +scsi_block_requests (hostdata->host); +if (crq->format ==0x06 ) { +/* We need to re-setup the interpartition connection */ +printk (KERN_INFO +"ibmvscsi: Re-enabling adapter!\n" ); +purge_requests (hostdata,DID_REQUEUE ); +if (ibmvscsi_reenable_crq_queue (&hostdata->queue, + hostdata) ==0 ) +if (ibmvscsi_send_crq (hostdata, +0xC001000000000000LL ,0 )) +printk (KERN_ERR +"ibmvscsi: transmit error after" +" enable\n" ); + }else { +printk (KERN_INFO +"ibmvscsi: Virtual adapter failed rc %d!\n" , + crq->format); -atomic_set (&hostdata->request_limit,-1 ); -purge_requests (hostdata); -ibmvscsi_reset_crq_queue (&hostdata->queue, hostdata); +atomic_set (&hostdata->request_limit,-1 ); +purge_requests (hostdata,DID_ERROR ); +ibmvscsi_reset_crq_queue (&hostdata->queue, hostdata); + } +scsi_unblock_requests (hostdata->host);return ;case 0x80 :/* real payload */ break ;
drivers/scsi/ibmvscsi/ibmvscsi.h +3 -0
@@ -103,6 +103,9 @@int ibmvscsi_reset_crq_queue (struct crq_queue *queue,struct ibmvscsi_host_data *hostdata); +int ibmvscsi_reenable_crq_queue (struct crq_queue *queue, +struct ibmvscsi_host_data *hostdata); +void ibmvscsi_handle_crq (struct viosrp_crq *crq,struct ibmvscsi_host_data *hostdata); int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
drivers/scsi/ibmvscsi/iseries_vscsi.c +13 -0
@@ -124,6 +124,19 @@ }/** +* reenable_crq_queue: - reenables a crq after a failure +* @queue: crq_queue to initialize and register +* @hostdata: ibmvscsi_host_data of host +* +* no-op for iSeries +*/ +int ibmvscsi_reenable_crq_queue (struct crq_queue *queue, +struct ibmvscsi_host_data *hostdata) +{ +return 0 ; +} + +/** * ibmvscsi_send_crq: - Send a CRQ * @hostdata: the adapter * @word1: the first 64 bits of the data
drivers/scsi/ibmvscsi/rpa_vscsi.c +22 -0
@@ -281,6 +281,28 @@ }/** +* reenable_crq_queue: - reenables a crq after +* @queue: crq_queue to initialize and register +* @hostdata: ibmvscsi_host_data of host +* +*/ +int ibmvscsi_reenable_crq_queue (struct crq_queue *queue, +struct ibmvscsi_host_data *hostdata) +{ +int rc; +struct vio_dev *vdev =to_vio_dev (hostdata->dev); + +/* Re-enable the CRQ */ +do { + rc =plpar_hcall_norets (H_ENABLE_CRQ , vdev->unit_address); + }while ((rc == H_InProgress) || (rc == H_Busy) || (H_isLongBusy (rc))); + +if (rc) +printk (KERN_ERR "ibmvscsi: Error %d enabling adapter\n" , rc); +return rc; +} + +/** * reset_crq_queue: - resets a crq after a failure * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host
Signature · 1 line
Dave Boutcher
Is there also an updated ibmvscsi-server patch somewhere?
-jf
Quoted 1 line · Jan-Frode Myklebust
Is there also an updated ibmvscsi-server patch somewhere?
No, I gave up on pushing that driver in its current form towards mainline, and I've been tied up for the last month or so on another project. The long term answer is to tie into the work Mike Christie & Co. are doing....
I have somewhat reliable reports that the previous patches still work on 2.6.15. We also have a sourcforge project with the ibmvscsis driver. If you are using it heavily, let me know and I'll put a little more effort into keeping it current until an alternative is available.
Signature · 1 line
Dave Boutcher