1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P. 14 */ 15 16 #ifndef _CPQARY3_H 17 #define _CPQARY3_H 18 19 #include <sys/types.h> 20 #include <sys/pci.h> 21 #include <sys/param.h> 22 #include <sys/errno.h> 23 #include <sys/conf.h> 24 #include <sys/map.h> 25 #include <sys/modctl.h> 26 #include <sys/kmem.h> 27 #include <sys/cmn_err.h> 28 #include <sys/stat.h> 29 #include <sys/scsi/scsi.h> 30 #include <sys/devops.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 34 #include <cpqary3_ciss.h> 35 #include <cpqary3_bd.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* 42 * Ioctl Commands 43 */ 44 #define CPQARY3_IOCTL_CMD ('c' << 4) 45 #define CPQARY3_IOCTL_DRIVER_INFO CPQARY3_IOCTL_CMD | 0x01 46 #define CPQARY3_IOCTL_CTLR_INFO CPQARY3_IOCTL_CMD | 0x02 47 #define CPQARY3_IOCTL_BMIC_PASS CPQARY3_IOCTL_CMD | 0x04 48 #define CPQARY3_IOCTL_SCSI_PASS CPQARY3_IOCTL_CMD | 0x08 49 50 /* Driver Revision : Used in Ioctl */ 51 #define CPQARY3_MINOR_REV_NO 00 52 #define CPQARY3_MAJOR_REV_NO 01 53 #define CPQARY3_REV_DATE 05 54 #define CPQARY3_REV_MONTH 04 55 #define CPQARY3_REV_YEAR 2001 56 57 /* Some Useful definations */ 58 #define CPQARY3_FAILURE 0 59 #define CPQARY3_SUCCESS 1 60 #define CPQARY3_SENT 2 61 #define CPQARY3_SUBMITTED 3 62 #define CPQARY3_NO_SIG 4 63 64 #define CPQARY3_TRUE 1 65 #define CPQARY3_FALSE 0 66 67 #define CTLR_SCSI_ID 7 68 #define CPQARY3_LD_FAILED 1 69 /* 70 * Defines for cleanup in cpqary3_attach and cpqary3_detach. 71 */ 72 #define CPQARY3_HBA_TRAN_ALLOC_DONE 0x0001 73 #define CPQARY3_HBA_TRAN_ATTACH_DONE 0x0002 74 #define CPQARY3_CTLR_CONFIG_DONE 0x0004 75 #define CPQARY3_INTR_HDLR_SET 0x0008 76 #define CPQARY3_CREATE_MINOR_NODE 0x0010 77 #define CPQARY3_SOFTSTATE_ALLOC_DONE 0x0020 78 #define CPQARY3_MUTEX_INIT_DONE 0x0040 79 #define CPQARY3_TICK_TMOUT_REGD 0x0080 80 #define CPQARY3_MEM_MAPPED 0x0100 81 #define CPQARY3_SW_INTR_HDLR_SET 0x0200 82 #define CPQARY3_SW_MUTEX_INIT_DONE 0x0400 83 #define CPQARY3_NOE_INIT_DONE 0x0800 84 85 #define CPQARY3_CLEAN_ALL 0x0FFF 86 87 #define CPQARY3_TICKTMOUT_VALUE 180000000 /* 180 seconds */ 88 89 /* 90 * Defines for Maximum and Default Settings. 91 */ 92 93 #define MAX_LOGDRV 64 /* Max supported Logical Drivers */ 94 #define MAX_CTLRS 8 /* Max supported Controllers */ 95 #define MAX_TAPE 28 96 /* 97 * NOTE: When changing the below two entries, Max SG count in cpqary3_ciss.h 98 * should also be changed. 99 */ 100 /* SG */ 101 #define MAX_PERF_SG_CNT 64 /* Maximum S/G in performant mode */ 102 #define CPQARY3_SG_CNT 30 /* minimum S/G in simple mode */ 103 #define CPQARY3_PERF_SG_CNT 31 /* minimum S/G for performant mode */ 104 /* SG */ 105 106 107 #define CPQARY3_MAX_TGT (MAX_LOGDRV + MAX_TAPE + 1) 108 109 /* 110 * SCSI Capabilities Related IDs 111 */ 112 #define CPQARY3_CAP_DISCON_ENABLED 0x01 113 #define CPQARY3_CAP_SYNC_ENABLED 0x02 114 #define CPQARY3_CAP_WIDE_XFER_ENABLED 0x04 115 #define CPQARY3_CAP_ARQ_ENABLED 0x08 116 #define CPQARY3_CAP_TAG_QING_ENABLED 0x10 117 #define CPQARY3_CAP_TAG_QING_SUPP 0x20 118 #define CPQARY3_CAP_UNTAG_DRV_QING_ENABLED 0x40 119 120 /* 121 * Defines for HBA 122 */ 123 #define CAP_NOT_DEFINED -1 124 #define CAP_CHG_NOT_ALLOWED 0 125 #define CAP_CHG_SUCCESS 1 126 127 /* 128 * Macros for Data Access 129 */ 130 131 /* SCSI Addr to Per Controller */ 132 #define SA2CTLR(saddr) ((cpqary3_t *)((saddr)->a_hba_tran->tran_hba_private)) 133 #define SA2TGT(sa) (sa)->a_target /* SCSI Addr to Target ID */ 134 #define SD2TGT(sd) (sd)->sd_address.a_target /* SCSI Dev to Target ID */ 135 #define SD2LUN(sd) (sd)->sd_address.a_lun /* SCSI Dev to Lun */ 136 #define SD2SA(sd) ((sd)->sd_address) /* SCSI Dev to SCSI Addr */ 137 138 /* SCSI Dev to Per Controller */ 139 #define SD2CTLR(sd) \ 140 ((cpqary3_t *)sd->sd_address.a_hba_tran->tran_hba_private) 141 142 #define PKT2PVTPKT(sp) ((cpqary3_pkt_t *)((sp)->pkt_ha_private)) 143 #define PVTPKT2MEM(p) ((cpqary3_cmdpvt_t *)p->memp) 144 #define MEM2CMD(m) ((CommandList_t *)m->cmdlist_memaddr) 145 #define SP2CMD(sp) MEM2CMD(PVTPKT2MEM(PKT2PVTPKT(sp))) 146 #define CTLR2MEMLISTP(ctlr) ((cpqary3_cmdmemlist_t *)ctlr->cmdmemlistp) 147 #define MEM2PVTPKT(m) ((cpqary3_pkt_t *)m->pvt_pkt) 148 #define MEM2DRVPVT(m) ((cpqary3_private_t *)m->driverdata) 149 #define TAG2MEM(ctlr, tag) \ 150 ((cpqary3_cmdpvt_t *)(CTLR2MEMLISTP(ctlr)->pool[tag])) 151 152 /* MACROS */ 153 #define CPQARY3_MIN(x, y) (x < y ? x : y) 154 #define CPQARY3_SWAP(val) ((val >> 8) | ((val & 0xff) << 8)) 155 #define RETURN_VOID_IF_NULL(x) if (NULL == x) return 156 #define RETURN_NULL_IF_NULL(x) if (NULL == x) return (NULL) 157 #define RETURN_FAILURE_IF_NULL(x) if (NULL == x) return (CPQARY3_FAILURE) 158 159 /* 160 * Macros for memory allocation/deallocations 161 */ 162 #define MEM_ZALLOC(x) kmem_zalloc(x, KM_NOSLEEP) 163 #define MEM_SFREE(x, y) if (x) kmem_free((void*)x, y) 164 165 /* 166 * Convenient macros for reading/writing Configuration table registers 167 */ 168 #define DDI_GET8(ctlr, regp) \ 169 ddi_get8((ctlr)->ct_handle, (uint8_t *)(regp)) 170 #define DDI_PUT8(ctlr, regp, value) \ 171 ddi_put8((ctlr)->ct_handle, (uint8_t *)(regp), (value)) 172 #define DDI_GET16(ctlr, regp) \ 173 ddi_get16((ctlr)->ct_handle, (uint16_t *)(regp)) 174 #define DDI_PUT16(ctlr, regp, value) \ 175 ddi_put16((ctlr)->ct_handle, (uint16_t *)(regp), (value)) 176 #define DDI_GET32(ctlr, regp) \ 177 ddi_get32((ctlr)->ct_handle, (uint32_t *)(regp)) 178 #define DDI_PUT32(ctlr, regp, value) \ 179 ddi_put32((ctlr)->ct_handle, (uint32_t *)(regp), (value)) 180 /* PERF */ 181 #define DDI_PUT32_CP(ctlr, regp, value) \ 182 ddi_put32((ctlr)->cp_handle, (uint32_t *)(regp), (value)) 183 /* PERF */ 184 185 #define CPQARY3_BUFFER_ERROR_CLEAR 0x0 /* to be used with bioerror */ 186 #define CPQARY3_DMA_NO_CALLBACK 0x0 /* to be used with DMA calls */ 187 #define CPQARY3_DMA_ALLOC_HANDLE_DONE 0x01 188 #define CPQARY3_DMA_ALLOC_MEM_DONE 0x02 189 #define CPQARY3_DMA_BIND_ADDR_DONE 0x04 190 #define CPQARY3_FREE_PHYCTG_MEM 0x07 191 #define CPQARY3_SYNCCMD_SEND_WAITSIG (0x0001) 192 193 /* 194 * Include the driver specific relevant header files here. 195 */ 196 #include "cpqary3_ciss.h" 197 #include "cpqary3_q_mem.h" 198 #include "cpqary3_noe.h" 199 #include "cpqary3_scsi.h" 200 #include "cpqary3_ioctl.h" 201 202 /* 203 * Per Target Structure 204 */ 205 206 typedef struct cpqary3_target { 207 uint32_t logical_id : 30; /* at most 64 : 63 drives + 1 CTLR */ 208 uint32_t type : 2; /* NONE, CTLR, LOGICAL DRIVE, TAPE */ 209 PhysDevAddr_t PhysID; 210 union { 211 struct { 212 uint8_t id; 213 uint8_t bus; 214 } scsi; /* To support tapes */ 215 struct { 216 uint8_t heads; 217 uint8_t sectors; 218 } drive; /* Logical drives */ 219 } properties; 220 221 uint32_t ctlr_flags; 222 dev_info_t *tgt_dip; 223 ddi_dma_attr_t dma_attrs; 224 } cpqary3_tgt_t; 225 226 227 /* 228 * Values for the type field in the Per Target Structure (above) 229 */ 230 #define CPQARY3_TARGET_NONE 0 /* No Device */ 231 #define CPQARY3_TARGET_CTLR 1 /* Controller */ 232 #define CPQARY3_TARGET_LOG_VOL 2 /* Logical Volume */ 233 #define CPQARY3_TARGET_TAPE 3 /* SCSI Device - Tape */ 234 235 /* 236 * Index into PCI Configuration Registers for Base Address Registers(BAR) 237 * Currently, only index for BAR 0 and BAR 1 are defined 238 */ 239 #define INDEX_PCI_BASE0 1 /* offset 0x10 */ 240 #define INDEX_PCI_BASE1 2 /* offset 0x14 */ 241 242 /* Offset Values for IO interface from BAR 0 */ 243 #define INBOUND_DOORBELL 0x20 244 #define OUTBOUND_LIST_STATUS 0x30 245 #define OUTBOUND_INTERRUPT_MASK 0x34 246 #define INBOUND_QUEUE 0x40 247 #define OUTBOUND_QUEUE 0x44 248 249 /* Offset Values for IO interface from BAR 1 */ 250 #define CONFIGURATION_TABLE 0x00 251 252 #define INTR_DISABLE_5300_MASK 0x00000008l 253 #define INTR_DISABLE_5I_MASK 0x00000004l 254 255 #define OUTBOUND_LIST_5300_EXISTS 0x00000008l 256 #define OUTBOUND_LIST_5I_EXISTS 0x00000004l 257 258 #define INTR_PERF_MASK 0x00000001l 259 260 #define INTR_PERF_LOCKUP_MASK 0x00000004l 261 262 #define INTR_E200_PERF_MASK 0x00000004l 263 264 #define INTR_SIMPLE_MASK 0x00000008l 265 #define INTR_SIMPLE_LOCKUP_MASK 0x0000000cl 266 267 268 #define INTR_SIMPLE_5I_MASK 0x00000004l 269 #define INTR_SIMPLE_5I_LOCKUP_MASK 0x0000000cl 270 271 typedef struct cpqary3_per_controller CTLR; 272 /* 273 * Per Controller Structure 274 */ 275 typedef struct cpqary3_per_controller { 276 /* System Dependent Entities */ 277 uint8_t bus; 278 uint8_t dev : 5; 279 uint8_t fun : 3; 280 uint32_t instance; 281 dev_info_t *dip; 282 283 /* Controller Specific Information */ 284 int8_t hba_name[38]; 285 ulong_t num_of_targets; 286 uint32_t heartbeat; 287 uint32_t board_id; 288 cpqary3_bd_t *bddef; 289 290 /* Condition Variables used */ 291 kcondvar_t cv_immediate_wait; 292 kcondvar_t cv_noe_wait; 293 kcondvar_t cv_flushcache_wait; 294 kcondvar_t cv_abort_wait; 295 kcondvar_t cv_ioctl_wait; /* Variable for ioctls */ 296 297 /* 298 * CPQary3 driver related entities related to : 299 * Hardware & Software Interrupts, Cookies & Mutex. 300 * Timeout Handler 301 * Driver Transport Layer/Structure 302 * Database for the per-controller Command Memory Pool 303 * Target List for the per-controller 304 */ 305 uint8_t irq; /* h/w IRQ */ 306 ddi_iblock_cookie_t hw_iblock_cookie; /* cookie for h/w intr */ 307 kmutex_t hw_mutex; /* h/w mutex */ 308 ddi_iblock_cookie_t sw_iblock_cookie; /* cookie for s/w intr */ 309 kmutex_t sw_mutex; /* s/w mutex */ 310 ddi_softintr_t cpqary3_softintr_id; /* s/w intr identifier */ 311 uint8_t swintr_flag; 312 timeout_id_t tick_tmout_id; /* timeout identifier */ 313 uint8_t cpqary3_tick_hdlr; 314 scsi_hba_tran_t *hba_tran; /* transport structure */ 315 cpqary3_cmdmemlist_t *cmdmemlistp; /* database - Memory Pool */ 316 cpqary3_tgt_t *cpqary3_tgtp[CPQARY3_MAX_TGT]; 317 cpqary3_drvr_replyq_t *drvr_replyq; 318 319 320 uint8_t (*check_ctlr_intr)(CTLR *); 321 322 /* 323 * PCI Configuration Registers 324 * 0x10 Primary I2O Memory BAR - for Host Interface 325 * 0x14 Primary DRAM 1 BAR - for Transport Configuration Table 326 * 327 * Host Interface Registers 328 * Offset from Primary I2O Memory BAR 329 * 0x20 Inbound Doorbell - for interrupting controller 330 * 0x30 Outbound List Status - for signalling status of Reply Q 331 * 0x34 Outbound Interrupt Mask - for masking Interrupts to host 332 * 0x40 Host Inbound Queue - Request Q 333 * 0x44 Host Outbound Queue - reply Q 334 * 335 * Offset from Primary DRAM 1 BAR 336 * 0x00 Configuration Table - for Controller Transport Layer 337 */ 338 339 uint32_t *idr; 340 ddi_acc_handle_t idr_handle; 341 342 /* LOCKUP CODE */ 343 uint32_t *spr0; 344 ddi_acc_handle_t spr0_handle; 345 /* LOCKUP CODE */ 346 347 uint32_t *odr; 348 ddi_acc_handle_t odr_handle; 349 350 uint32_t *odr_cl; 351 ddi_acc_handle_t odr_cl_handle; 352 353 uint32_t *isr; 354 ddi_acc_handle_t isr_handle; 355 356 uint32_t *imr; 357 ddi_acc_handle_t imr_handle; 358 359 uint32_t *ipq; 360 ddi_acc_handle_t ipq_handle; 361 362 uint32_t *opq; 363 ddi_acc_handle_t opq_handle; 364 365 CfgTable_t *ct; 366 ddi_acc_handle_t ct_handle; 367 368 CfgTrans_Perf_t *cp; 369 ddi_acc_handle_t cp_handle; 370 371 uint32_t legacy_mapping; 372 uint32_t noe_support; 373 /* SG */ 374 uint32_t sg_cnt; 375 /* SG */ 376 uint32_t ctlr_maxcmds; 377 uint32_t host_support; 378 uint8_t controller_lockup; 379 uint8_t lockup_logged; 380 uint32_t poll_flag; 381 } cpqary3_t; 382 383 384 /* 385 * Private Structure for Self Issued Commands 386 */ 387 388 typedef struct cpqary3_driver_private { 389 void *sg; 390 cpqary3_phyctg_t *phyctgp; 391 }cpqary3_private_t; 392 393 /* cmd_flags */ 394 #define CFLAG_DMASEND 0x01 395 #define CFLAG_CMDIOPB 0x02 396 #define CFLAG_DMAVALID 0x04 397 398 /* 399 * Driver Private Packet 400 */ 401 typedef struct cpqary3_pkt { 402 struct scsi_pkt *scsi_cmd_pkt; 403 ddi_dma_win_t prev_winp; 404 ddi_dma_seg_t prev_segp; 405 clock_t cmd_start_time; 406 /* SG */ 407 ddi_dma_cookie_t cmd_dmacookies[MAX_PERF_SG_CNT]; 408 /* SG */ 409 uint32_t cmd_ncookies; 410 uint32_t cmd_cookie; 411 uint32_t cmd_cookiecnt; 412 uint32_t cmd_nwin; 413 uint32_t cmd_curwin; 414 off_t cmd_dma_offset; 415 size_t cmd_dma_len; 416 size_t cmd_dmacount; 417 struct buf *bf; 418 ddi_dma_handle_t cmd_dmahandle; 419 uint32_t bytes; 420 uint32_t cmd_flags; 421 uint32_t cdb_len; 422 uint32_t scb_len; 423 cpqary3_cmdpvt_t *memp; 424 } cpqary3_pkt_t; 425 426 #pragma pack(1) 427 428 typedef struct cpqary3_ioctlresp { 429 /* Driver Revision */ 430 struct cpqary3_revision { 431 uint8_t minor; /* Version */ 432 uint8_t major; 433 uint8_t mm; /* Revision Date */ 434 uint8_t dd; 435 uint16_t yyyy; 436 } cpqary3_drvrev; 437 438 /* HBA Info */ 439 struct cpqary3_ctlr { 440 uint8_t num_of_tgts; /* No of Logical Drive */ 441 uint8_t *name; 442 } cpqary3_ctlr; 443 } cpqary3_ioctlresp_t; 444 445 typedef struct cpqary3_ioctlreq { 446 cpqary3_ioctlresp_t *cpqary3_ioctlrespp; 447 } cpqary3_ioctlreq_t; 448 449 #pragma pack() 450 451 /* Driver function definitions */ 452 453 void cpqary3_init_hbatran(cpqary3_t *); 454 void cpqary3_read_conf_file(dev_info_t *, cpqary3_t *); 455 void cpqary3_tick_hdlr(void *); 456 void cpqary3_flush_cache(cpqary3_t *); 457 void cpqary3_intr_onoff(cpqary3_t *, uint8_t); 458 void cpqary3_lockup_intr_onoff(cpqary3_t *, uint8_t); 459 uint8_t cpqary3_disable_NOE_command(cpqary3_t *); 460 uint8_t cpqary3_send_NOE_command(cpqary3_t *, cpqary3_cmdpvt_t *, uint8_t); 461 uint16_t cpqary3_init_ctlr_resource(cpqary3_t *); 462 uint32_t cpqary3_hw_isr(caddr_t); 463 uint32_t cpqary3_sw_isr(caddr_t); 464 int32_t cpqary3_ioctl_driver_info(uintptr_t, int); 465 int32_t cpqary3_ioctl_ctlr_info(uintptr_t, cpqary3_t *, int); 466 int32_t cpqary3_ioctl_bmic_pass(uintptr_t, cpqary3_t *, int); 467 int32_t cpqary3_ioctl_scsi_pass(uintptr_t, cpqary3_t *, int); 468 uint8_t cpqary3_probe4targets(cpqary3_t *); 469 void cpqary3_cmdlist_release(cpqary3_cmdpvt_t *, uint8_t); 470 int32_t cpqary3_submit(cpqary3_t *, uint32_t); 471 void cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *, uint8_t); 472 caddr_t cpqary3_alloc_phyctgs_mem(cpqary3_t *, size_t, uint32_t *, 473 cpqary3_phyctg_t *); 474 cpqary3_cmdpvt_t *cpqary3_cmdlist_occupy(cpqary3_t *); 475 void cpqary3_synccmd_complete(cpqary3_cmdpvt_t *); 476 void cpqary3_NOE_handler(cpqary3_cmdpvt_t *); 477 uint8_t cpqary3_retrieve(cpqary3_t *); 478 void cpqary3_synccmd_cleanup(cpqary3_cmdpvt_t *); 479 int cpqary3_target_geometry(struct scsi_address *); 480 uint8_t cpqary3_send_abortcmd(cpqary3_t *, uint16_t, CommandList_t *); 481 void cpqary3_memfini(cpqary3_t *, uint8_t); 482 uint8_t cpqary3_init_ctlr(cpqary3_t *); 483 int16_t cpqary3_meminit(cpqary3_t *); 484 void cpqary3_noe_complete(cpqary3_cmdpvt_t *cpqary3_cmdpvtp); 485 cpqary3_cmdpvt_t *cpqary3_synccmd_alloc(cpqary3_t *, size_t); 486 void cpqary3_synccmd_free(cpqary3_t *, cpqary3_cmdpvt_t *); 487 int cpqary3_synccmd_send(cpqary3_t *, cpqary3_cmdpvt_t *, clock_t, int); 488 uint8_t cpqary3_poll_retrieve(cpqary3_t *cpqary3p, uint32_t poll_tag); 489 uint8_t cpqary3_build_cmdlist(cpqary3_cmdpvt_t *cpqary3_cmdpvtp, uint32_t tid); 490 491 #ifdef __cplusplus 492 } 493 #endif 494 495 #endif /* _CPQARY3_H */ 496