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.h> 36 #include <machine/resource.h> 37 #include <machine/bus.h> 38 #include <sys/rman.h> 39 40 #include <cam/cam.h> 41 #include <cam/cam_ccb.h> 42 #include <cam/cam_debug.h> 43 #include <cam/cam_sim.h> 44 #include <cam/cam_xpt_sim.h> 45 #include <cam/cam_periph.h> 46 #include <cam/scsi/scsi_all.h> 47 #include <cam/scsi/scsi_message.h> 48 49 extern intrmask_t lock_driver(void); 50 extern void unlock_driver(intrmask_t spl); 51 52 typedef struct 53 { 54 UCHAR status; /* 0 nonbootable; 80h bootable */ 55 UCHAR start_head; 56 USHORT start_sector; 57 UCHAR type; 58 UCHAR end_head; 59 USHORT end_sector; 60 ULONG start_abs_sector; 61 ULONG num_of_sector; 62 } partition; 63 64 typedef struct _INQUIRYDATA { 65 UCHAR DeviceType : 5; 66 UCHAR DeviceTypeQualifier : 3; 67 UCHAR DeviceTypeModifier : 7; 68 UCHAR RemovableMedia : 1; 69 UCHAR Versions; 70 UCHAR ResponseDataFormat; 71 UCHAR AdditionalLength; 72 UCHAR Reserved[2]; 73 UCHAR SoftReset : 1; 74 UCHAR CommandQueue : 1; 75 UCHAR Reserved2 : 1; 76 UCHAR LinkedCommands : 1; 77 UCHAR Synchronous : 1; 78 UCHAR Wide16Bit : 1; 79 UCHAR Wide32Bit : 1; 80 UCHAR RelativeAddressing : 1; 81 UCHAR VendorId[8]; 82 UCHAR ProductId[16]; 83 UCHAR ProductRevisionLevel[4]; 84 UCHAR VendorSpecific[20]; 85 UCHAR Reserved3[40]; 86 } INQUIRYDATA, *PINQUIRYDATA; 87 88 typedef struct _READ_CAPACITY_DATA { 89 ULONG LogicalBlockAddress; 90 ULONG BytesPerBlock; 91 } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA; 92 93 #define MV_IAL_HT_SACOALT_DEFAULT 1 94 #define MV_IAL_HT_SAITMTH_DEFAULT 1 95 96 /****************************************/ 97 /* GENERAL Definitions */ 98 /****************************************/ 99 100 /* Bits for HD_ERROR */ 101 #define NM_ERR 0x02 /* media present */ 102 #define ABRT_ERR 0x04 /* Command aborted */ 103 #define MCR_ERR 0x08 /* media change request */ 104 #define IDNF_ERR 0x10 /* ID field not found */ 105 #define MC_ERR 0x20 /* media changed */ 106 #define UNC_ERR 0x40 /* Uncorrect data */ 107 #define WP_ERR 0x40 /* write protect */ 108 #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ 109 110 #define REQUESTS_ARRAY_SIZE (9 * MV_EDMA_REQUEST_QUEUE_SIZE) /* 9 K bytes */ 111 #define RESPONSES_ARRAY_SIZE (12*MV_EDMA_RESPONSE_QUEUE_SIZE) /* 3 K bytes */ 112 113 #define PRD_ENTRIES_PER_CMD (MAX_SG_DESCRIPTORS+1) 114 #define PRD_ENTRIES_SIZE (MV_EDMA_PRD_ENTRY_SIZE*PRD_ENTRIES_PER_CMD) 115 #define PRD_TABLES_FOR_VBUS (MV_SATA_CHANNELS_NUM*MV_EDMA_QUEUE_LENGTH) 116 117 typedef enum _SataEvent { 118 SATA_EVENT_NO_CHANGE = 0, 119 SATA_EVENT_CHANNEL_CONNECTED, 120 SATA_EVENT_CHANNEL_DISCONNECTED 121 } SATA_EVENT; 122 123 typedef ULONG_PTR dma_addr_t; 124 125 typedef struct _MV_CHANNEL { 126 unsigned int maxUltraDmaModeSupported; 127 unsigned int maxDmaModeSupported; 128 unsigned int maxPioModeSupported; 129 MV_BOOLEAN online; 130 } MV_CHANNEL; 131 132 struct _privCommand; 133 134 typedef struct IALAdapter { 135 struct cam_path *path; 136 device_t hpt_dev; /* bus device */ 137 struct resource *hpt_irq; /* interrupt */ 138 void *hpt_intr; /* interrupt handle */ 139 struct resource *mem_res; 140 bus_space_handle_t mem_bsh; 141 bus_space_tag_t mem_btag; 142 bus_dma_tag_t parent_dmat; 143 bus_dma_tag_t req_dmat; 144 bus_dmamap_t req_map; 145 bus_dma_tag_t resp_dmat; 146 bus_dmamap_t resp_map; 147 bus_dma_tag_t prd_dmat; 148 bus_dmamap_t prd_map; 149 bus_dma_tag_t buf_dmat; 150 151 struct IALAdapter *next; 152 153 MV_SATA_ADAPTER mvSataAdapter; 154 MV_CHANNEL mvChannel[MV_SATA_CHANNELS_NUM]; 155 MV_U8 *requestsArrayBaseAddr; 156 MV_U8 *requestsArrayBaseAlignedAddr; 157 dma_addr_t requestsArrayBaseDmaAddr; 158 dma_addr_t requestsArrayBaseDmaAlignedAddr; 159 MV_U8 *responsesArrayBaseAddr; 160 MV_U8 *responsesArrayBaseAlignedAddr; 161 dma_addr_t responsesArrayBaseDmaAddr; 162 dma_addr_t responsesArrayBaseDmaAlignedAddr; 163 SATA_EVENT sataEvents[MV_SATA_CHANNELS_NUM]; 164 165 struct callout_handle event_timer_connect; 166 struct callout_handle event_timer_disconnect; 167 168 struct _VBus VBus; 169 struct _VDevice VDevices[MV_SATA_CHANNELS_NUM]; 170 PCommand pCommandBlocks; 171 struct _privCommand *pPrivateBlocks; 172 TAILQ_HEAD(, _privCommand) PrivCmdTQH; 173 PUCHAR prdTableAddr; 174 ULONG prdTableDmaAddr; 175 void* pFreePRDLink; 176 177 union ccb *pending_Q; 178 179 MV_U8 outstandingCommands; 180 181 UCHAR status; 182 UCHAR ver_601; 183 UCHAR beeping; 184 185 eventhandler_tag eh; 186 } IAL_ADAPTER_T; 187 188 typedef struct _privCommand { 189 TAILQ_ENTRY(_privCommand) PrivEntry; 190 IAL_ADAPTER_T *pAdapter; 191 union ccb *ccb; 192 bus_dmamap_t buf_map; 193 } *pPrivCommand; 194 195 extern IAL_ADAPTER_T *gIal_Adapter; 196 197 /*entry.c*/ 198 typedef void (*HPT_DPC)(IAL_ADAPTER_T *,void*,UCHAR); 199 int hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T *pAdapter, void *arg, UCHAR flags); 200 void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, 201 UCHAR flags); 202 void Check_Idle_Call(IAL_ADAPTER_T *pAdapter); 203 int Kernel_DeviceIoControl(_VBUS_ARG DWORD dwIoControlCode, PVOID lpInBuffer, 204 DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize, 205 PDWORD lpBytesReturned); 206 void fRescanAllDevice(_VBUS_ARG0); 207 int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk); 208 209 210 #define __str_direct(x) #x 211 #define __str(x) __str_direct(x) 212 #define KMSG_LEADING __str(PROC_DIR_NAME) ": " 213 #define hpt_printk(_x_) do { \ 214 printf(KMSG_LEADING); \ 215 printf _x_ ; \ 216 } while (0) 217 218 #define DUPLICATE 0 219 #define INITIALIZE 1 220 #define REBUILD_PARITY 2 221 #define VERIFY 3 222 223 /**********************************************************/ 224 static __inline struct cam_periph * 225 hpt_get_periph(int path_id,int target_id) 226 { 227 struct cam_periph *periph = NULL; 228 struct cam_path *path; 229 int status; 230 231 status = xpt_create_path(&path, NULL, path_id, target_id, 0); 232 if (status == CAM_REQ_CMP) { 233 periph = cam_periph_find(path, NULL); 234 xpt_free_path(path); 235 if (periph != NULL) { 236 if (strncmp(periph->periph_name, "da", 2)) 237 periph = NULL; 238 } 239 } 240 return periph; 241 } 242 243 static __inline void 244 FreePrivCommand(IAL_ADAPTER_T *pAdapter, pPrivCommand prvCmd) 245 { 246 TAILQ_INSERT_TAIL(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry); 247 } 248 249 static __inline pPrivCommand 250 AllocPrivCommand(IAL_ADAPTER_T *pAdapter) 251 { 252 pPrivCommand prvCmd; 253 254 prvCmd = TAILQ_FIRST(&pAdapter->PrivCmdTQH); 255 if (prvCmd == NULL) 256 return NULL; 257 258 TAILQ_REMOVE(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry); 259 return (prvCmd); 260 } 261 262 static __inline void 263 mv_reg_write_byte(MV_BUS_ADDR_T base, MV_U32 offset, MV_U8 val) 264 { 265 IAL_ADAPTER_T *pAdapter; 266 267 pAdapter = base; 268 bus_space_write_1(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 269 } 270 271 static __inline void 272 mv_reg_write_word(MV_BUS_ADDR_T base, MV_U32 offset, MV_U16 val) 273 { 274 IAL_ADAPTER_T *pAdapter; 275 276 pAdapter = base; 277 bus_space_write_2(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 278 } 279 280 static __inline void 281 mv_reg_write_dword(MV_BUS_ADDR_T base, MV_U32 offset, MV_U32 val) 282 { 283 IAL_ADAPTER_T *pAdapter; 284 285 pAdapter = base; 286 bus_space_write_4(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val); 287 } 288 289 static __inline MV_U8 290 mv_reg_read_byte(MV_BUS_ADDR_T base, MV_U32 offset) 291 { 292 IAL_ADAPTER_T *pAdapter; 293 294 pAdapter = base; 295 return (bus_space_read_1(pAdapter->mem_btag, pAdapter->mem_bsh, 296 offset)); 297 } 298 299 static __inline MV_U16 300 mv_reg_read_word(MV_BUS_ADDR_T base, MV_U32 offset) 301 { 302 IAL_ADAPTER_T *pAdapter; 303 304 pAdapter = base; 305 return (bus_space_read_2(pAdapter->mem_btag, pAdapter->mem_bsh, 306 offset)); 307 } 308 309 static __inline MV_U32 310 mv_reg_read_dword(MV_BUS_ADDR_T base, MV_U32 offset) 311 { 312 IAL_ADAPTER_T *pAdapter; 313 314 pAdapter = base; 315 return (bus_space_read_4(pAdapter->mem_btag, pAdapter->mem_bsh, 316 offset)); 317 } 318 319 #endif 320