diff options
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 4b32ca442433..1be0776a80c4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -136,6 +136,7 @@ int aac_fib_setup(struct aac_dev * dev) | |||
136 | i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | 136 | i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); |
137 | i++, fibptr++) | 137 | i++, fibptr++) |
138 | { | 138 | { |
139 | fibptr->flags = 0; | ||
139 | fibptr->dev = dev; | 140 | fibptr->dev = dev; |
140 | fibptr->hw_fib_va = hw_fib; | 141 | fibptr->hw_fib_va = hw_fib; |
141 | fibptr->data = (void *) fibptr->hw_fib_va->data; | 142 | fibptr->data = (void *) fibptr->hw_fib_va->data; |
@@ -240,11 +241,11 @@ void aac_fib_init(struct fib *fibptr) | |||
240 | { | 241 | { |
241 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 242 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
242 | 243 | ||
244 | memset(&hw_fib->header, 0, sizeof(struct aac_fibhdr)); | ||
243 | hw_fib->header.StructType = FIB_MAGIC; | 245 | hw_fib->header.StructType = FIB_MAGIC; |
244 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); | 246 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); |
245 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); | 247 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); |
246 | hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */ | 248 | hw_fib->header.u.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); |
247 | hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); | ||
248 | hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); | 249 | hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); |
249 | } | 250 | } |
250 | 251 | ||
@@ -259,7 +260,6 @@ void aac_fib_init(struct fib *fibptr) | |||
259 | static void fib_dealloc(struct fib * fibptr) | 260 | static void fib_dealloc(struct fib * fibptr) |
260 | { | 261 | { |
261 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 262 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
262 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); | ||
263 | hw_fib->header.XferState = 0; | 263 | hw_fib->header.XferState = 0; |
264 | } | 264 | } |
265 | 265 | ||
@@ -370,7 +370,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw | |||
370 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); | 370 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); |
371 | entry->addr = hw_fib->header.SenderFibAddress; | 371 | entry->addr = hw_fib->header.SenderFibAddress; |
372 | /* Restore adapters pointer to the FIB */ | 372 | /* Restore adapters pointer to the FIB */ |
373 | hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ | 373 | hw_fib->header.u.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ |
374 | map = 0; | 374 | map = 0; |
375 | } | 375 | } |
376 | /* | 376 | /* |
@@ -450,7 +450,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
450 | */ | 450 | */ |
451 | 451 | ||
452 | hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); | 452 | hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); |
453 | hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); | 453 | hw_fib->header.Handle = (u32)(fibptr - dev->fibs) + 1; |
454 | /* | 454 | /* |
455 | * Set FIB state to indicate where it came from and if we want a | 455 | * Set FIB state to indicate where it came from and if we want a |
456 | * response from the adapter. Also load the command from the | 456 | * response from the adapter. Also load the command from the |
@@ -460,7 +460,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
460 | */ | 460 | */ |
461 | hw_fib->header.Command = cpu_to_le16(command); | 461 | hw_fib->header.Command = cpu_to_le16(command); |
462 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); | 462 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); |
463 | fibptr->hw_fib_va->header.Flags = 0; /* 0 the flags field - internal only*/ | ||
464 | /* | 463 | /* |
465 | * Set the size of the Fib we want to send to the adapter | 464 | * Set the size of the Fib we want to send to the adapter |
466 | */ | 465 | */ |
@@ -564,10 +563,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
564 | * functioning because an interrupt routing or other | 563 | * functioning because an interrupt routing or other |
565 | * hardware failure has occurred. | 564 | * hardware failure has occurred. |
566 | */ | 565 | */ |
567 | unsigned long count = 36000000L; /* 3 minutes */ | 566 | unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */ |
568 | while (down_trylock(&fibptr->event_wait)) { | 567 | while (down_trylock(&fibptr->event_wait)) { |
569 | int blink; | 568 | int blink; |
570 | if (--count == 0) { | 569 | if (time_is_before_eq_jiffies(timeout)) { |
571 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; | 570 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; |
572 | spin_lock_irqsave(q->lock, qflags); | 571 | spin_lock_irqsave(q->lock, qflags); |
573 | q->numpending--; | 572 | q->numpending--; |
@@ -588,7 +587,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
588 | } | 587 | } |
589 | return -EFAULT; | 588 | return -EFAULT; |
590 | } | 589 | } |
591 | udelay(5); | 590 | /* We used to udelay() here but that absorbed |
591 | * a CPU when a timeout occured. Not very | ||
592 | * useful. */ | ||
593 | cpu_relax(); | ||
592 | } | 594 | } |
593 | } else if (down_interruptible(&fibptr->event_wait)) { | 595 | } else if (down_interruptible(&fibptr->event_wait)) { |
594 | /* Do nothing ... satisfy | 596 | /* Do nothing ... satisfy |
@@ -708,7 +710,8 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
708 | unsigned long nointr = 0; | 710 | unsigned long nointr = 0; |
709 | unsigned long qflags; | 711 | unsigned long qflags; |
710 | 712 | ||
711 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { | 713 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 || |
714 | dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { | ||
712 | kfree(hw_fib); | 715 | kfree(hw_fib); |
713 | return 0; | 716 | return 0; |
714 | } | 717 | } |
@@ -721,7 +724,9 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
721 | /* | 724 | /* |
722 | * If we plan to do anything check the structure type first. | 725 | * If we plan to do anything check the structure type first. |
723 | */ | 726 | */ |
724 | if (hw_fib->header.StructType != FIB_MAGIC) { | 727 | if (hw_fib->header.StructType != FIB_MAGIC && |
728 | hw_fib->header.StructType != FIB_MAGIC2 && | ||
729 | hw_fib->header.StructType != FIB_MAGIC2_64) { | ||
725 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 730 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
726 | kfree(hw_fib); | 731 | kfree(hw_fib); |
727 | return -EINVAL; | 732 | return -EINVAL; |
@@ -783,7 +788,9 @@ int aac_fib_complete(struct fib *fibptr) | |||
783 | * If we plan to do anything check the structure type first. | 788 | * If we plan to do anything check the structure type first. |
784 | */ | 789 | */ |
785 | 790 | ||
786 | if (hw_fib->header.StructType != FIB_MAGIC) | 791 | if (hw_fib->header.StructType != FIB_MAGIC && |
792 | hw_fib->header.StructType != FIB_MAGIC2 && | ||
793 | hw_fib->header.StructType != FIB_MAGIC2_64) | ||
787 | return -EINVAL; | 794 | return -EINVAL; |
788 | /* | 795 | /* |
789 | * This block completes a cdb which orginated on the host and we | 796 | * This block completes a cdb which orginated on the host and we |