mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-30 12:04:07 +00:00
Introduce a driver for the Highpoint RocketRAID 3xxx series of controllers.
The driver relies on CAM. Many thanks to Highpoint for providing this driver.
This commit is contained in:
parent
10fe523e99
commit
4439f8b4b6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169412
@ -97,6 +97,7 @@ device ahd # AHA39320/29320 and onboard AIC79xx devices
|
||||
options AHD_REG_PRETTY_PRINT # Print register bitfields in debug
|
||||
# output. Adds ~215k to driver.
|
||||
device amd # AMD 53C974 (Tekram DC-390(T))
|
||||
device hptiop # Highpoint RocketRaid 3xxx series
|
||||
device isp # Qlogic family
|
||||
#device ispfw # Firmware for QLogic HBAs- normally a module
|
||||
device mpt # LSI-Logic MPT-Fusion
|
||||
|
@ -1433,6 +1433,7 @@ options SC_NO_SUSPEND_VTYSWITCH
|
||||
# bt: Most Buslogic controllers: including BT-445, BT-54x, BT-64x, BT-74x,
|
||||
# BT-75x, BT-946, BT-948, BT-956, BT-958, SDC3211B, SDC3211F, SDC3222F
|
||||
# esp: NCR53c9x. Only for SBUS hardware right now.
|
||||
# hptiop: Highpoint RocketRaid 3xxx series SATA RAID
|
||||
# isp: Qlogic ISP 1020, 1040 and 1040B PCI SCSI host adapters,
|
||||
# ISP 1240 Dual Ultra SCSI, ISP 1080 and 1280 (Dual) Ultra2,
|
||||
# ISP 12160 Ultra3 SCSI,
|
||||
@ -1469,6 +1470,7 @@ device ahc
|
||||
device ahd
|
||||
device amd
|
||||
device esp
|
||||
device hptiop
|
||||
device isp
|
||||
hint.isp.0.disable="1"
|
||||
hint.isp.0.role="3"
|
||||
|
@ -685,6 +685,7 @@ dev/hifn/hifn7751.c optional hifn
|
||||
dev/hme/if_hme.c optional hme
|
||||
dev/hme/if_hme_pci.c optional hme pci
|
||||
dev/hme/if_hme_sbus.c optional hme sbus
|
||||
dev/hptiop/hptiop.c optional hptiop cam
|
||||
dev/hwpmc/hwpmc_logging.c optional hwpmc
|
||||
dev/hwpmc/hwpmc_mod.c optional hwpmc
|
||||
dev/ichsmb/ichsmb.c optional ichsmb
|
||||
|
1301
sys/dev/hptiop/hptiop.c
Normal file
1301
sys/dev/hptiop/hptiop.c
Normal file
File diff suppressed because it is too large
Load Diff
343
sys/dev/hptiop/hptiop.h
Normal file
343
sys/dev/hptiop/hptiop.h
Normal file
@ -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
|
||||
|
@ -99,6 +99,7 @@ device ahd # AHA39320/29320 and onboard AIC79xx devices
|
||||
options AHD_REG_PRETTY_PRINT # Print register bitfields in debug
|
||||
# output. Adds ~215k to driver.
|
||||
device amd # AMD 53C974 (Tekram DC-390(T))
|
||||
device hptiop * Highpoint RocketRaid 3xxx series
|
||||
device isp # Qlogic family
|
||||
#device ispfw # Firmware for QLogic HBAs- normally a module
|
||||
device mpt # LSI-Logic MPT-Fusion
|
||||
|
@ -94,6 +94,7 @@ SUBDIR= ${_3dfx} \
|
||||
hifn \
|
||||
hme \
|
||||
${_hptmv} \
|
||||
hptiop \
|
||||
hwpmc \
|
||||
${_i2c} \
|
||||
${_ibcs2} \
|
||||
|
10
sys/modules/hptiop/Makefile
Normal file
10
sys/modules/hptiop/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../dev/hptiop
|
||||
|
||||
KMOD= hptiop
|
||||
SRCS= hptiop.c
|
||||
SRCS+= opt_scsi.h opt_cam.h
|
||||
SRCS+= device_if.h bus_if.h pci_if.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
Loading…
Reference in New Issue
Block a user