aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c177
1 files changed, 50 insertions, 127 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3b983f3ed960..e4d543a474ae 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -271,40 +271,22 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
271 /* Interrupt Moderation, only interrupt for first two entries */ 271 /* Interrupt Moderation, only interrupt for first two entries */
272 if (idx != le32_to_cpu(*(q->headers.consumer))) { 272 if (idx != le32_to_cpu(*(q->headers.consumer))) {
273 if (--idx == 0) { 273 if (--idx == 0) {
274 if (qid == AdapHighCmdQueue) 274 if (qid == AdapNormCmdQueue)
275 idx = ADAP_HIGH_CMD_ENTRIES;
276 else if (qid == AdapNormCmdQueue)
277 idx = ADAP_NORM_CMD_ENTRIES; 275 idx = ADAP_NORM_CMD_ENTRIES;
278 else if (qid == AdapHighRespQueue) 276 else
279 idx = ADAP_HIGH_RESP_ENTRIES;
280 else if (qid == AdapNormRespQueue)
281 idx = ADAP_NORM_RESP_ENTRIES; 277 idx = ADAP_NORM_RESP_ENTRIES;
282 } 278 }
283 if (idx != le32_to_cpu(*(q->headers.consumer))) 279 if (idx != le32_to_cpu(*(q->headers.consumer)))
284 *nonotify = 1; 280 *nonotify = 1;
285 } 281 }
286 282
287 if (qid == AdapHighCmdQueue) { 283 if (qid == AdapNormCmdQueue) {
288 if (*index >= ADAP_HIGH_CMD_ENTRIES)
289 *index = 0;
290 } else if (qid == AdapNormCmdQueue) {
291 if (*index >= ADAP_NORM_CMD_ENTRIES) 284 if (*index >= ADAP_NORM_CMD_ENTRIES)
292 *index = 0; /* Wrap to front of the Producer Queue. */ 285 *index = 0; /* Wrap to front of the Producer Queue. */
293 } 286 } else {
294 else if (qid == AdapHighRespQueue)
295 {
296 if (*index >= ADAP_HIGH_RESP_ENTRIES)
297 *index = 0;
298 }
299 else if (qid == AdapNormRespQueue)
300 {
301 if (*index >= ADAP_NORM_RESP_ENTRIES) 287 if (*index >= ADAP_NORM_RESP_ENTRIES)
302 *index = 0; /* Wrap to front of the Producer Queue. */ 288 *index = 0; /* Wrap to front of the Producer Queue. */
303 } 289 }
304 else {
305 printk("aacraid: invalid qid\n");
306 BUG();
307 }
308 290
309 if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */ 291 if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
310 printk(KERN_WARNING "Queue %d full, %u outstanding.\n", 292 printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
@@ -336,12 +318,8 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
336{ 318{
337 struct aac_entry * entry = NULL; 319 struct aac_entry * entry = NULL;
338 int map = 0; 320 int map = 0;
339 struct aac_queue * q = &dev->queues->queue[qid];
340
341 spin_lock_irqsave(q->lock, q->SavedIrql);
342 321
343 if (qid == AdapHighCmdQueue || qid == AdapNormCmdQueue) 322 if (qid == AdapNormCmdQueue) {
344 {
345 /* if no entries wait for some if caller wants to */ 323 /* if no entries wait for some if caller wants to */
346 while (!aac_get_entry(dev, qid, &entry, index, nonotify)) 324 while (!aac_get_entry(dev, qid, &entry, index, nonotify))
347 { 325 {
@@ -352,9 +330,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
352 */ 330 */
353 entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); 331 entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
354 map = 1; 332 map = 1;
355 } 333 } else {
356 else if (qid == AdapHighRespQueue || qid == AdapNormRespQueue)
357 {
358 while(!aac_get_entry(dev, qid, &entry, index, nonotify)) 334 while(!aac_get_entry(dev, qid, &entry, index, nonotify))
359 { 335 {
360 /* if no entries wait for some if caller wants to */ 336 /* if no entries wait for some if caller wants to */
@@ -377,42 +353,6 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
377 return 0; 353 return 0;
378} 354}
379 355
380
381/**
382 * aac_insert_entry - insert a queue entry
383 * @dev: Adapter
384 * @index: Index of entry to insert
385 * @qid: Queue number
386 * @nonotify: Suppress adapter notification
387 *
388 * Gets the next free QE off the requested priorty adapter command
389 * queue and associates the Fib with the QE. The QE represented by
390 * index is ready to insert on the queue when this routine returns
391 * success.
392 */
393
394static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned long nonotify)
395{
396 struct aac_queue * q = &dev->queues->queue[qid];
397
398 if(q == NULL)
399 BUG();
400 *(q->headers.producer) = cpu_to_le32(index + 1);
401 spin_unlock_irqrestore(q->lock, q->SavedIrql);
402
403 if (qid == AdapHighCmdQueue ||
404 qid == AdapNormCmdQueue ||
405 qid == AdapHighRespQueue ||
406 qid == AdapNormRespQueue)
407 {
408 if (!nonotify)
409 aac_adapter_notify(dev, qid);
410 }
411 else
412 printk("Suprise insert!\n");
413 return 0;
414}
415
416/* 356/*
417 * Define the highest level of host to adapter communication routines. 357 * Define the highest level of host to adapter communication routines.
418 * These routines will support host to adapter FS commuication. These 358 * These routines will support host to adapter FS commuication. These
@@ -441,12 +381,13 @@ static int aac_insert_entry(struct aac_dev * dev, u32 index, u32 qid, unsigned l
441int 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)
442{ 382{
443 u32 index; 383 u32 index;
444 u32 qid;
445 struct aac_dev * dev = fibptr->dev; 384 struct aac_dev * dev = fibptr->dev;
446 unsigned long nointr = 0; 385 unsigned long nointr = 0;
447 struct hw_fib * hw_fib = fibptr->hw_fib; 386 struct hw_fib * hw_fib = fibptr->hw_fib;
448 struct aac_queue * q; 387 struct aac_queue * q;
449 unsigned long flags = 0; 388 unsigned long flags = 0;
389 unsigned long qflags;
390
450 if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) 391 if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
451 return -EBUSY; 392 return -EBUSY;
452 /* 393 /*
@@ -499,26 +440,8 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
499 * Get a queue entry connect the FIB to it and send an notify 440 * Get a queue entry connect the FIB to it and send an notify
500 * the adapter a command is ready. 441 * the adapter a command is ready.
501 */ 442 */
502 if (priority == FsaHigh) { 443 hw_fib->header.XferState |= cpu_to_le32(NormalPriority);
503 hw_fib->header.XferState |= cpu_to_le32(HighPriority);
504 qid = AdapHighCmdQueue;
505 } else {
506 hw_fib->header.XferState |= cpu_to_le32(NormalPriority);
507 qid = AdapNormCmdQueue;
508 }
509 q = &dev->queues->queue[qid];
510 444
511 if(wait)
512 spin_lock_irqsave(&fibptr->event_lock, flags);
513 if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0)
514 return -EWOULDBLOCK;
515 dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
516 dprintk((KERN_DEBUG "Fib contents:.\n"));
517 dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
518 dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
519 dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib));
520 dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
521 dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
522 /* 445 /*
523 * Fill in the Callback and CallbackContext if we are not 446 * Fill in the Callback and CallbackContext if we are not
524 * going to wait. 447 * going to wait.
@@ -527,15 +450,33 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority
527 fibptr->callback = callback; 450 fibptr->callback = callback;
528 fibptr->callback_data = callback_data; 451 fibptr->callback_data = callback_data;
529 } 452 }
530 FIB_COUNTER_INCREMENT(aac_config.FibsSent);
531 list_add_tail(&fibptr->queue, &q->pendingq);
532 q->numpending++;
533 453
534 fibptr->done = 0; 454 fibptr->done = 0;
535 fibptr->flags = 0; 455 fibptr->flags = 0;
536 456
537 if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0) 457 FIB_COUNTER_INCREMENT(aac_config.FibsSent);
538 return -EWOULDBLOCK; 458
459 dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
460 dprintk((KERN_DEBUG "Fib contents:.\n"));
461 dprintk((KERN_DEBUG " Command = %d.\n", hw_fib->header.Command));
462 dprintk((KERN_DEBUG " XferState = %x.\n", hw_fib->header.XferState));
463 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));
465 dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr));
466
467 q = &dev->queues->queue[AdapNormCmdQueue];
468
469 if(wait)
470 spin_lock_irqsave(&fibptr->event_lock, flags);
471 spin_lock_irqsave(q->lock, qflags);
472 aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
473
474 list_add_tail(&fibptr->queue, &q->pendingq);
475 q->numpending++;
476 *(q->headers.producer) = cpu_to_le32(index + 1);
477 spin_unlock_irqrestore(q->lock, qflags);
478 if (!(nointr & aac_config.irq_mod))
479 aac_adapter_notify(dev, AdapNormCmdQueue);
539 /* 480 /*
540 * If the caller wanted us to wait for response wait now. 481 * If the caller wanted us to wait for response wait now.
541 */ 482 */
@@ -651,15 +592,9 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
651 case HostNormCmdQueue: 592 case HostNormCmdQueue:
652 notify = HostNormCmdNotFull; 593 notify = HostNormCmdNotFull;
653 break; 594 break;
654 case HostHighCmdQueue:
655 notify = HostHighCmdNotFull;
656 break;
657 case HostNormRespQueue: 595 case HostNormRespQueue:
658 notify = HostNormRespNotFull; 596 notify = HostNormRespNotFull;
659 break; 597 break;
660 case HostHighRespQueue:
661 notify = HostHighRespNotFull;
662 break;
663 default: 598 default:
664 BUG(); 599 BUG();
665 return; 600 return;
@@ -681,9 +616,13 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
681{ 616{
682 struct hw_fib * hw_fib = fibptr->hw_fib; 617 struct hw_fib * hw_fib = fibptr->hw_fib;
683 struct aac_dev * dev = fibptr->dev; 618 struct aac_dev * dev = fibptr->dev;
619 struct aac_queue * q;
684 unsigned long nointr = 0; 620 unsigned long nointr = 0;
685 if (hw_fib->header.XferState == 0) 621 unsigned long qflags;
622
623 if (hw_fib->header.XferState == 0) {
686 return 0; 624 return 0;
625 }
687 /* 626 /*
688 * If we plan to do anything check the structure type first. 627 * If we plan to do anything check the structure type first.
689 */ 628 */
@@ -698,37 +637,21 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
698 * send the completed cdb to the adapter. 637 * send the completed cdb to the adapter.
699 */ 638 */
700 if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) { 639 if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
640 u32 index;
701 hw_fib->header.XferState |= cpu_to_le32(HostProcessed); 641 hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
702 if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) { 642 if (size) {
703 u32 index; 643 size += sizeof(struct aac_fibhdr);
704 if (size) 644 if (size > le16_to_cpu(hw_fib->header.SenderSize))
705 { 645 return -EMSGSIZE;
706 size += sizeof(struct aac_fibhdr); 646 hw_fib->header.Size = cpu_to_le16(size);
707 if (size > le16_to_cpu(hw_fib->header.SenderSize))
708 return -EMSGSIZE;
709 hw_fib->header.Size = cpu_to_le16(size);
710 }
711 if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) {
712 return -EWOULDBLOCK;
713 }
714 if (aac_insert_entry(dev, index, AdapHighRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) {
715 }
716 } else if (hw_fib->header.XferState &
717 cpu_to_le32(NormalPriority)) {
718 u32 index;
719
720 if (size) {
721 size += sizeof(struct aac_fibhdr);
722 if (size > le16_to_cpu(hw_fib->header.SenderSize))
723 return -EMSGSIZE;
724 hw_fib->header.Size = cpu_to_le16(size);
725 }
726 if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0)
727 return -EWOULDBLOCK;
728 if (aac_insert_entry(dev, index, AdapNormRespQueue, (nointr & (int)aac_config.irq_mod)) != 0)
729 {
730 }
731 } 647 }
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);
732 } 655 }
733 else 656 else
734 { 657 {