summaryrefslogtreecommitdiffstats
path: root/sys/dev/hptiop/hptiop.h
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2007-05-09 07:07:26 +0000
committerscottl <scottl@FreeBSD.org>2007-05-09 07:07:26 +0000
commit2ddb46eeb6224ecb7078555faf58fa91374c0760 (patch)
treee6097df0d1ec783ab98f9db835aa6d2a54e915bb /sys/dev/hptiop/hptiop.h
parentcc6f7c0d991522d3063004bbc78a1c276db66ca0 (diff)
downloadFreeBSD-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.h343
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
+
OpenPOWER on IntegriCloud