root/drivers/scsi/aic94xx/aic94xx_hwi.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. asd_dmatok_alloc
  2. asd_dmatok_free
  3. asd_alloc_coherent
  4. asd_free_coherent
  5. asd_init_ascb
  6. asd_tc_index_release
  7. asd_tc_index_get
  8. asd_tc_index_find
  9. asd_ascb_free
  10. asd_ascb_free_list

   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * Aic94xx SAS/SATA driver hardware interface header file.
   4  *
   5  * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
   6  * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
   7  */
   8 
   9 #ifndef _AIC94XX_HWI_H_
  10 #define _AIC94XX_HWI_H_
  11 
  12 #include <linux/interrupt.h>
  13 #include <linux/pci.h>
  14 #include <linux/dma-mapping.h>
  15 
  16 #include <scsi/libsas.h>
  17 
  18 #include "aic94xx.h"
  19 #include "aic94xx_sas.h"
  20 
  21 /* Define ASD_MAX_PHYS to the maximum phys ever. Currently 8. */
  22 #define ASD_MAX_PHYS       8
  23 #define ASD_PCBA_SN_SIZE   12
  24 
  25 struct asd_ha_addrspace {
  26         void __iomem  *addr;
  27         unsigned long  start;       /* pci resource start */
  28         unsigned long  len;         /* pci resource len */
  29         unsigned long  flags;       /* pci resource flags */
  30 
  31         /* addresses internal to the host adapter */
  32         u32 swa_base; /* mmspace 1 (MBAR1) uses this only */
  33         u32 swb_base;
  34         u32 swc_base;
  35 };
  36 
  37 struct bios_struct {
  38         int    present;
  39         u8     maj;
  40         u8     min;
  41         u32    bld;
  42 };
  43 
  44 struct unit_element_struct {
  45         u16    num;
  46         u16    size;
  47         void   *area;
  48 };
  49 
  50 struct flash_struct {
  51         u32    bar;
  52         int    present;
  53         int    wide;
  54         u8     manuf;
  55         u8     dev_id;
  56         u8     sec_prot;
  57         u8     method;
  58 
  59         u32    dir_offs;
  60 };
  61 
  62 struct asd_phy_desc {
  63         /* From CTRL-A settings, then set to what is appropriate */
  64         u8     sas_addr[SAS_ADDR_SIZE];
  65         u8     max_sas_lrate;
  66         u8     min_sas_lrate;
  67         u8     max_sata_lrate;
  68         u8     min_sata_lrate;
  69         u8     flags;
  70 #define ASD_CRC_DIS  1
  71 #define ASD_SATA_SPINUP_HOLD 2
  72 
  73         u8     phy_control_0; /* mode 5 reg 0x160 */
  74         u8     phy_control_1; /* mode 5 reg 0x161 */
  75         u8     phy_control_2; /* mode 5 reg 0x162 */
  76         u8     phy_control_3; /* mode 5 reg 0x163 */
  77 };
  78 
  79 struct asd_dma_tok {
  80         void *vaddr;
  81         dma_addr_t dma_handle;
  82         size_t size;
  83 };
  84 
  85 struct hw_profile {
  86         struct bios_struct bios;
  87         struct unit_element_struct ue;
  88         struct flash_struct flash;
  89 
  90         u8     sas_addr[SAS_ADDR_SIZE];
  91         char   pcba_sn[ASD_PCBA_SN_SIZE+1];
  92 
  93         u8     enabled_phys;      /* mask of enabled phys */
  94         struct asd_phy_desc phy_desc[ASD_MAX_PHYS];
  95         u32    max_scbs;          /* absolute sequencer scb queue size */
  96         struct asd_dma_tok *scb_ext;
  97         u32    max_ddbs;
  98         struct asd_dma_tok *ddb_ext;
  99 
 100         spinlock_t ddb_lock;
 101         void  *ddb_bitmap;
 102 
 103         int    num_phys;          /* ENABLEABLE */
 104         int    max_phys;          /* REPORTED + ENABLEABLE */
 105 
 106         unsigned addr_range;      /* max # of addrs; max # of possible ports */
 107         unsigned port_name_base;
 108         unsigned dev_name_base;
 109         unsigned sata_name_base;
 110 };
 111 
 112 struct asd_ascb {
 113         struct list_head list;
 114         struct asd_ha_struct *ha;
 115 
 116         struct scb *scb;          /* equals dma_scb->vaddr */
 117         struct asd_dma_tok dma_scb;
 118         struct asd_dma_tok *sg_arr;
 119 
 120         void (*tasklet_complete)(struct asd_ascb *, struct done_list_struct *);
 121         u8     uldd_timer:1;
 122 
 123         /* internally generated command */
 124         struct timer_list timer;
 125         struct completion *completion;
 126         u8        tag_valid:1;
 127         __be16    tag;            /* error recovery only */
 128 
 129         /* If this is an Empty SCB, index of first edb in seq->edb_arr. */
 130         int    edb_index;
 131 
 132         /* Used by the timer timeout function. */
 133         int    tc_index;
 134 
 135         void   *uldd_task;
 136 };
 137 
 138 #define ASD_DL_SIZE_BITS   0x8
 139 #define ASD_DL_SIZE        (1<<(2+ASD_DL_SIZE_BITS))
 140 #define ASD_DEF_DL_TOGGLE  0x01
 141 
 142 struct asd_seq_data {
 143         spinlock_t pend_q_lock;
 144         u16    scbpro;
 145         int    pending;
 146         struct list_head pend_q;
 147         int    can_queue;         /* per adapter */
 148         struct asd_dma_tok next_scb; /* next scb to be delivered to CSEQ */
 149 
 150         spinlock_t tc_index_lock;
 151         void **tc_index_array;
 152         void *tc_index_bitmap;
 153         int   tc_index_bitmap_bits;
 154 
 155         struct tasklet_struct dl_tasklet;
 156         struct done_list_struct *dl; /* array of done list entries, equals */
 157         struct asd_dma_tok *actual_dl; /* actual_dl->vaddr */
 158         int    dl_toggle;
 159         int    dl_next;
 160 
 161         int    num_edbs;
 162         struct asd_dma_tok **edb_arr;
 163         int    num_escbs;
 164         struct asd_ascb **escb_arr; /* array of pointers to escbs */
 165 };
 166 
 167 /* This is an internal port structure. These are used to get accurate
 168  * phy_mask for updating DDB 0.
 169  */
 170 struct asd_port {
 171         u8  sas_addr[SAS_ADDR_SIZE];
 172         u8  attached_sas_addr[SAS_ADDR_SIZE];
 173         u32 phy_mask;
 174         int num_phys;
 175 };
 176 
 177 /* This is the Host Adapter structure.  It describes the hardware
 178  * SAS adapter.
 179  */
 180 struct asd_ha_struct {
 181         struct pci_dev   *pcidev;
 182         const char       *name;
 183 
 184         struct sas_ha_struct sas_ha;
 185 
 186         u8                revision_id;
 187 
 188         int               iospace;
 189         spinlock_t        iolock;
 190         struct asd_ha_addrspace io_handle[2];
 191 
 192         struct hw_profile hw_prof;
 193 
 194         struct asd_phy    phys[ASD_MAX_PHYS];
 195         spinlock_t        asd_ports_lock;
 196         struct asd_port   asd_ports[ASD_MAX_PHYS];
 197         struct asd_sas_port   ports[ASD_MAX_PHYS];
 198 
 199         struct dma_pool  *scb_pool;
 200 
 201         struct asd_seq_data  seq; /* sequencer related */
 202         u32    bios_status;
 203         const struct firmware *bios_image;
 204 };
 205 
 206 /* ---------- Common macros ---------- */
 207 
 208 #define ASD_BUSADDR_LO(__dma_handle) ((u32)(__dma_handle))
 209 #define ASD_BUSADDR_HI(__dma_handle) (((sizeof(dma_addr_t))==8)     \
 210                                     ? ((u32)((__dma_handle) >> 32)) \
 211                                     : ((u32)0))
 212 
 213 #define dev_to_asd_ha(__dev)  pci_get_drvdata(to_pci_dev(__dev))
 214 #define SCB_SITE_VALID(__site_no) (((__site_no) & 0xF0FF) != 0x00FF   \
 215                                  && ((__site_no) & 0xF0FF) > 0x001F)
 216 /* For each bit set in __lseq_mask, set __lseq to equal the bit
 217  * position of the set bit and execute the statement following.
 218  * __mc is the temporary mask, used as a mask "counter".
 219  */
 220 #define for_each_sequencer(__lseq_mask, __mc, __lseq)                        \
 221         for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
 222                 if (((__mc) & 1))
 223 #define for_each_phy(__lseq_mask, __mc, __lseq)                              \
 224         for ((__mc)=(__lseq_mask),(__lseq)=0;(__mc)!=0;(__lseq++),(__mc)>>=1)\
 225                 if (((__mc) & 1))
 226 
 227 #define PHY_ENABLED(_HA, _I) ((_HA)->hw_prof.enabled_phys & (1<<(_I)))
 228 
 229 /* ---------- DMA allocs ---------- */
 230 
 231 static inline struct asd_dma_tok *asd_dmatok_alloc(gfp_t flags)
 232 {
 233         return kmem_cache_alloc(asd_dma_token_cache, flags);
 234 }
 235 
 236 static inline void asd_dmatok_free(struct asd_dma_tok *token)
 237 {
 238         kmem_cache_free(asd_dma_token_cache, token);
 239 }
 240 
 241 static inline struct asd_dma_tok *asd_alloc_coherent(struct asd_ha_struct *
 242                                                      asd_ha, size_t size,
 243                                                      gfp_t flags)
 244 {
 245         struct asd_dma_tok *token = asd_dmatok_alloc(flags);
 246         if (token) {
 247                 token->size = size;
 248                 token->vaddr = dma_alloc_coherent(&asd_ha->pcidev->dev,
 249                                                   token->size,
 250                                                   &token->dma_handle,
 251                                                   flags);
 252                 if (!token->vaddr) {
 253                         asd_dmatok_free(token);
 254                         token = NULL;
 255                 }
 256         }
 257         return token;
 258 }
 259 
 260 static inline void asd_free_coherent(struct asd_ha_struct *asd_ha,
 261                                      struct asd_dma_tok *token)
 262 {
 263         if (token) {
 264                 dma_free_coherent(&asd_ha->pcidev->dev, token->size,
 265                                   token->vaddr, token->dma_handle);
 266                 asd_dmatok_free(token);
 267         }
 268 }
 269 
 270 static inline void asd_init_ascb(struct asd_ha_struct *asd_ha,
 271                                  struct asd_ascb *ascb)
 272 {
 273         INIT_LIST_HEAD(&ascb->list);
 274         ascb->scb = ascb->dma_scb.vaddr;
 275         ascb->ha = asd_ha;
 276         timer_setup(&ascb->timer, NULL, 0);
 277         ascb->tc_index = -1;
 278 }
 279 
 280 /* Must be called with the tc_index_lock held!
 281  */
 282 static inline void asd_tc_index_release(struct asd_seq_data *seq, int index)
 283 {
 284         seq->tc_index_array[index] = NULL;
 285         clear_bit(index, seq->tc_index_bitmap);
 286 }
 287 
 288 /* Must be called with the tc_index_lock held!
 289  */
 290 static inline int asd_tc_index_get(struct asd_seq_data *seq, void *ptr)
 291 {
 292         int index;
 293 
 294         index = find_first_zero_bit(seq->tc_index_bitmap,
 295                                     seq->tc_index_bitmap_bits);
 296         if (index == seq->tc_index_bitmap_bits)
 297                 return -1;
 298 
 299         seq->tc_index_array[index] = ptr;
 300         set_bit(index, seq->tc_index_bitmap);
 301 
 302         return index;
 303 }
 304 
 305 /* Must be called with the tc_index_lock held!
 306  */
 307 static inline void *asd_tc_index_find(struct asd_seq_data *seq, int index)
 308 {
 309         return seq->tc_index_array[index];
 310 }
 311 
 312 /**
 313  * asd_ascb_free -- free a single aSCB after is has completed
 314  * @ascb: pointer to the aSCB of interest
 315  *
 316  * This frees an aSCB after it has been executed/completed by
 317  * the sequencer.
 318  */
 319 static inline void asd_ascb_free(struct asd_ascb *ascb)
 320 {
 321         if (ascb) {
 322                 struct asd_ha_struct *asd_ha = ascb->ha;
 323                 unsigned long flags;
 324 
 325                 BUG_ON(!list_empty(&ascb->list));
 326                 spin_lock_irqsave(&ascb->ha->seq.tc_index_lock, flags);
 327                 asd_tc_index_release(&ascb->ha->seq, ascb->tc_index);
 328                 spin_unlock_irqrestore(&ascb->ha->seq.tc_index_lock, flags);
 329                 dma_pool_free(asd_ha->scb_pool, ascb->dma_scb.vaddr,
 330                               ascb->dma_scb.dma_handle);
 331                 kmem_cache_free(asd_ascb_cache, ascb);
 332         }
 333 }
 334 
 335 /**
 336  * asd_ascb_list_free -- free a list of ascbs
 337  * @ascb_list: a list of ascbs
 338  *
 339  * This function will free a list of ascbs allocated by asd_ascb_alloc_list.
 340  * It is used when say the scb queueing function returned QUEUE_FULL,
 341  * and we do not need the ascbs any more.
 342  */
 343 static inline void asd_ascb_free_list(struct asd_ascb *ascb_list)
 344 {
 345         LIST_HEAD(list);
 346         struct list_head *n, *pos;
 347 
 348         __list_add(&list, ascb_list->list.prev, &ascb_list->list);
 349         list_for_each_safe(pos, n, &list) {
 350                 list_del_init(pos);
 351                 asd_ascb_free(list_entry(pos, struct asd_ascb, list));
 352         }
 353 }
 354 
 355 /* ---------- Function declarations ---------- */
 356 
 357 int  asd_init_hw(struct asd_ha_struct *asd_ha);
 358 irqreturn_t asd_hw_isr(int irq, void *dev_id);
 359 
 360 
 361 struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
 362                                      *asd_ha, int *num,
 363                                      gfp_t gfp_mask);
 364 
 365 int  asd_post_ascb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
 366                         int num);
 367 int  asd_post_escb_list(struct asd_ha_struct *asd_ha, struct asd_ascb *ascb,
 368                         int num);
 369 
 370 int  asd_init_post_escbs(struct asd_ha_struct *asd_ha);
 371 void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc);
 372 void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 373 void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 374 int  asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
 375 
 376 void asd_ascb_timedout(struct timer_list *t);
 377 int  asd_chip_hardrst(struct asd_ha_struct *asd_ha);
 378 
 379 #endif

/* [<][>][^][v][top][bottom][index][help] */