aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/dpcsup.c
diff options
context:
space:
mode:
authorMahesh Rajashekhara <Mahesh_Rajashekhara@pmc-sierra.com>2011-03-17 05:10:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 12:36:58 -0400
commite8b12f0fb8352237525961f14ec933e915848840 (patch)
treecdbf1209bdb6dc300434a6608e5ac73d536e47c0 /drivers/scsi/aacraid/dpcsup.c
parent0a2385cea9a715e11df10fce1f1442d933008a40 (diff)
[SCSI] aacraid: Add new code for PMC-Sierra's SRC based controller family
Added new hardware device 0x28b interface for PMC-Sierra's SRC based controller family. - new src.c file for 0x28b specific functions - new XPORT header required - sync. command interface: doorbell bits shifted (SRC_ODR_SHIFT, SRC_IDR_SHIFT) - async. Interface: different inbound queue handling, no outbound I2O queue available, using doorbell ("PmDoorBellResponseSent") and response buffer on the host ("host_rrq") for status - changed AIF (adapter initiated FIBs) interface: "DoorBellAifPending" bit to inform about pending AIF, "AifRequest" command to read AIF, "NoMoreAifDataAvailable" to mark the end of the AIFs Signed-off-by: Mahesh Rajashekhara <aacraid@pmc-sierra.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/aacraid/dpcsup.c')
-rw-r--r--drivers/scsi/aacraid/dpcsup.c85
1 files changed, 74 insertions, 11 deletions
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 9c7408fe8c7d..f0c66a80ad13 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -5,7 +5,8 @@
5 * based on the old aacraid driver that is.. 5 * based on the old aacraid driver that is..
6 * Adaptec aacraid device driver for Linux. 6 * Adaptec aacraid device driver for Linux.
7 * 7 *
8 * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) 8 * Copyright (c) 2000-2010 Adaptec, Inc.
9 * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -228,6 +229,48 @@ unsigned int aac_command_normal(struct aac_queue *q)
228 return 0; 229 return 0;
229} 230}
230 231
232/*
233 *
234 * aac_aif_callback
235 * @context: the context set in the fib - here it is scsi cmd
236 * @fibptr: pointer to the fib
237 *
238 * Handles the AIFs - new method (SRC)
239 *
240 */
241
242static void aac_aif_callback(void *context, struct fib * fibptr)
243{
244 struct fib *fibctx;
245 struct aac_dev *dev;
246 struct aac_aifcmd *cmd;
247 int status;
248
249 fibctx = (struct fib *)context;
250 BUG_ON(fibptr == NULL);
251 dev = fibptr->dev;
252
253 if (fibptr->hw_fib_va->header.XferState &
254 cpu_to_le32(NoMoreAifDataAvailable)) {
255 aac_fib_complete(fibptr);
256 aac_fib_free(fibptr);
257 return;
258 }
259
260 aac_intr_normal(dev, 0, 1, 0, fibptr->hw_fib_va);
261
262 aac_fib_init(fibctx);
263 cmd = (struct aac_aifcmd *) fib_data(fibctx);
264 cmd->command = cpu_to_le32(AifReqEvent);
265
266 status = aac_fib_send(AifRequest,
267 fibctx,
268 sizeof(struct hw_fib)-sizeof(struct aac_fibhdr),
269 FsaNormal,
270 0, 1,
271 (fib_callback)aac_aif_callback, fibctx);
272}
273
231 274
232/** 275/**
233 * aac_intr_normal - Handle command replies 276 * aac_intr_normal - Handle command replies
@@ -238,19 +281,17 @@ unsigned int aac_command_normal(struct aac_queue *q)
238 * know there is a response on our normal priority queue. We will pull off 281 * know there is a response on our normal priority queue. We will pull off
239 * all QE there are and wake up all the waiters before exiting. 282 * all QE there are and wake up all the waiters before exiting.
240 */ 283 */
241 284unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
242unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) 285 int isAif, int isFastResponse, struct hw_fib *aif_fib)
243{ 286{
244 unsigned long mflags; 287 unsigned long mflags;
245 dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); 288 dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
246 if ((index & 0x00000002L)) { 289 if (isAif == 1) { /* AIF - common */
247 struct hw_fib * hw_fib; 290 struct hw_fib * hw_fib;
248 struct fib * fib; 291 struct fib * fib;
249 struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue]; 292 struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue];
250 unsigned long flags; 293 unsigned long flags;
251 294
252 if (index == 0xFFFFFFFEL) /* Special Case */
253 return 0; /* Do nothing */
254 /* 295 /*
255 * Allocate a FIB. For non queued stuff we can just use 296 * Allocate a FIB. For non queued stuff we can just use
256 * the stack so we are happy. We need a fib object in order to 297 * the stack so we are happy. We need a fib object in order to
@@ -263,8 +304,13 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
263 kfree (fib); 304 kfree (fib);
264 return 1; 305 return 1;
265 } 306 }
266 memcpy(hw_fib, (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) + 307 if (aif_fib != NULL) {
267 (index & ~0x00000002L)), sizeof(struct hw_fib)); 308 memcpy(hw_fib, aif_fib, sizeof(struct hw_fib));
309 } else {
310 memcpy(hw_fib,
311 (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
312 index), sizeof(struct hw_fib));
313 }
268 INIT_LIST_HEAD(&fib->fiblink); 314 INIT_LIST_HEAD(&fib->fiblink);
269 fib->type = FSAFS_NTC_FIB_CONTEXT; 315 fib->type = FSAFS_NTC_FIB_CONTEXT;
270 fib->size = sizeof(struct fib); 316 fib->size = sizeof(struct fib);
@@ -277,9 +323,26 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
277 wake_up_interruptible(&q->cmdready); 323 wake_up_interruptible(&q->cmdready);
278 spin_unlock_irqrestore(q->lock, flags); 324 spin_unlock_irqrestore(q->lock, flags);
279 return 1; 325 return 1;
326 } else if (isAif == 2) { /* AIF - new (SRC) */
327 struct fib *fibctx;
328 struct aac_aifcmd *cmd;
329
330 fibctx = aac_fib_alloc(dev);
331 if (!fibctx)
332 return 1;
333 aac_fib_init(fibctx);
334
335 cmd = (struct aac_aifcmd *) fib_data(fibctx);
336 cmd->command = cpu_to_le32(AifReqEvent);
337
338 return aac_fib_send(AifRequest,
339 fibctx,
340 sizeof(struct hw_fib)-sizeof(struct aac_fibhdr),
341 FsaNormal,
342 0, 1,
343 (fib_callback)aac_aif_callback, fibctx);
280 } else { 344 } else {
281 int fast = index & 0x01; 345 struct fib *fib = &dev->fibs[index];
282 struct fib * fib = &dev->fibs[index >> 2];
283 struct hw_fib * hwfib = fib->hw_fib_va; 346 struct hw_fib * hwfib = fib->hw_fib_va;
284 347
285 /* 348 /*
@@ -298,7 +361,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
298 return 0; 361 return 0;
299 } 362 }
300 363
301 if (fast) { 364 if (isFastResponse) {
302 /* 365 /*
303 * Doctor the fib 366 * Doctor the fib
304 */ 367 */