aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-10-24 13:52:22 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-28 12:41:53 -0400
commit8e0c5ebde82b08f6d996e11983890fc4cc085fab (patch)
tree3ba38ff8e7b9203b47d038c215d9c7d623c250ba /drivers/scsi/aacraid/commsup.c
parent38a9a621aba953ddb8051547e98c10ec3c741312 (diff)
[SCSI] aacraid: Newer adapter communication iterface support
Received from Mark Salyzyn. This patch adds the 'new comm' interface, which modern AAC based adapters that are less than a year old support in the name of much improved performance. These modern adapters support both the legacy and the 'new comm' interfaces. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c88
1 files changed, 58 insertions, 30 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e4d543a474ae..ee9067255930 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -212,7 +212,7 @@ void fib_init(struct fib *fibptr)
212 hw_fib->header.StructType = FIB_MAGIC; 212 hw_fib->header.StructType = FIB_MAGIC;
213 hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); 213 hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
214 hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); 214 hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
215 hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); 215 hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */
216 hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); 216 hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
217 hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); 217 hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
218} 218}
@@ -380,9 +380,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
380 380
381int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data) 381int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data)
382{ 382{
383 u32 index;
384 struct aac_dev * dev = fibptr->dev; 383 struct aac_dev * dev = fibptr->dev;
385 unsigned long nointr = 0;
386 struct hw_fib * hw_fib = fibptr->hw_fib; 384 struct hw_fib * hw_fib = fibptr->hw_fib;
387 struct aac_queue * q; 385 struct aac_queue * q;
388 unsigned long flags = 0; 386 unsigned long flags = 0;
@@ -417,7 +415,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
417 * Map the fib into 32bits by using the fib number 415 * Map the fib into 32bits by using the fib number
418 */ 416 */
419 417
420 hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1); 418 hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
421 hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); 419 hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
422 /* 420 /*
423 * Set FIB state to indicate where it came from and if we want a 421 * Set FIB state to indicate where it came from and if we want a
@@ -456,10 +454,10 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
456 454
457 FIB_COUNTER_INCREMENT(aac_config.FibsSent); 455 FIB_COUNTER_INCREMENT(aac_config.FibsSent);
458 456
459 dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
460 dprintk((KERN_DEBUG "Fib contents:.\n")); 457 dprintk((KERN_DEBUG "Fib contents:.\n"));
461 dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command)); 458 dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command)));
462 dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState)); 459 dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command)));
460 dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState)));
463 dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); 461 dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
464 dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); 462 dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
465 dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); 463 dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
@@ -469,14 +467,37 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
469 if(wait) 467 if(wait)
470 spin_lock_irqsave(&fibptr->event_lock, flags); 468 spin_lock_irqsave(&fibptr->event_lock, flags);
471 spin_lock_irqsave(q->lock, qflags); 469 spin_lock_irqsave(q->lock, qflags);
472 aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); 470 if (dev->new_comm_interface) {
473 471 unsigned long count = 10000000L; /* 50 seconds */
474 list_add_tail(&fibptr->queue, &q->pendingq); 472 list_add_tail(&fibptr->queue, &q->pendingq);
475 q->numpending++; 473 q->numpending++;
476 *(q->headers.producer) = cpu_to_le32(index + 1); 474 spin_unlock_irqrestore(q->lock, qflags);
477 spin_unlock_irqrestore(q->lock, qflags); 475 while (aac_adapter_send(fibptr) != 0) {
478 if (!(nointr & aac_config.irq_mod)) 476 if (--count == 0) {
479 aac_adapter_notify(dev, AdapNormCmdQueue); 477 if (wait)
478 spin_unlock_irqrestore(&fibptr->event_lock, flags);
479 spin_lock_irqsave(q->lock, qflags);
480 q->numpending--;
481 list_del(&fibptr->queue);
482 spin_unlock_irqrestore(q->lock, qflags);
483 return -ETIMEDOUT;
484 }
485 udelay(5);
486 }
487 } else {
488 u32 index;
489 unsigned long nointr = 0;
490 aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
491
492 list_add_tail(&fibptr->queue, &q->pendingq);
493 q->numpending++;
494 *(q->headers.producer) = cpu_to_le32(index + 1);
495 spin_unlock_irqrestore(q->lock, qflags);
496 dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
497 if (!(nointr & aac_config.irq_mod))
498 aac_adapter_notify(dev, AdapNormCmdQueue);
499 }
500
480 /* 501 /*
481 * If the caller wanted us to wait for response wait now. 502 * If the caller wanted us to wait for response wait now.
482 */ 503 */
@@ -492,7 +513,6 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
492 * hardware failure has occurred. 513 * hardware failure has occurred.
493 */ 514 */
494 unsigned long count = 36000000L; /* 3 minutes */ 515 unsigned long count = 36000000L; /* 3 minutes */
495 unsigned long qflags;
496 while (down_trylock(&fibptr->event_wait)) { 516 while (down_trylock(&fibptr->event_wait)) {
497 if (--count == 0) { 517 if (--count == 0) {
498 spin_lock_irqsave(q->lock, qflags); 518 spin_lock_irqsave(q->lock, qflags);
@@ -621,12 +641,16 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
621 unsigned long qflags; 641 unsigned long qflags;
622 642
623 if (hw_fib->header.XferState == 0) { 643 if (hw_fib->header.XferState == 0) {
644 if (dev->new_comm_interface)
645 kfree (hw_fib);
624 return 0; 646 return 0;
625 } 647 }
626 /* 648 /*
627 * If we plan to do anything check the structure type first. 649 * If we plan to do anything check the structure type first.
628 */ 650 */
629 if ( hw_fib->header.StructType != FIB_MAGIC ) { 651 if ( hw_fib->header.StructType != FIB_MAGIC ) {
652 if (dev->new_comm_interface)
653 kfree (hw_fib);
630 return -EINVAL; 654 return -EINVAL;
631 } 655 }
632 /* 656 /*
@@ -637,21 +661,25 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
637 * send the completed cdb to the adapter. 661 * send the completed cdb to the adapter.
638 */ 662 */
639 if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { 663 if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
640 u32 index; 664 if (dev->new_comm_interface) {
641 hw_fib->header.XferState |= cpu_to_le32(HostProcessed); 665 kfree (hw_fib);
642 if (size) { 666 } else {
643 size += sizeof(struct aac_fibhdr); 667 u32 index;
644 if (size > le16_to_cpu(hw_fib->header.SenderSize)) 668 hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
645 return -EMSGSIZE; 669 if (size) {
646 hw_fib->header.Size = cpu_to_le16(size); 670 size += sizeof(struct aac_fibhdr);
671 if (size > le16_to_cpu(hw_fib->header.SenderSize))
672 return -EMSGSIZE;
673 hw_fib->header.Size = cpu_to_le16(size);
674 }
675 q = &dev->queues->queue[AdapNormRespQueue];
676 spin_lock_irqsave(q->lock, qflags);
677 aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
678 *(q->headers.producer) = cpu_to_le32(index + 1);
679 spin_unlock_irqrestore(q->lock, qflags);
680 if (!(nointr & (int)aac_config.irq_mod))
681 aac_adapter_notify(dev, AdapNormRespQueue);
647 } 682 }
648 q = &dev->queues->queue[AdapNormRespQueue];
649 spin_lock_irqsave(q->lock, qflags);
650 aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
651 *(q->headers.producer) = cpu_to_le32(index + 1);
652 spin_unlock_irqrestore(q->lock, qflags);
653 if (!(nointr & (int)aac_config.irq_mod))
654 aac_adapter_notify(dev, AdapNormRespQueue);
655 } 683 }
656 else 684 else
657 { 685 {