Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aic94xx_hwi.h
Go to the documentation of this file.
1 /*
2  * Aic94xx SAS/SATA driver hardware interface header file.
3  *
4  * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5  * Copyright (C) 2005 Luben Tuikov <[email protected]>
6  *
7  * This file is licensed under GPLv2.
8  *
9  * This file is part of the aic94xx driver.
10  *
11  * The aic94xx driver is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; version 2 of the
14  * License.
15  *
16  * The aic94xx driver is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with the aic94xx driver; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  */
26 
27 #ifndef _AIC94XX_HWI_H_
28 #define _AIC94XX_HWI_H_
29 
30 #include <linux/interrupt.h>
31 #include <linux/pci.h>
32 #include <linux/dma-mapping.h>
33 
34 #include <scsi/libsas.h>
35 
36 #include "aic94xx.h"
37 #include "aic94xx_sas.h"
38 
39 /* Define ASD_MAX_PHYS to the maximum phys ever. Currently 8. */
40 #define ASD_MAX_PHYS 8
41 #define ASD_PCBA_SN_SIZE 12
42 
44  void __iomem *addr;
45  unsigned long start; /* pci resource start */
46  unsigned long len; /* pci resource len */
47  unsigned long flags; /* pci resource flags */
48 
49  /* addresses internal to the host adapter */
50  u32 swa_base; /* mmspace 1 (MBAR1) uses this only */
53 };
54 
55 struct bios_struct {
56  int present;
60 };
61 
65  void *area;
66 };
67 
68 struct flash_struct {
70  int present;
71  int wide;
76 
78 };
79 
80 struct asd_phy_desc {
81  /* From CTRL-A settings, then set to what is appropriate */
88 #define ASD_CRC_DIS 1
89 #define ASD_SATA_SPINUP_HOLD 2
90 
91  u8 phy_control_0; /* mode 5 reg 0x160 */
92  u8 phy_control_1; /* mode 5 reg 0x161 */
93  u8 phy_control_2; /* mode 5 reg 0x162 */
94  u8 phy_control_3; /* mode 5 reg 0x163 */
95 };
96 
97 struct asd_dma_tok {
98  void *vaddr;
100  size_t size;
101 };
102 
103 struct hw_profile {
107 
110 
111  u8 enabled_phys; /* mask of enabled phys */
113  u32 max_scbs; /* absolute sequencer scb queue size */
117 
119  void *ddb_bitmap;
120 
121  int num_phys; /* ENABLEABLE */
122  int max_phys; /* REPORTED + ENABLEABLE */
123 
124  unsigned addr_range; /* max # of addrs; max # of possible ports */
125  unsigned port_name_base;
126  unsigned dev_name_base;
127  unsigned sata_name_base;
128 };
129 
130 struct asd_ascb {
131  struct list_head list;
132  struct asd_ha_struct *ha;
133 
134  struct scb *scb; /* equals dma_scb->vaddr */
137 
140 
141  /* internally generated command */
145  __be16 tag; /* error recovery only */
146 
147  /* If this is an Empty SCB, index of first edb in seq->edb_arr. */
149 
150  /* Used by the timer timeout function. */
151  int tc_index;
152 
153  void *uldd_task;
154 };
155 
156 #define ASD_DL_SIZE_BITS 0x8
157 #define ASD_DL_SIZE (1<<(2+ASD_DL_SIZE_BITS))
158 #define ASD_DEF_DL_TOGGLE 0x01
159 
160 struct asd_seq_data {
163  int pending;
165  int can_queue; /* per adapter */
166  struct asd_dma_tok next_scb; /* next scb to be delivered to CSEQ */
167 
172 
174  struct done_list_struct *dl; /* array of done list entries, equals */
175  struct asd_dma_tok *actual_dl; /* actual_dl->vaddr */
177  int dl_next;
178 
179  int num_edbs;
182  struct asd_ascb **escb_arr; /* array of pointers to escbs */
183 };
184 
185 /* This is an internal port structure. These are used to get accurate
186  * phy_mask for updating DDB 0.
187  */
188 struct asd_port {
192  int num_phys;
193 };
194 
195 /* This is the Host Adapter structure. It describes the hardware
196  * SAS adapter.
197  */
199  struct pci_dev *pcidev;
200  const char *name;
201 
203 
205 
206  int iospace;
209 
211 
216 
218 
219  struct asd_seq_data seq; /* sequencer related */
221  const struct firmware *bios_image;
222 };
223 
224 /* ---------- Common macros ---------- */
225 
226 #define ASD_BUSADDR_LO(__dma_handle) ((u32)(__dma_handle))
227 #define ASD_BUSADDR_HI(__dma_handle) (((sizeof(dma_addr_t))==8) \
228  ? ((u32)((__dma_handle) >> 32)) \
229  : ((u32)0))
230 
231 #define dev_to_asd_ha(__dev) pci_get_drvdata(to_pci_dev(__dev))
232 #define SCB_SITE_VALID(__site_no) (((__site_no) & 0xF0FF) != 0x00FF \
233  && ((__site_no) & 0xF0FF) > 0x001F)
234 /* For each bit set in __lseq_mask, set __lseq to equal the bit
235  * position of the set bit and execute the statement following.
236  * __mc is the temporary mask, used as a mask "counter".
237  */
238 #define for_each_sequencer(__lseq_mask, __mc, __lseq) \
239  for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
240  if (((__mc) & 1))
241 #define for_each_phy(__lseq_mask, __mc, __lseq) \
242  for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
243  if (((__mc) & 1))
244 
245 #define PHY_ENABLED(_HA, _I) ((_HA)->hw_prof.enabled_phys & (1<<(_I)))
246 
247 /* ---------- DMA allocs ---------- */
248 
249 static inline struct asd_dma_tok *asd_dmatok_alloc(gfp_t flags)
250 {
251  return kmem_cache_alloc(asd_dma_token_cache, flags);
252 }
253 
254 static inline void asd_dmatok_free(struct asd_dma_tok *token)
255 {
257 }
258 
259 static inline struct asd_dma_tok *asd_alloc_coherent(struct asd_ha_struct *
260  asd_ha, size_t size,
261  gfp_t flags)
262 {
263  struct asd_dma_tok *token = asd_dmatok_alloc(flags);
264  if (token) {
265  token->size = size;
266  token->vaddr = dma_alloc_coherent(&asd_ha->pcidev->dev,
267  token->size,
268  &token->dma_handle,
269  flags);
270  if (!token->vaddr) {
271  asd_dmatok_free(token);
272  token = NULL;
273  }
274  }
275  return token;
276 }
277 
278 static inline void asd_free_coherent(struct asd_ha_struct *asd_ha,
279  struct asd_dma_tok *token)
280 {
281  if (token) {
282  dma_free_coherent(&asd_ha->pcidev->dev, token->size,
283  token->vaddr, token->dma_handle);
284  asd_dmatok_free(token);
285  }
286 }
287 
288 static inline void asd_init_ascb(struct asd_ha_struct *asd_ha,
289  struct asd_ascb *ascb)
290 {
291  INIT_LIST_HEAD(&ascb->list);
292  ascb->scb = ascb->dma_scb.vaddr;
293  ascb->ha = asd_ha;
294  ascb->timer.function = NULL;
295  init_timer(&ascb->timer);
296  ascb->tc_index = -1;
297 }
298 
299 /* Must be called with the tc_index_lock held!
300  */
301 static inline void asd_tc_index_release(struct asd_seq_data *seq, int index)
302 {
303  seq->tc_index_array[index] = NULL;
304  clear_bit(index, seq->tc_index_bitmap);
305 }
306 
307 /* Must be called with the tc_index_lock held!
308  */
309 static inline int asd_tc_index_get(struct asd_seq_data *seq, void *ptr)
310 {
311  int index;
312 
314  seq->tc_index_bitmap_bits);
315  if (index == seq->tc_index_bitmap_bits)
316  return -1;
317 
318  seq->tc_index_array[index] = ptr;
319  set_bit(index, seq->tc_index_bitmap);
320 
321  return index;
322 }
323 
324 /* Must be called with the tc_index_lock held!
325  */
326 static inline void *asd_tc_index_find(struct asd_seq_data *seq, int index)
327 {
328  return seq->tc_index_array[index];
329 }
330 
338 static inline void asd_ascb_free(struct asd_ascb *ascb)
339 {
340  if (ascb) {
341  struct asd_ha_struct *asd_ha = ascb->ha;
342  unsigned long flags;
343 
344  BUG_ON(!list_empty(&ascb->list));
345  spin_lock_irqsave(&ascb->ha->seq.tc_index_lock, flags);
346  asd_tc_index_release(&ascb->ha->seq, ascb->tc_index);
347  spin_unlock_irqrestore(&ascb->ha->seq.tc_index_lock, flags);
348  dma_pool_free(asd_ha->scb_pool, ascb->dma_scb.vaddr,
349  ascb->dma_scb.dma_handle);
351  }
352 }
353 
362 static inline void asd_ascb_free_list(struct asd_ascb *ascb_list)
363 {
364  LIST_HEAD(list);
365  struct list_head *n, *pos;
366 
367  __list_add(&list, ascb_list->list.prev, &ascb_list->list);
368  list_for_each_safe(pos, n, &list) {
369  list_del_init(pos);
370  asd_ascb_free(list_entry(pos, struct asd_ascb, list));
371  }
372 }
373 
374 /* ---------- Function declarations ---------- */
375 
376 int asd_init_hw(struct asd_ha_struct *asd_ha);
377 irqreturn_t asd_hw_isr(int irq, void *dev_id);
378 
379 
381  *asd_ha, int *num,
382  gfp_t gfp_mask);
383 
384 int asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
385  int num);
386 int asd_post_escb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
387  int num);
388 
389 int asd_init_post_escbs(struct asd_ha_struct *asd_ha);
390 void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc);
391 void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
392 void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
393 int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
394 
395 void asd_ascb_timedout(unsigned long data);
396 int asd_chip_hardrst(struct asd_ha_struct *asd_ha);
397 
398 #endif