dpcsup.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Adaptec AAC series RAID controller driver
  3.  * (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
  4.  *
  5.  * based on the old aacraid driver that is..
  6.  * Adaptec aacraid device driver for Linux.
  7.  *
  8.  * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
  9.  *
  10.  * 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.  * the Free Software Foundation; either version 2, or (at your option)
  13.  * any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; see the file COPYING.  If not, write to
  22.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  *
  24.  * Module Name:
  25.  *  dpcsup.c
  26.  *
  27.  * Abstract: All DPC processing routines for the cyclone board occur here.
  28.  *
  29.  *
  30.  */
  31. #include <linux/config.h>
  32. #include <linux/kernel.h>
  33. #include <linux/init.h>
  34. #include <linux/types.h>
  35. #include <linux/sched.h>
  36. #include <linux/pci.h>
  37. #include <linux/spinlock.h>
  38. #include <linux/slab.h>
  39. #include <linux/completion.h>
  40. #include <linux/blk.h>
  41. #include <asm/semaphore.h>
  42. #include "scsi.h"
  43. #include "hosts.h"
  44. #include "aacraid.h"
  45. /**
  46.  * aac_response_normal - Handle command replies
  47.  * @q: Queue to read from
  48.  *
  49.  * This DPC routine will be run when the adapter interrupts us to let us
  50.  * know there is a response on our normal priority queue. We will pull off
  51.  * all QE there are and wake up all the waiters before exiting. We will
  52.  * take a spinlock out on the queue before operating on it.
  53.  */
  54. unsigned int aac_response_normal(struct aac_queue * q)
  55. {
  56. struct aac_dev * dev = q->dev;
  57. struct aac_entry *entry;
  58. struct hw_fib * fib;
  59. struct fib * fibctx;
  60. int consumed = 0;
  61. unsigned long flags;
  62. spin_lock_irqsave(q->lock, flags);
  63. /*
  64.  * Keep pulling response QEs off the response queue and waking
  65.  * up the waiters until there are no more QEs. We then return
  66.  * back to the system. If no response was requesed we just
  67.  * deallocate the Fib here and continue.
  68.  */
  69. while(aac_consumer_get(dev, q, &entry))
  70. {
  71. int fast;
  72. fast = (int) (entry->addr & 0x01);
  73. fib = (struct hw_fib *) (entry->addr & ~0x01);
  74. aac_consumer_free(dev, q, HostNormRespQueue);
  75. fibctx = (struct fib *)fib->header.SenderData;
  76. /*
  77.  * Remove this fibctx from the Outstanding I/O queue.
  78.  * But only if it has not already been timed out.
  79.  *
  80.  * If the fib has been timed out already, then just 
  81.  * continue. The caller has already been notified that
  82.  * the fib timed out.
  83.  */
  84. if (!(fibctx->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
  85. list_del(&fibctx->queue);
  86. dev->queues->queue[AdapNormCmdQueue].numpending--;
  87. } else {
  88. printk(KERN_WARNING "aacraid: FIB timeout.n");
  89. continue;
  90. }
  91. spin_unlock_irqrestore(q->lock, flags);
  92. if (fast) {
  93. /*
  94.  * Doctor the fib
  95.  */
  96. *(u32 *)fib->data = cpu_to_le32(ST_OK);
  97. fib->header.XferState |= cpu_to_le32(AdapterProcessed);
  98. }
  99. FIB_COUNTER_INCREMENT(aac_config.FibRecved);
  100. if (fib->header.Command == cpu_to_le16(NuFileSystem))
  101. {
  102. u32 *pstatus = (u32 *)fib->data;
  103. if (*pstatus & cpu_to_le32(0xffff0000))
  104. *pstatus = cpu_to_le32(ST_OK);
  105. }
  106. if (fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) 
  107. {
  108.          if (fib->header.XferState & cpu_to_le32(NoResponseExpected))
  109. FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved);
  110. else 
  111. FIB_COUNTER_INCREMENT(aac_config.AsyncRecved);
  112. /*
  113.  * NOTE:  we cannot touch the fibctx after this
  114.  *     call, because it may have been deallocated.
  115.  */
  116. fibctx->callback(fibctx->callback_data, fibctx);
  117. } else {
  118. unsigned long flagv;
  119. spin_lock_irqsave(&fibctx->event_lock, flagv);
  120. fibctx->done = 1;
  121. up(&fibctx->event_wait);
  122. spin_unlock_irqrestore(&fibctx->event_lock, flagv);
  123. FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
  124. }
  125. consumed++;
  126. spin_lock_irqsave(q->lock, flags);
  127. }
  128. if (consumed > aac_config.peak_fibs)
  129. aac_config.peak_fibs = consumed;
  130. if (consumed == 0) 
  131. aac_config.zero_fibs++;
  132. spin_unlock_irqrestore(q->lock, flags);
  133. return 0;
  134. }
  135. /**
  136.  * aac_command_normal - handle commands
  137.  * @q: queue to process
  138.  *
  139.  * This DPC routine will be queued when the adapter interrupts us to 
  140.  * let us know there is a command on our normal priority queue. We will 
  141.  * pull off all QE there are and wake up all the waiters before exiting.
  142.  * We will take a spinlock out on the queue before operating on it.
  143.  */
  144.  
  145. unsigned int aac_command_normal(struct aac_queue *q)
  146. {
  147. struct aac_dev * dev = q->dev;
  148. struct aac_entry *entry;
  149. unsigned long flags;
  150. spin_lock_irqsave(q->lock, flags);
  151. /*
  152.  * Keep pulling response QEs off the response queue and waking
  153.  * up the waiters until there are no more QEs. We then return
  154.  * back to the system.
  155.  */
  156. while(aac_consumer_get(dev, q, &entry))
  157. {
  158. struct hw_fib * fib;
  159. fib = (struct hw_fib *)entry->addr;
  160. if (dev->aif_thread) {
  161.         list_add_tail(&fib->header.FibLinks, &q->cmdq);
  162.           aac_consumer_free(dev, q, HostNormCmdQueue);
  163.         wake_up_interruptible(&q->cmdready);
  164. } else {
  165. struct fib fibctx;
  166.           aac_consumer_free(dev, q, HostNormCmdQueue);
  167. spin_unlock_irqrestore(q->lock, flags);
  168. memset(&fibctx, 0, sizeof(struct fib));
  169. fibctx.type = FSAFS_NTC_FIB_CONTEXT;
  170. fibctx.size = sizeof(struct fib);
  171. fibctx.fib = fib;
  172. fibctx.data = fib->data;
  173. fibctx.dev = dev;
  174. /*
  175.  * Set the status of this FIB
  176.  */
  177. *(u32 *)fib->data = cpu_to_le32(ST_OK);
  178. fib_adapter_complete(&fibctx, sizeof(u32));
  179. spin_lock_irqsave(q->lock, flags);
  180. }
  181. }
  182. spin_unlock_irqrestore(q->lock, flags);
  183. return 0;
  184. }