1edd16368SStephen M. Cameron /* 2edd16368SStephen M. Cameron * Disk Array driver for HP Smart Array SAS controllers 3edd16368SStephen M. Cameron * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. 4edd16368SStephen M. Cameron * 5edd16368SStephen M. Cameron * This program is free software; you can redistribute it and/or modify 6edd16368SStephen M. Cameron * it under the terms of the GNU General Public License as published by 7edd16368SStephen M. Cameron * the Free Software Foundation; version 2 of the License. 8edd16368SStephen M. Cameron * 9edd16368SStephen M. Cameron * This program is distributed in the hope that it will be useful, 10edd16368SStephen M. Cameron * but WITHOUT ANY WARRANTY; without even the implied warranty of 11edd16368SStephen M. Cameron * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 12edd16368SStephen M. Cameron * NON INFRINGEMENT. See the GNU General Public License for more details. 13edd16368SStephen M. Cameron * 14edd16368SStephen M. Cameron * You should have received a copy of the GNU General Public License 15edd16368SStephen M. Cameron * along with this program; if not, write to the Free Software 16edd16368SStephen M. Cameron * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17edd16368SStephen M. Cameron * 18edd16368SStephen M. Cameron * Questions/Comments/Bugfixes to iss_storagedev@hp.com 19edd16368SStephen M. Cameron * 20edd16368SStephen M. Cameron */ 21edd16368SStephen M. Cameron #ifndef HPSA_H 22edd16368SStephen M. Cameron #define HPSA_H 23edd16368SStephen M. Cameron 24edd16368SStephen M. Cameron #include <scsi/scsicam.h> 25edd16368SStephen M. Cameron 26edd16368SStephen M. Cameron #define IO_OK 0 27edd16368SStephen M. Cameron #define IO_ERROR 1 28edd16368SStephen M. Cameron 29edd16368SStephen M. Cameron struct ctlr_info; 30edd16368SStephen M. Cameron 31edd16368SStephen M. Cameron struct access_method { 32edd16368SStephen M. Cameron void (*submit_command)(struct ctlr_info *h, 33edd16368SStephen M. Cameron struct CommandList *c); 34edd16368SStephen M. Cameron void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); 35edd16368SStephen M. Cameron unsigned long (*fifo_full)(struct ctlr_info *h); 36900c5440SStephen M. Cameron bool (*intr_pending)(struct ctlr_info *h); 37edd16368SStephen M. Cameron unsigned long (*command_completed)(struct ctlr_info *h); 38edd16368SStephen M. Cameron }; 39edd16368SStephen M. Cameron 40edd16368SStephen M. Cameron struct hpsa_scsi_dev_t { 41edd16368SStephen M. Cameron int devtype; 42edd16368SStephen M. Cameron int bus, target, lun; /* as presented to the OS */ 43edd16368SStephen M. Cameron unsigned char scsi3addr[8]; /* as presented to the HW */ 44edd16368SStephen M. Cameron #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" 45edd16368SStephen M. Cameron unsigned char device_id[16]; /* from inquiry pg. 0x83 */ 46edd16368SStephen M. Cameron unsigned char vendor[8]; /* bytes 8-15 of inquiry data */ 47edd16368SStephen M. Cameron unsigned char model[16]; /* bytes 16-31 of inquiry data */ 48edd16368SStephen M. Cameron unsigned char raid_level; /* from inquiry page 0xC1 */ 49edd16368SStephen M. Cameron }; 50edd16368SStephen M. Cameron 51edd16368SStephen M. Cameron struct ctlr_info { 52edd16368SStephen M. Cameron int ctlr; 53edd16368SStephen M. Cameron char devname[8]; 54edd16368SStephen M. Cameron char *product_name; 55edd16368SStephen M. Cameron struct pci_dev *pdev; 5601a02ffcSStephen M. Cameron u32 board_id; 57edd16368SStephen M. Cameron void __iomem *vaddr; 58edd16368SStephen M. Cameron unsigned long paddr; 59edd16368SStephen M. Cameron int nr_cmds; /* Number of commands allowed on this controller */ 60edd16368SStephen M. Cameron struct CfgTable __iomem *cfgtable; 61303932fdSDon Brace int max_sg_entries; 62edd16368SStephen M. Cameron int interrupts_enabled; 63edd16368SStephen M. Cameron int major; 64edd16368SStephen M. Cameron int max_commands; 65edd16368SStephen M. Cameron int commands_outstanding; 66edd16368SStephen M. Cameron int max_outstanding; /* Debug */ 67edd16368SStephen M. Cameron int usage_count; /* number of opens all all minor devices */ 68303932fdSDon Brace # define PERF_MODE_INT 0 69303932fdSDon Brace # define DOORBELL_INT 1 70edd16368SStephen M. Cameron # define SIMPLE_MODE_INT 2 71edd16368SStephen M. Cameron # define MEMQ_MODE_INT 3 72edd16368SStephen M. Cameron unsigned int intr[4]; 73edd16368SStephen M. Cameron unsigned int msix_vector; 74edd16368SStephen M. Cameron unsigned int msi_vector; 75a9a3a273SStephen M. Cameron int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */ 76edd16368SStephen M. Cameron struct access_method access; 77edd16368SStephen M. Cameron 78edd16368SStephen M. Cameron /* queue and queue Info */ 799e0fc764SStephen M. Cameron struct list_head reqQ; 809e0fc764SStephen M. Cameron struct list_head cmpQ; 81edd16368SStephen M. Cameron unsigned int Qdepth; 82edd16368SStephen M. Cameron unsigned int maxQsinceinit; 83edd16368SStephen M. Cameron unsigned int maxSG; 84edd16368SStephen M. Cameron spinlock_t lock; 8533a2ffceSStephen M. Cameron int maxsgentries; 8633a2ffceSStephen M. Cameron u8 max_cmd_sg_entries; 8733a2ffceSStephen M. Cameron int chainsize; 8833a2ffceSStephen M. Cameron struct SGDescriptor **cmd_sg_list; 89edd16368SStephen M. Cameron 90edd16368SStephen M. Cameron /* pointers to command and error info pool */ 91edd16368SStephen M. Cameron struct CommandList *cmd_pool; 92edd16368SStephen M. Cameron dma_addr_t cmd_pool_dhandle; 93edd16368SStephen M. Cameron struct ErrorInfo *errinfo_pool; 94edd16368SStephen M. Cameron dma_addr_t errinfo_pool_dhandle; 95edd16368SStephen M. Cameron unsigned long *cmd_pool_bits; 96edd16368SStephen M. Cameron int nr_allocs; 97edd16368SStephen M. Cameron int nr_frees; 98edd16368SStephen M. Cameron int busy_initializing; 99edd16368SStephen M. Cameron int busy_scanning; 100a08a8471SStephen M. Cameron int scan_finished; 101a08a8471SStephen M. Cameron spinlock_t scan_lock; 102a08a8471SStephen M. Cameron wait_queue_head_t scan_wait_queue; 103edd16368SStephen M. Cameron 104edd16368SStephen M. Cameron struct Scsi_Host *scsi_host; 105edd16368SStephen M. Cameron spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ 106edd16368SStephen M. Cameron int ndevices; /* number of used elements in .dev[] array. */ 107edd16368SStephen M. Cameron #define HPSA_MAX_SCSI_DEVS_PER_HBA 256 108edd16368SStephen M. Cameron struct hpsa_scsi_dev_t *dev[HPSA_MAX_SCSI_DEVS_PER_HBA]; 109303932fdSDon Brace /* 110303932fdSDon Brace * Performant mode tables. 111303932fdSDon Brace */ 112303932fdSDon Brace u32 trans_support; 113303932fdSDon Brace u32 trans_offset; 114303932fdSDon Brace struct TransTable_struct *transtable; 115303932fdSDon Brace unsigned long transMethod; 116303932fdSDon Brace 117303932fdSDon Brace /* 118303932fdSDon Brace * Performant mode completion buffer 119303932fdSDon Brace */ 120303932fdSDon Brace u64 *reply_pool; 121303932fdSDon Brace dma_addr_t reply_pool_dhandle; 122303932fdSDon Brace u64 *reply_pool_head; 123303932fdSDon Brace size_t reply_pool_size; 124303932fdSDon Brace unsigned char reply_pool_wraparound; 125303932fdSDon Brace u32 *blockFetchTable; 126339b2b14SStephen M. Cameron unsigned char *hba_inquiry_data; 127edd16368SStephen M. Cameron }; 128edd16368SStephen M. Cameron #define HPSA_ABORT_MSG 0 129edd16368SStephen M. Cameron #define HPSA_DEVICE_RESET_MSG 1 130edd16368SStephen M. Cameron #define HPSA_BUS_RESET_MSG 2 131edd16368SStephen M. Cameron #define HPSA_HOST_RESET_MSG 3 132edd16368SStephen M. Cameron #define HPSA_MSG_SEND_RETRY_LIMIT 10 133edd16368SStephen M. Cameron #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000 134edd16368SStephen M. Cameron 135edd16368SStephen M. Cameron /* Maximum time in seconds driver will wait for command completions 136edd16368SStephen M. Cameron * when polling before giving up. 137edd16368SStephen M. Cameron */ 138edd16368SStephen M. Cameron #define HPSA_MAX_POLL_TIME_SECS (20) 139edd16368SStephen M. Cameron 140edd16368SStephen M. Cameron /* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines 141edd16368SStephen M. Cameron * how many times to retry TEST UNIT READY on a device 142edd16368SStephen M. Cameron * while waiting for it to become ready before giving up. 143edd16368SStephen M. Cameron * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval 144edd16368SStephen M. Cameron * between sending TURs while waiting for a device 145edd16368SStephen M. Cameron * to become ready. 146edd16368SStephen M. Cameron */ 147edd16368SStephen M. Cameron #define HPSA_TUR_RETRY_LIMIT (20) 148edd16368SStephen M. Cameron #define HPSA_MAX_WAIT_INTERVAL_SECS (30) 149edd16368SStephen M. Cameron 150edd16368SStephen M. Cameron /* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board 151edd16368SStephen M. Cameron * to become ready, in seconds, before giving up on it. 152edd16368SStephen M. Cameron * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait 153edd16368SStephen M. Cameron * between polling the board to see if it is ready, in 154edd16368SStephen M. Cameron * milliseconds. HPSA_BOARD_READY_POLL_INTERVAL and 155edd16368SStephen M. Cameron * HPSA_BOARD_READY_ITERATIONS are derived from those. 156edd16368SStephen M. Cameron */ 157edd16368SStephen M. Cameron #define HPSA_BOARD_READY_WAIT_SECS (120) 158fe5389c8SStephen M. Cameron #define HPSA_BOARD_NOT_READY_WAIT_SECS (10) 159edd16368SStephen M. Cameron #define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100) 160edd16368SStephen M. Cameron #define HPSA_BOARD_READY_POLL_INTERVAL \ 161edd16368SStephen M. Cameron ((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000) 162edd16368SStephen M. Cameron #define HPSA_BOARD_READY_ITERATIONS \ 163edd16368SStephen M. Cameron ((HPSA_BOARD_READY_WAIT_SECS * 1000) / \ 164edd16368SStephen M. Cameron HPSA_BOARD_READY_POLL_INTERVAL_MSECS) 165fe5389c8SStephen M. Cameron #define HPSA_BOARD_NOT_READY_ITERATIONS \ 166fe5389c8SStephen M. Cameron ((HPSA_BOARD_NOT_READY_WAIT_SECS * 1000) / \ 167fe5389c8SStephen M. Cameron HPSA_BOARD_READY_POLL_INTERVAL_MSECS) 168edd16368SStephen M. Cameron #define HPSA_POST_RESET_PAUSE_MSECS (3000) 169edd16368SStephen M. Cameron #define HPSA_POST_RESET_NOOP_RETRIES (12) 170edd16368SStephen M. Cameron 171edd16368SStephen M. Cameron /* Defining the diffent access_menthods */ 172edd16368SStephen M. Cameron /* 173edd16368SStephen M. Cameron * Memory mapped FIFO interface (SMART 53xx cards) 174edd16368SStephen M. Cameron */ 175edd16368SStephen M. Cameron #define SA5_DOORBELL 0x20 176edd16368SStephen M. Cameron #define SA5_REQUEST_PORT_OFFSET 0x40 177edd16368SStephen M. Cameron #define SA5_REPLY_INTR_MASK_OFFSET 0x34 178edd16368SStephen M. Cameron #define SA5_REPLY_PORT_OFFSET 0x44 179edd16368SStephen M. Cameron #define SA5_INTR_STATUS 0x30 180edd16368SStephen M. Cameron #define SA5_SCRATCHPAD_OFFSET 0xB0 181edd16368SStephen M. Cameron 182edd16368SStephen M. Cameron #define SA5_CTCFG_OFFSET 0xB4 183edd16368SStephen M. Cameron #define SA5_CTMEM_OFFSET 0xB8 184edd16368SStephen M. Cameron 185edd16368SStephen M. Cameron #define SA5_INTR_OFF 0x08 186edd16368SStephen M. Cameron #define SA5B_INTR_OFF 0x04 187edd16368SStephen M. Cameron #define SA5_INTR_PENDING 0x08 188edd16368SStephen M. Cameron #define SA5B_INTR_PENDING 0x04 189edd16368SStephen M. Cameron #define FIFO_EMPTY 0xffffffff 190edd16368SStephen M. Cameron #define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ 191edd16368SStephen M. Cameron 192edd16368SStephen M. Cameron #define HPSA_ERROR_BIT 0x02 193edd16368SStephen M. Cameron 194303932fdSDon Brace /* Performant mode flags */ 195303932fdSDon Brace #define SA5_PERF_INTR_PENDING 0x04 196303932fdSDon Brace #define SA5_PERF_INTR_OFF 0x05 197303932fdSDon Brace #define SA5_OUTDB_STATUS_PERF_BIT 0x01 198303932fdSDon Brace #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 199303932fdSDon Brace #define SA5_OUTDB_CLEAR 0xA0 200303932fdSDon Brace #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 201303932fdSDon Brace #define SA5_OUTDB_STATUS 0x9C 202303932fdSDon Brace 203303932fdSDon Brace 204edd16368SStephen M. Cameron #define HPSA_INTR_ON 1 205edd16368SStephen M. Cameron #define HPSA_INTR_OFF 0 206edd16368SStephen M. Cameron /* 207edd16368SStephen M. Cameron Send the command to the hardware 208edd16368SStephen M. Cameron */ 209edd16368SStephen M. Cameron static void SA5_submit_command(struct ctlr_info *h, 210edd16368SStephen M. Cameron struct CommandList *c) 211edd16368SStephen M. Cameron { 212303932fdSDon Brace dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr, 213303932fdSDon Brace c->Header.Tag.lower); 214edd16368SStephen M. Cameron writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); 215edd16368SStephen M. Cameron h->commands_outstanding++; 216edd16368SStephen M. Cameron if (h->commands_outstanding > h->max_outstanding) 217edd16368SStephen M. Cameron h->max_outstanding = h->commands_outstanding; 218edd16368SStephen M. Cameron } 219edd16368SStephen M. Cameron 220edd16368SStephen M. Cameron /* 221edd16368SStephen M. Cameron * This card is the opposite of the other cards. 222edd16368SStephen M. Cameron * 0 turns interrupts on... 223edd16368SStephen M. Cameron * 0x08 turns them off... 224edd16368SStephen M. Cameron */ 225edd16368SStephen M. Cameron static void SA5_intr_mask(struct ctlr_info *h, unsigned long val) 226edd16368SStephen M. Cameron { 227edd16368SStephen M. Cameron if (val) { /* Turn interrupts on */ 228edd16368SStephen M. Cameron h->interrupts_enabled = 1; 229edd16368SStephen M. Cameron writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 230edd16368SStephen M. Cameron } else { /* Turn them off */ 231edd16368SStephen M. Cameron h->interrupts_enabled = 0; 232edd16368SStephen M. Cameron writel(SA5_INTR_OFF, 233edd16368SStephen M. Cameron h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 234edd16368SStephen M. Cameron } 235edd16368SStephen M. Cameron } 236303932fdSDon Brace 237303932fdSDon Brace static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val) 238303932fdSDon Brace { 239303932fdSDon Brace if (val) { /* turn on interrupts */ 240303932fdSDon Brace h->interrupts_enabled = 1; 241303932fdSDon Brace writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 242303932fdSDon Brace } else { 243303932fdSDon Brace h->interrupts_enabled = 0; 244303932fdSDon Brace writel(SA5_PERF_INTR_OFF, 245303932fdSDon Brace h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 246303932fdSDon Brace } 247303932fdSDon Brace } 248303932fdSDon Brace 249303932fdSDon Brace static unsigned long SA5_performant_completed(struct ctlr_info *h) 250303932fdSDon Brace { 251303932fdSDon Brace unsigned long register_value = FIFO_EMPTY; 252303932fdSDon Brace 253303932fdSDon Brace /* flush the controller write of the reply queue by reading 254303932fdSDon Brace * outbound doorbell status register. 255303932fdSDon Brace */ 256303932fdSDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 257303932fdSDon Brace /* msi auto clears the interrupt pending bit. */ 258303932fdSDon Brace if (!(h->msi_vector || h->msix_vector)) { 259303932fdSDon Brace writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); 260303932fdSDon Brace /* Do a read in order to flush the write to the controller 261303932fdSDon Brace * (as per spec.) 262303932fdSDon Brace */ 263303932fdSDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 264303932fdSDon Brace } 265303932fdSDon Brace 266303932fdSDon Brace if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { 267303932fdSDon Brace register_value = *(h->reply_pool_head); 268303932fdSDon Brace (h->reply_pool_head)++; 269303932fdSDon Brace h->commands_outstanding--; 270303932fdSDon Brace } else { 271303932fdSDon Brace register_value = FIFO_EMPTY; 272303932fdSDon Brace } 273303932fdSDon Brace /* Check for wraparound */ 274303932fdSDon Brace if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { 275303932fdSDon Brace h->reply_pool_head = h->reply_pool; 276303932fdSDon Brace h->reply_pool_wraparound ^= 1; 277303932fdSDon Brace } 278303932fdSDon Brace 279303932fdSDon Brace return register_value; 280303932fdSDon Brace } 281303932fdSDon Brace 282edd16368SStephen M. Cameron /* 283edd16368SStephen M. Cameron * Returns true if fifo is full. 284edd16368SStephen M. Cameron * 285edd16368SStephen M. Cameron */ 286edd16368SStephen M. Cameron static unsigned long SA5_fifo_full(struct ctlr_info *h) 287edd16368SStephen M. Cameron { 288edd16368SStephen M. Cameron if (h->commands_outstanding >= h->max_commands) 289edd16368SStephen M. Cameron return 1; 290edd16368SStephen M. Cameron else 291edd16368SStephen M. Cameron return 0; 292edd16368SStephen M. Cameron 293edd16368SStephen M. Cameron } 294edd16368SStephen M. Cameron /* 295edd16368SStephen M. Cameron * returns value read from hardware. 296edd16368SStephen M. Cameron * returns FIFO_EMPTY if there is nothing to read 297edd16368SStephen M. Cameron */ 298edd16368SStephen M. Cameron static unsigned long SA5_completed(struct ctlr_info *h) 299edd16368SStephen M. Cameron { 300edd16368SStephen M. Cameron unsigned long register_value 301edd16368SStephen M. Cameron = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); 302edd16368SStephen M. Cameron 303edd16368SStephen M. Cameron if (register_value != FIFO_EMPTY) 304edd16368SStephen M. Cameron h->commands_outstanding--; 305edd16368SStephen M. Cameron 306edd16368SStephen M. Cameron #ifdef HPSA_DEBUG 307edd16368SStephen M. Cameron if (register_value != FIFO_EMPTY) 30884ca0be2SStephen M. Cameron dev_dbg(&h->pdev->dev, "Read %lx back from board\n", 309edd16368SStephen M. Cameron register_value); 310edd16368SStephen M. Cameron else 31184ca0be2SStephen M. Cameron dev_dbg(&h->pdev->dev, "hpsa: FIFO Empty read\n"); 312edd16368SStephen M. Cameron #endif 313edd16368SStephen M. Cameron 314edd16368SStephen M. Cameron return register_value; 315edd16368SStephen M. Cameron } 316edd16368SStephen M. Cameron /* 317edd16368SStephen M. Cameron * Returns true if an interrupt is pending.. 318edd16368SStephen M. Cameron */ 319900c5440SStephen M. Cameron static bool SA5_intr_pending(struct ctlr_info *h) 320edd16368SStephen M. Cameron { 321edd16368SStephen M. Cameron unsigned long register_value = 322edd16368SStephen M. Cameron readl(h->vaddr + SA5_INTR_STATUS); 32384ca0be2SStephen M. Cameron dev_dbg(&h->pdev->dev, "intr_pending %lx\n", register_value); 324900c5440SStephen M. Cameron return register_value & SA5_INTR_PENDING; 325edd16368SStephen M. Cameron } 326edd16368SStephen M. Cameron 327303932fdSDon Brace static bool SA5_performant_intr_pending(struct ctlr_info *h) 328303932fdSDon Brace { 329303932fdSDon Brace unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS); 330303932fdSDon Brace 331303932fdSDon Brace if (!register_value) 332303932fdSDon Brace return false; 333303932fdSDon Brace 334303932fdSDon Brace if (h->msi_vector || h->msix_vector) 335303932fdSDon Brace return true; 336303932fdSDon Brace 337303932fdSDon Brace /* Read outbound doorbell to flush */ 338303932fdSDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 339303932fdSDon Brace return register_value & SA5_OUTDB_STATUS_PERF_BIT; 340303932fdSDon Brace } 341edd16368SStephen M. Cameron 342edd16368SStephen M. Cameron static struct access_method SA5_access = { 343edd16368SStephen M. Cameron SA5_submit_command, 344edd16368SStephen M. Cameron SA5_intr_mask, 345edd16368SStephen M. Cameron SA5_fifo_full, 346edd16368SStephen M. Cameron SA5_intr_pending, 347edd16368SStephen M. Cameron SA5_completed, 348edd16368SStephen M. Cameron }; 349edd16368SStephen M. Cameron 350303932fdSDon Brace static struct access_method SA5_performant_access = { 351303932fdSDon Brace SA5_submit_command, 352303932fdSDon Brace SA5_performant_intr_mask, 353303932fdSDon Brace SA5_fifo_full, 354303932fdSDon Brace SA5_performant_intr_pending, 355303932fdSDon Brace SA5_performant_completed, 356303932fdSDon Brace }; 357303932fdSDon Brace 358edd16368SStephen M. Cameron struct board_type { 35901a02ffcSStephen M. Cameron u32 board_id; 360edd16368SStephen M. Cameron char *product_name; 361edd16368SStephen M. Cameron struct access_method *access; 362edd16368SStephen M. Cameron }; 363edd16368SStephen M. Cameron 364edd16368SStephen M. Cameron #endif /* HPSA_H */ 365edd16368SStephen M. Cameron 366