1 /*- 2 * Copyright (c) 2003-2004 HighPoint Technologies, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 #ifndef _OSBSD_H_ 29 #define _OSBSD_H_ 30 31 #include <sys/bus.h> 32 #include <sys/resource.h> 33 #include <sys/eventhandler.h> 34 35 #include <machine/bus_memio.h> 36 #include <machine/bus.h> 37 #include <machine/resource.h> 38 #include <machine/bus.h> 39 #include <sys/rman.h> 40 41 #include <cam/cam.h> 42 #include <cam/cam_ccb.h> 43 #include <cam/cam_debug.h> 44 #include <cam/cam_sim.h> 45 #include <cam/cam_xpt_sim.h> 46 #include <cam/cam_periph.h> 47 #include <cam/scsi/scsi_all.h> 48 #include <cam/scsi/scsi_message.h> 49 50 extern intrmask_t lock_driver(void); 51 extern void unlock_driver(intrmask_t spl); 52 53 typedef struct 54 { 55 UCHAR status; /* 0 nonbootable; 80h bootable */ 56 UCHAR start_head; 57 USHORT start_sector; 58 UCHAR type; 59 UCHAR end_head; 60 USHORT end_sector; 61 ULONG start_abs_sector; 62 ULONG num_of_sector; 63 } partition; 64 65 typedef struct _INQUIRYDATA { 66 UCHAR DeviceType : 5; 67 UCHAR DeviceTypeQualifier : 3; 68 UCHAR DeviceTypeModifier : 7; 69 UCHAR RemovableMedia : 1; 70 UCHAR Versions; 71 UCHAR ResponseDataFormat; 72 UCHAR AdditionalLength; 73 UCHAR Reserved[2]; 74 UCHAR SoftReset : 1; 75 UCHAR CommandQueue : 1; 76 UCHAR Reserved2 : 1; 77 UCHAR LinkedCommands : 1; 78 UCHAR Synchronous : 1; 79 UCHAR Wide16Bit : 1; 80 UCHAR Wide32Bit : 1; 81 UCHAR RelativeAddressing : 1; 82 UCHAR VendorId[8]; 83 UCHAR ProductId[16]; 84 UCHAR ProductRevisionLevel[4]; 85 UCHAR VendorSpecific[20]; 86 UCHAR Reserved3[40]; 87 } INQUIRYDATA, *PINQUIRYDATA; 88 89 typedef struct _READ_CAPACITY_DATA { 90 ULONG LogicalBlockAddress; 91 ULONG BytesPerBlock; 92 } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA; 93 94 #define MV_IAL_HT_SACOALT_DEFAULT 1 95 #define MV_IAL_HT_SAITMTH_DEFAULT 1 96 97 /****************************************/ 98 /* GENERAL Definitions */ 99 /****************************************/ 100 101 /* Bits for HD_ERROR */ 102 #define NM_ERR 0x02 /* media present */ 103 #define ABRT_ERR 0x04 /* Command aborted */ 104 #define MCR_ERR 0x08 /* media change request */ 105 #define IDNF_ERR 0x10 /* ID field not found */ 106 #define MC_ERR 0x20 /* media changed */ 107 #define UNC_ERR 0x40 /* Uncorrect data */ 108 #define WP_ERR 0x40 /* write protect */ 109 #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ 110 111 #define REQUESTS_ARRAY_SIZE (9 * MV_EDMA_REQUEST_QUEUE_SIZE) /* 9 K bytes */ 112 #define RESPONSES_ARRAY_SIZE (12*MV_EDMA_RESPONSE_QUEUE_SIZE) /* 3 K bytes */ 113 114 #define PRD_ENTRIES_PER_CMD (MAX_SG_DESCRIPTORS+1) 115 #define PRD_ENTRIES_SIZE (MV_EDMA_PRD_ENTRY_SIZE*PRD_ENTRIES_PER_CMD) 116 #define PRD_TABLES_FOR_VBUS (MV_SATA_CHANNELS_NUM*MV_EDMA_QUEUE_LENGTH) 117 118 typedef enum _SataEvent { 119 SATA_EVENT_NO_CHANGE = 0, 120 SATA_EVENT_CHANNEL_CONNECTED, 121 SATA_EVENT_CHANNEL_DISCONNECTED 122 } SATA_EVENT; 123 124 typedef ULONG_PTR dma_addr_t; 125 126 typedef struct _MV_CHANNEL { 127 unsigned int maxUltraDmaModeSupported; 128 unsigned int maxDmaModeSupported; 129 unsigned int maxPioModeSupported; 130 MV_BOOLEAN online; 131 } MV_CHANNEL; 132 133 struct _privCommand; 134 135 typedef struct IALAdapter { 136 struct cam_path *path; 137 device_t hpt_dev; /* bus device */ 138 struct resource *hpt_irq; /* interrupt */ 139 void *hpt_intr; /* interrupt handle */ 140 struct resource *mem_res; 141 bus_space_handle_t mem_bsh; 142 bus_space_tag_t mem_btag; 143 bus_dma_tag_t parent_dmat; 144 bus_dma_tag_t req_dmat; 145 bus_dmamap_t req_map; 146 bus_dma_tag_t resp_dmat; 147 bus_dmamap_t resp_map; 148 bus_dma_tag_t prd_dmat; 149 bus_dmamap_t prd_map; 150 bus_dma_tag_t buf_dmat; 151 152 struct IALAdapter *next; 153 154 MV_SATA_ADAPTER mvSataAdapter; 155 MV_CHANNEL mvChannel[MV_SATA_CHANNELS_NUM]; 156 MV_U8 *requestsArrayBaseAddr; 157 MV_U8 *requestsArrayBaseAlignedAddr; 158 dma_addr_t requestsArrayBaseDmaAddr; 159 dma_addr_t requestsArrayBaseDmaAlignedAddr; 160 MV_U8 *responsesArrayBaseAddr; 161 MV_U8 *responsesArrayBaseAlignedAddr; 162 dma_addr_t responsesArrayBaseDmaAddr; 163 dma_addr_t responsesArrayBaseDmaAlignedAddr; 164 SATA_EVENT sataEvents[MV_SATA_CHANNELS_NUM]; 165 166 struct callout_handle event_timer_connect; 167 struct callout_handle event_timer_disconnect; 168 169 struct _VBus VBus; 170 struct _VDevice VDevices[MV_SATA_CHANNELS_NUM]; 171 PCommand pCommandBlocks; 172 struct _privCommand *pPrivateBlocks; 173 TAILQ_HEAD(, _privCommand) PrivCmdTQH; 174 PUCHAR prdTableAddr; 175 ULONG prdTableDmaAddr; 176 void* pFreePRDLink; 177 178 union ccb *pending_Q; 179 180 MV_U8 outstandingCommands; 181 182 UCHAR status; 183 UCHAR ver_601; 184 UCHAR beeping; 185 186 eventhandler_tag eh; 187 } IAL_ADAPTER_T; 188 189 typedef struct _privCommand { 190 TAILQ_ENTRY(_privCommand) PrivEntry; 191 IAL_ADAPTER_T *pAdapter; 192 union ccb *ccb; 193 bus_dmamap_t buf_map; 194 } *pPrivCommand; 195 196 extern IAL_ADAPTER_T *gIal_Adapter; 197 198 /*entry.c*/ 199 typedef void (*HPT_DPC)(IAL_ADAPTER_T *,void*,UCHAR); 200 int hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T *pAdapter, void *arg, UCHAR flags); 201 void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, 202 UCHAR flags); 203 void Check_Idle_Call(IAL_ADAPTER_T *pAdapter); 204 int Kernel_DeviceIoControl(_VBUS_ARG DWORD dwIoControlCode, PVOID lpInBuffer, 205 DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize, 206 PDWORD lpBytesReturned); 207 void fRescanAllDevice(_VBUS_ARG0); 208 int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk); 209 210 211 #define __str_direct(x) #x 212 #define __str(x) __str_direct(x) 213 #define KMSG_LEADING __str(PROC_DIR_NAME) ": " 214 #define hpt_printk(_x_) do { \ 215 printf(KMSG_LEADING); \ 216 printf _x_ ; \ 217 } while (0) 218 219 #define DUPLICATE 0 220 #define INITIALIZE 1 221 #define REBUILD_PARITY 2 222 #define VERIFY 3 223 224 /**********************************************************/ 225 static __inline struct cam_periph * 226 hpt_get_periph(int path_id,int target_id) 227 { 228 struct cam_periph *periph = NULL; 229 struct cam_path *path; 230 int status; 231 232 status = xpt_create_path(&path, NULL, path_id, target_id, 0); 233 if (status == CAM_REQ_CMP) { 234 periph = cam_periph_find(path, NULL); 235 xpt_free_path(path); 236 if (periph != NULL) { 237 if (strncmp(periph->periph_name, "da", 2)) 238 periph = NULL; 239 } 240 } 241 return periph; 242 } 243 244 static __inline void 245 FreePrivCommand(IAL_ADAPTER_T *pAdapter, pPrivCommand prvCmd) 246 { 247 TAILQ_INSERT_TAIL(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry); 248 } 249 250 static __inline pPrivCommand 251 AllocPrivCommand(IAL_ADAPTER_T *pAdapter) 252 { 253 pPrivCommand prvCmd; 254 255 prvCmd = TAILQ_FIRST(&pAdapter->PrivCmdTQH); 256 if (prvCmd == NULL) 257 return NULL; 258 259 TAILQ_REMOVE(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry); 260 return (prvCmd); 261 } 262 263 static __inline void 264 mv_reg_write_byte(MV_BUS_ADDR_T base, MV_U32 offset, MV_U8 val) 265 { 266 IAL_ADAPTER_T *pAdapter; 267 268 pAdapter = base; 269 bus_space_write_1(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 270 } 271 272 static __inline void 273 mv_reg_write_word(MV_BUS_ADDR_T base, MV_U32 offset, MV_U16 val) 274 { 275 IAL_ADAPTER_T *pAdapter; 276 277 pAdapter = base; 278 bus_space_write_2(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 279 } 280 281 static __inline void 282 mv_reg_write_dword(MV_BUS_ADDR_T base, MV_U32 offset, MV_U32 val) 283 { 284 IAL_ADAPTER_T *pAdapter; 285 286 pAdapter = base; 287 bus_space_write_4(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 288 } 289 290 static __inline MV_U8 291 mv_reg_read_byte(MV_BUS_ADDR_T base, MV_U32 offset) 292 { 293 IAL_ADAPTER_T *pAdapter; 294 295 pAdapter = base; 296 return (bus_space_read_1(pAdapter->mem_btag, pAdapter->mem_bsh, 297 offset)); 298 } 299 300 static __inline MV_U16 301 mv_reg_read_word(MV_BUS_ADDR_T base, MV_U32 offset) 302 { 303 IAL_ADAPTER_T *pAdapter; 304 305 pAdapter = base; 306 return (bus_space_read_2(pAdapter->mem_btag, pAdapter->mem_bsh, 307 offset)); 308 } 309 310 static __inline MV_U32 311 mv_reg_read_dword(MV_BUS_ADDR_T base, MV_U32 offset) 312 { 313 IAL_ADAPTER_T *pAdapter; 314 315 pAdapter = base; 316 return (bus_space_read_4(pAdapter->mem_btag, pAdapter->mem_bsh, 317 offset)); 318 } 319 320 #endif 321