aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi/rpa_vscsi.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-09-21 18:29:36 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:49:26 -0400
commitd3849d512fb0ca1e369e3efcaec910a949f55f62 (patch)
tree52b79dd6cd4fe8835ad46b35083edf803c5180b5 /drivers/scsi/ibmvscsi/rpa_vscsi.c
parent5307b1e8b050f309901acc9c6121061206a70ba5 (diff)
[SCSI] Fix ibmvscsi client for multiplatform iSeries+pSeries kernel
If you build a multiplatform kernel for iSeries and pSeries, with ibmvscsic support, the resulting client doesn't work on iSeries. This fixes that, using the appropriate low-level operations for the machine detected at runtime. [jejb: fixed up rejections around the srp transport patch] Signed-off-by: David Woodhouse <dwmw2@infradead.org> Acked by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi/rpa_vscsi.c')
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c113
1 files changed, 61 insertions, 52 deletions
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 9c14e789df5f..182146100dc1 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -42,14 +42,14 @@ static unsigned int partition_number = -1;
42 * Routines for managing the command/response queue 42 * Routines for managing the command/response queue
43 */ 43 */
44/** 44/**
45 * ibmvscsi_handle_event: - Interrupt handler for crq events 45 * rpavscsi_handle_event: - Interrupt handler for crq events
46 * @irq: number of irq to handle, not used 46 * @irq: number of irq to handle, not used
47 * @dev_instance: ibmvscsi_host_data of host that received interrupt 47 * @dev_instance: ibmvscsi_host_data of host that received interrupt
48 * 48 *
49 * Disables interrupts and schedules srp_task 49 * Disables interrupts and schedules srp_task
50 * Always returns IRQ_HANDLED 50 * Always returns IRQ_HANDLED
51 */ 51 */
52static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) 52static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance)
53{ 53{
54 struct ibmvscsi_host_data *hostdata = 54 struct ibmvscsi_host_data *hostdata =
55 (struct ibmvscsi_host_data *)dev_instance; 55 (struct ibmvscsi_host_data *)dev_instance;
@@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance)
66 * Frees irq, deallocates a page for messages, unmaps dma, and unregisters 66 * Frees irq, deallocates a page for messages, unmaps dma, and unregisters
67 * the crq with the hypervisor. 67 * the crq with the hypervisor.
68 */ 68 */
69void ibmvscsi_release_crq_queue(struct crq_queue *queue, 69static void rpavscsi_release_crq_queue(struct crq_queue *queue,
70 struct ibmvscsi_host_data *hostdata, 70 struct ibmvscsi_host_data *hostdata,
71 int max_requests) 71 int max_requests)
72{ 72{
73 long rc; 73 long rc;
74 struct vio_dev *vdev = to_vio_dev(hostdata->dev); 74 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue)
108} 108}
109 109
110/** 110/**
111 * ibmvscsi_send_crq: - Send a CRQ 111 * rpavscsi_send_crq: - Send a CRQ
112 * @hostdata: the adapter 112 * @hostdata: the adapter
113 * @word1: the first 64 bits of the data 113 * @word1: the first 64 bits of the data
114 * @word2: the second 64 bits of the data 114 * @word2: the second 64 bits of the data
115 */ 115 */
116int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) 116static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata,
117 u64 word1, u64 word2)
117{ 118{
118 struct vio_dev *vdev = to_vio_dev(hostdata->dev); 119 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
119 120
@@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2)
121} 122}
122 123
123/** 124/**
124 * ibmvscsi_task: - Process srps asynchronously 125 * rpavscsi_task: - Process srps asynchronously
125 * @data: ibmvscsi_host_data of host 126 * @data: ibmvscsi_host_data of host
126 */ 127 */
127static void ibmvscsi_task(void *data) 128static void rpavscsi_task(void *data)
128{ 129{
129 struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; 130 struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
130 struct vio_dev *vdev = to_vio_dev(hostdata->dev); 131 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@@ -190,6 +191,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
190} 191}
191 192
192/** 193/**
194 * reset_crq_queue: - resets a crq after a failure
195 * @queue: crq_queue to initialize and register
196 * @hostdata: ibmvscsi_host_data of host
197 *
198 */
199static int rpavscsi_reset_crq_queue(struct crq_queue *queue,
200 struct ibmvscsi_host_data *hostdata)
201{
202 int rc;
203 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
204
205 /* Close the CRQ */
206 do {
207 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
208 } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
209
210 /* Clean out the queue */
211 memset(queue->msgs, 0x00, PAGE_SIZE);
212 queue->cur = 0;
213
214 set_adapter_info(hostdata);
215
216 /* And re-open it again */
217 rc = plpar_hcall_norets(H_REG_CRQ,
218 vdev->unit_address,
219 queue->msg_token, PAGE_SIZE);
220 if (rc == 2) {
221 /* Adapter is good, but other end is not ready */
222 dev_warn(hostdata->dev, "Partner adapter not ready\n");
223 } else if (rc != 0) {
224 dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
225 }
226 return rc;
227}
228
229/**
193 * initialize_crq_queue: - Initializes and registers CRQ with hypervisor 230 * initialize_crq_queue: - Initializes and registers CRQ with hypervisor
194 * @queue: crq_queue to initialize and register 231 * @queue: crq_queue to initialize and register
195 * @hostdata: ibmvscsi_host_data of host 232 * @hostdata: ibmvscsi_host_data of host
@@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
198 * the crq with the hypervisor. 235 * the crq with the hypervisor.
199 * Returns zero on success. 236 * Returns zero on success.
200 */ 237 */
201int ibmvscsi_init_crq_queue(struct crq_queue *queue, 238static int rpavscsi_init_crq_queue(struct crq_queue *queue,
202 struct ibmvscsi_host_data *hostdata, 239 struct ibmvscsi_host_data *hostdata,
203 int max_requests) 240 int max_requests)
204{ 241{
205 int rc; 242 int rc;
206 int retrc; 243 int retrc;
@@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
227 queue->msg_token, PAGE_SIZE); 264 queue->msg_token, PAGE_SIZE);
228 if (rc == H_RESOURCE) 265 if (rc == H_RESOURCE)
229 /* maybe kexecing and resource is busy. try a reset */ 266 /* maybe kexecing and resource is busy. try a reset */
230 rc = ibmvscsi_reset_crq_queue(queue, 267 rc = rpavscsi_reset_crq_queue(queue,
231 hostdata); 268 hostdata);
232 269
233 if (rc == 2) { 270 if (rc == 2) {
@@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
240 } 277 }
241 278
242 if (request_irq(vdev->irq, 279 if (request_irq(vdev->irq,
243 ibmvscsi_handle_event, 280 rpavscsi_handle_event,
244 0, "ibmvscsi", (void *)hostdata) != 0) { 281 0, "ibmvscsi", (void *)hostdata) != 0) {
245 dev_err(hostdata->dev, "couldn't register irq 0x%x\n", 282 dev_err(hostdata->dev, "couldn't register irq 0x%x\n",
246 vdev->irq); 283 vdev->irq);
@@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
256 queue->cur = 0; 293 queue->cur = 0;
257 spin_lock_init(&queue->lock); 294 spin_lock_init(&queue->lock);
258 295
259 tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, 296 tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task,
260 (unsigned long)hostdata); 297 (unsigned long)hostdata);
261 298
262 return retrc; 299 return retrc;
@@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue,
281 * @hostdata: ibmvscsi_host_data of host 318 * @hostdata: ibmvscsi_host_data of host
282 * 319 *
283 */ 320 */
284int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, 321static int rpavscsi_reenable_crq_queue(struct crq_queue *queue,
285 struct ibmvscsi_host_data *hostdata) 322 struct ibmvscsi_host_data *hostdata)
286{ 323{
287 int rc; 324 int rc;
288 struct vio_dev *vdev = to_vio_dev(hostdata->dev); 325 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
@@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue,
297 return rc; 334 return rc;
298} 335}
299 336
300/** 337struct ibmvscsi_ops rpavscsi_ops = {
301 * reset_crq_queue: - resets a crq after a failure 338 .init_crq_queue = rpavscsi_init_crq_queue,
302 * @queue: crq_queue to initialize and register 339 .release_crq_queue = rpavscsi_release_crq_queue,
303 * @hostdata: ibmvscsi_host_data of host 340 .reset_crq_queue = rpavscsi_reset_crq_queue,
304 * 341 .reenable_crq_queue = rpavscsi_reenable_crq_queue,
305 */ 342 .send_crq = rpavscsi_send_crq,
306int ibmvscsi_reset_crq_queue(struct crq_queue *queue, 343};
307 struct ibmvscsi_host_data *hostdata)
308{
309 int rc;
310 struct vio_dev *vdev = to_vio_dev(hostdata->dev);
311
312 /* Close the CRQ */
313 do {
314 rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
315 } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc)));
316
317 /* Clean out the queue */
318 memset(queue->msgs, 0x00, PAGE_SIZE);
319 queue->cur = 0;
320
321 set_adapter_info(hostdata);
322
323 /* And re-open it again */
324 rc = plpar_hcall_norets(H_REG_CRQ,
325 vdev->unit_address,
326 queue->msg_token, PAGE_SIZE);
327 if (rc == 2) {
328 /* Adapter is good, but other end is not ready */
329 dev_warn(hostdata->dev, "Partner adapter not ready\n");
330 } else if (rc != 0) {
331 dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc);
332 }
333 return rc;
334}