diff options
author | scottl <scottl@FreeBSD.org> | 2007-05-09 07:07:26 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-05-09 07:07:26 +0000 |
commit | 2ddb46eeb6224ecb7078555faf58fa91374c0760 (patch) | |
tree | e6097df0d1ec783ab98f9db835aa6d2a54e915bb /sys/dev/hptiop/hptiop.h | |
parent | cc6f7c0d991522d3063004bbc78a1c276db66ca0 (diff) | |
download | FreeBSD-src-2ddb46eeb6224ecb7078555faf58fa91374c0760.zip FreeBSD-src-2ddb46eeb6224ecb7078555faf58fa91374c0760.tar.gz |
Introduce a driver for the Highpoint RocketRAID 3xxx series of controllers.
The driver relies on CAM.
Many thanks to Highpoint for providing this driver.
Diffstat (limited to 'sys/dev/hptiop/hptiop.h')
-rw-r--r-- | sys/dev/hptiop/hptiop.h | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/sys/dev/hptiop/hptiop.h b/sys/dev/hptiop/hptiop.h new file mode 100644 index 0000000..fc332e5 --- /dev/null +++ b/sys/dev/hptiop/hptiop.h @@ -0,0 +1,343 @@ +/* + * HighPoint RR3xxx RAID Driver for FreeBSD + * Copyright (C) 2005-2007 HighPoint Technologies, Inc. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _HPTIOP_H +#define _HPTIOP_H + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#ifdef DBG +int hpt_dbg_level = 0; +#define KdPrint(x) do { if (hpt_dbg_level) printf x; } while (0) +#define HPT_ASSERT(x) assert(x) +#else +#define KdPrint(x) +#define HPT_ASSERT(x) +#endif + +#define HPT_SRB_MAX_REQ_SIZE 600 +#define HPT_SRB_MAX_QUEUE_SIZE 0x100 + +/* beyond 64G mem */ +#define HPT_SRB_FLAG_HIGH_MEM_ACESS 0x1 +#define HPT_SRB_MAX_SIZE ((sizeof(struct hpt_iop_srb) + 0x1f) & ~0x1f) + +#define HPT_IOCTL_MAGIC 0xA1B2C3D4 +#define HPT_IOCTL_MAGIC32 0x1A2B3C4D + + +struct hpt_iopmu +{ + u_int32_t resrved0[4]; + u_int32_t inbound_msgaddr0; + u_int32_t inbound_msgaddr1; + u_int32_t outbound_msgaddr0; + u_int32_t outbound_msgaddr1; + u_int32_t inbound_doorbell; + u_int32_t inbound_intstatus; + u_int32_t inbound_intmask; + u_int32_t outbound_doorbell; + u_int32_t outbound_intstatus; + u_int32_t outbound_intmask; + u_int32_t reserved1[2]; + u_int32_t inbound_queue; + u_int32_t outbound_queue; +}; + +struct hpt_iop_ioctl_param { + u_int32_t Magic; /* used to check if it's a valid ioctl packet */ + u_int32_t dwIoControlCode; /* operation control code */ + unsigned long lpInBuffer; /* input data buffer */ + u_int32_t nInBufferSize; /* size of input data buffer */ + unsigned long lpOutBuffer; /* output data buffer */ + u_int32_t nOutBufferSize; /* size of output data buffer */ + unsigned long lpBytesReturned; /* count of HPT_U8s returned */ +} __attribute__((packed)); + + +struct hpt_iop_srb { + u_int8_t req[HPT_SRB_MAX_REQ_SIZE]; + struct hpt_iop_hba *hba; + union ccb *ccb; + struct hpt_iop_srb * next; + bus_dmamap_t dma_map; + u_int32_t phy_addr; + u_int32_t srb_flag; + int index; +}; + +#define IOPMU_QUEUE_EMPTY 0xffffffff +#define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 +#define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 +#define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 +#define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 +#define IOPMU_MAX_MEM_SUPPORT_MASK_64G 0xfffffff000000000ull +#define IOPMU_MAX_MEM_SUPPORT_MASK_32G 0xfffffff800000000ull + +#define IOPMU_OUTBOUND_INT_MSG0 1 +#define IOPMU_OUTBOUND_INT_MSG1 2 +#define IOPMU_OUTBOUND_INT_DOORBELL 4 +#define IOPMU_OUTBOUND_INT_POSTQUEUE 8 +#define IOPMU_OUTBOUND_INT_PCI 0x10 + +#define IOPMU_INBOUND_INT_MSG0 1 +#define IOPMU_INBOUND_INT_MSG1 2 +#define IOPMU_INBOUND_INT_DOORBELL 4 +#define IOPMU_INBOUND_INT_ERROR 8 +#define IOPMU_INBOUND_INT_POSTQUEUE 0x10 + +enum hpt_iopmu_message { + /* host-to-iop messages */ + IOPMU_INBOUND_MSG0_NOP = 0, + IOPMU_INBOUND_MSG0_RESET, + IOPMU_INBOUND_MSG0_FLUSH, + IOPMU_INBOUND_MSG0_SHUTDOWN, + IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, + IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, + IOPMU_INBOUND_MSG0_MAX = 0xff, + /* iop-to-host messages */ + IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, + IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_MAX = 0x1ff, + IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_0 = 0x200, + IOPMU_OUTBOUND_MSG0_UNREGISTER_DEVICE_MAX = 0x2ff, + IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_0 = 0x300, + IOPMU_OUTBOUND_MSG0_REVALIDATE_DEVICE_MAX = 0x3ff, +}; + +struct hpt_iop_request_header +{ + u_int32_t size; + u_int32_t type; + u_int32_t flags; + u_int32_t result; + u_int32_t context; /* host context */ + u_int32_t context_hi32; +}; + +#define IOP_REQUEST_FLAG_SYNC_REQUEST 1 +#define IOP_REQUEST_FLAG_BIST_REQUEST 2 +#define IOP_REQUEST_FLAG_REMAPPED 4 +#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 + +enum hpt_iop_request_type { + IOP_REQUEST_TYPE_GET_CONFIG = 0, + IOP_REQUEST_TYPE_SET_CONFIG, + IOP_REQUEST_TYPE_BLOCK_COMMAND, + IOP_REQUEST_TYPE_SCSI_COMMAND, + IOP_REQUEST_TYPE_IOCTL_COMMAND, + IOP_REQUEST_TYPE_MAX +}; + +enum hpt_iop_result_type { + IOP_RESULT_PENDING = 0, + IOP_RESULT_SUCCESS, + IOP_RESULT_FAIL, + IOP_RESULT_BUSY, + IOP_RESULT_RESET, + IOP_RESULT_INVALID_REQUEST, + IOP_RESULT_BAD_TARGET, + IOP_RESULT_MODE_SENSE_CHECK_CONDITION, +}; + +struct hpt_iop_request_get_config +{ + struct hpt_iop_request_header header; + u_int32_t interface_version; + u_int32_t firmware_version; + u_int32_t max_requests; + u_int32_t request_size; + u_int32_t max_sg_count; + u_int32_t data_transfer_length; + u_int32_t alignment_mask; + u_int32_t max_devices; + u_int32_t sdram_size; +}; + +struct hpt_iop_request_set_config +{ + struct hpt_iop_request_header header; + u_int32_t iop_id; + u_int16_t vbus_id; + u_int16_t max_host_request_size; + u_int32_t reserve[6]; +}; + +struct hpt_iopsg +{ + u_int32_t size; + u_int32_t eot; /* non-zero: end of table */ + u_int64_t pci_address; +}; + +struct hpt_iop_request_block_command +{ + struct hpt_iop_request_header header; + u_int8_t channel; + u_int8_t target; + u_int8_t lun; + u_int8_t pad1; + u_int16_t command; /* IOP_BLOCK_COMMAND_{READ,WRITE} */ + u_int16_t sectors; + u_int64_t lba; + struct hpt_iopsg sg_list[1]; +}; + +#define IOP_BLOCK_COMMAND_READ 1 +#define IOP_BLOCK_COMMAND_WRITE 2 +#define IOP_BLOCK_COMMAND_VERIFY 3 +#define IOP_BLOCK_COMMAND_FLUSH 4 +#define IOP_BLOCK_COMMAND_SHUTDOWN 5 + +struct hpt_iop_request_scsi_command +{ + struct hpt_iop_request_header header; + u_int8_t channel; + u_int8_t target; + u_int8_t lun; + u_int8_t pad1; + u_int8_t cdb[16]; + u_int32_t dataxfer_length; + struct hpt_iopsg sg_list[1]; +}; + +struct hpt_iop_request_ioctl_command +{ + struct hpt_iop_request_header header; + u_int32_t ioctl_code; + u_int32_t inbuf_size; + u_int32_t outbuf_size; + u_int32_t bytes_returned; + u_int8_t buf[1]; + /* out data should be put at buf[(inbuf_size+3)&~3] */ +}; + +#define HPT_CTL_CODE_BSD_TO_IOP(x) ((x)-0xff00) + +#if __FreeBSD_version>503000 +typedef struct cdev * ioctl_dev_t; +#else +typedef dev_t ioctl_dev_t; +#endif + +#if __FreeBSD_version >= 500000 +typedef struct thread * ioctl_thread_t; +#else +typedef struct proc * ioctl_thread_t; +#endif + +struct hpt_iop_hba { + struct hpt_iopmu *iop; + struct hpt_iop_hba *next; + + u_int32_t firmware_version; + u_int32_t interface_version; + u_int32_t max_devices; + u_int32_t max_requests; + u_int32_t max_request_size; + u_int32_t max_sg_count; + + int msg_done; + + device_t pcidev; + u_int32_t pciunit; + ioctl_dev_t ioctl_dev; + + struct resource *bar0_res; + int bar0_rid; + + bus_dma_tag_t parent_dmat; + bus_dma_tag_t io_dmat; + bus_dma_tag_t srb_dmat; + bus_dmamap_t srb_dmamap; + /* to release */ + u_int8_t *uncached_ptr; + /* for scsi request block */ + struct hpt_iop_srb *srb_list; + /* for interrupt */ + struct resource *irq_res; + void *irq_handle; + /* other resources */ + struct cam_sim *sim; + struct cam_path *path; + void *req; +#if (__FreeBSD_version >= 500000) + struct mtx lock; +#else + int hpt_splx; +#endif +#define HPT_IOCTL_FLAG_OPEN 1 + u_int32_t flag; + struct hpt_iop_srb* srb[HPT_SRB_MAX_QUEUE_SIZE]; +}; + +#if __FreeBSD_version >= 500000 +#define hptiop_lock_adapter(hba) mtx_lock(&(hba)->lock) +#define hptiop_unlock_adapter(hba) mtx_unlock(&(hba)->lock) +#else +static __inline void hptiop_lock_adapter(struct hpt_iop_hba *hba) +{ + hba->hpt_splx = splcam(); +} +static __inline void hptiop_unlock_adapter(struct hpt_iop_hba *hba) +{ + splx(hba->hpt_splx); +} +#endif + +#define HPT_OSM_TIMEOUT (20*hz) /* timeout value for OS commands */ + +#define HPT_DO_IOCONTROL _IOW('H', 0, struct hpt_iop_ioctl_param) +#define HPT_SCAN_BUS _IO('H', 1) + +static __inline int hptiop_sleep(struct hpt_iop_hba *hba, void *ident, + int priority, const char *wmesg, int timo) +{ + + int retval; + +#if __FreeBSD_version >= 500000 + retval = msleep(ident, &hba->lock, priority, wmesg, timo); +#else + asleep(ident, priority, wmesg, timo); + hptiop_unlock_adapter(hba); + retval = await(priority, timo); + hptiop_lock_adapter(hba); +#endif + + return retval; + +} + +#if __FreeBSD_version < 501000 +#define READ_16 0x88 +#define WRITE_16 0x8a +#define SERVICE_ACTION_IN 0x9e +#endif + +#define HPT_DEV_MAJOR 200 + +#endif + |