Import the first release of HighPoint RocketRAID 27xx SAS 6Gb/s HBA card

driver.  This driver works for FreeBSD/i386 and FreeBSD/amd64 platforms.

Many thanks to HighPoint for providing this driver.

MFC after:	2 weeks
This commit is contained in:
Xin LI 2011-12-28 23:26:58 +00:00
parent a0b435f856
commit 81966bce06
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=228940
24 changed files with 44951 additions and 0 deletions

View File

@ -150,6 +150,7 @@ MAN= aac.4 \
hifn.4 \
hme.4 \
hpet.4 \
${_hpt27xx.4} \
${_hptiop.4} \
${_hptmv.4} \
${_hptrr.4} \
@ -687,6 +688,7 @@ _atp.4= atp.4
_coretemp.4= coretemp.4
_cpuctl.4= cpuctl.4
_dpms.4= dpms.4
_hpt27xx.4= hpt27xx.4
_hptiop.4= hptiop.4
_hptmv.4= hptmv.4
_hptrr.4= hptrr.4

101
share/man/man4/hpt27xx.4 Normal file
View File

@ -0,0 +1,101 @@
.\"
.\" Copyright (c) 2011 iXsystems, 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 DEVELOPERS ``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 DEVELOPERS 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.
.\"
.\" $FreeBSD$
.\"
.Dd December 28, 2011
.Dt HPT27XX 4
.Os
.Sh NAME
.Nm hpt27xx
.Nd "HighPoint RocketRAID 27xx SAS 6Gb/s HBA card driver"
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following line in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device hpt27xx"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
hpt27xx_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
driver provides support for HighPoint's RocketRAID 27xx based RAID controller.
.Pp
These devices support SAS disk drives
and provide RAID0 (striping), RAID1 (mirroring), and RAID5 functionality.
.Sh HARDWARE
The
.Nm
driver supports the following SAS
controllers:
.Pp
.Bl -bullet -compact
.It
HighPoint's RocketRAID 271x series
.It
HighPoint's RocketRAID 272x series
.It
HighPoint's RocketRAID 274x series
.It
HighPoint's RocketRAID 276x series
.It
HighPoint's RocketRAID 278x series
.El
.Sh NOTES
The
.Nm
driver only works on the i386 and amd64 platforms as it requires a binary
blob object from the manufacturer which they only supply for these platforms.
The
.Nm
driver does
.Em not
work on i386 with
.Xr pae 4
enabled.
.Sh SEE ALSO
.Xr kld 4 ,
.Xr kldload 8 ,
.Xr loader 8
.Sh HISTORY
The
.Nm
device driver first appeared in
.Fx 10.0 .
.Sh AUTHORS
.An -nosplit
The
.Nm
device driver was written by
.An HighPoint Technologies, Inc. .
This manual page was written by
.An Xin LI Aq delphij@FreeBSD.org
for iXsystems, Inc.

View File

@ -387,6 +387,10 @@ device stg
device aac
device aacp # SCSI Passthrough interface (optional, CAM required)
#
# Highpoint RocketRAID 27xx.
device hpt27xx
#
# Highpoint RocketRAID 182x.
device hptmv

View File

@ -58,6 +58,10 @@ os+%DIKED-nve.h optional nve pci \
no-implicit-rule no-obj before-depend \
clean "os+%DIKED-nve.h"
#
hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
hptmvraid.o optional hptmv \
dependency "$S/dev/hptmv/amd64-elf.raid.o.uu" \
compile-with "uudecode < $S/dev/hptmv/amd64-elf.raid.o.uu" \
@ -187,6 +191,9 @@ dev/fdc/fdc.c optional fdc
dev/fdc/fdc_acpi.c optional fdc
dev/fdc/fdc_isa.c optional fdc isa
dev/fdc/fdc_pccard.c optional fdc pccard
dev/hpt27xx/os_bsd.c optional hpt27xx
dev/hpt27xx/osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
dev/hptmv/entry.c optional hptmv
dev/hptmv/mv.c optional hptmv
dev/hptmv/gui_lib.c optional hptmv

View File

@ -57,6 +57,10 @@ os+%DIKED-nve.h optional nve pci \
no-implicit-rule no-obj before-depend \
clean "os+%DIKED-nve.h"
#
hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
hptmvraid.o optional hptmv \
dependency "$S/dev/hptmv/i386-elf.raid.o.uu" \
compile-with "uudecode < $S/dev/hptmv/i386-elf.raid.o.uu" \
@ -174,6 +178,9 @@ dev/fe/if_fe_isa.c optional fe isa
dev/glxiic/glxiic.c optional glxiic
dev/glxsb/glxsb.c optional glxsb
dev/glxsb/glxsb_hash.c optional glxsb
dev/hpt27xx/os_bsd.c optional hpt27xx
dev/hpt27xx/osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
dev/hptmv/entry.c optional hptmv
dev/hptmv/mv.c optional hptmv
dev/hptmv/gui_lib.c optional hptmv

196
sys/dev/hpt27xx/README Normal file
View File

@ -0,0 +1,196 @@
RocketRAID Controller Driver for FreeBSD
Copyright (C) 2011 HighPoint Technologies, Inc. All rights reserved.
#############################################################################
Revision History:
v1.0 2011-12-27
First source code release
#############################################################################
1. Overview
---------------------
This package contains FreeBSD driver source code for HighPoint RocketRAID
controller, include:
SAS Controller: RR271x, RR272x, RR274x, RR276x, RR278x.
NO WARRANTY
THE DRIVER SOURCE CODE HIGHPOINT PROVIDED IS FREE OF CHARGE, AND THERE IS
NO WARRANTY FOR THE PROGRAM. THERE ARE NO RESTRICTIONS ON THE USE OF THIS
FREE SOURCE CODE. HIGHPOINT DOES NOT PROVIDE ANY TECHNICAL SUPPORT IF THE
CODE HAS BEEN CHANGED FROM ORIGINAL SOURCE CODE.
LIMITATION OF LIABILITY
IN NO EVENT WILL HIGHPOINT BE LIABLE FOR DIRECT, INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF OR
INABILITY TO USE THIS PRODUCT OR DOCUMENTATION, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. IN PARTICULAR, HIGHPOINT SHALL NOT HAVE
LIABILITY FOR ANY HARDWARE, SOFTWARE, OR DATA STORED USED WITH THE
PRODUCT, INCLUDING THE COSTS OF REPAIRING, REPLACING, OR RECOVERING
SUCH HARDWARE, OR DATA.
2. Rebuild the kernel with HighPoint RocketRAID support
-----------------------------------------------
1) Install kernel source package and building tools.
2) Extract the driver files under the kernel source tree:
# cd /usr/src/sys/
# tar xvzf /your/path/to/hpt27xx-freebsd-src-v1.0-111227.tgz
3) Update the kernel configuration file to include the HighPoint source.
Assume the configure file is GENERIC, and new kernel configure file is
MYKERNEL:
# cd i386/conf (or amd64/conf for AMD64)
# cp GENERIC MYKERNEL
4) Edit MYKERNEL, and add the following line under "RAID controllers
interfaced to the SCSI subsystem":
device "hpt27xx" #HighPoint RocketRAID
5) For i386 system, edit /usr/src/sys/conf/files.i386 and append the lines
shown below:
hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
dev/hpt27xx/os_bsd.c optional hpt27xx
dev/hpt27xx/osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
For amd64 system, edit /usr/src/sys/conf/files.amd64 and append the lines
shown below:
hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
dev/hpt27xx/os_bsd.c optional hpt27xx
dev/hpt27xx/osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
6) Rebuild and install the kernel:
a) for FreeBSD 5.x-i386/6.x-i386/7.x-i386/8.x-i386/9.x-i386:
# cd /usr/src/sys/i386/conf/
# /usr/sbin/config MYKERNEL
# cd ../compile/MYKERNEL/
# make depend
# make
# make install
b) for FreeBSD 5.x-amd64/6.x-amd64/7.x-amd64/8.x-amd64/9.x-amd64:
# cd /usr/src/sys/amd64/conf/
# /usr/sbin/config MYKERNEL
# cd ../compile/MYKERNEL/
# make depend
# make
# make install
c) for FreeBSD 4.x:
# cd /usr/src/sys/i386/conf/
# /usr/sbin/config MYKERNEL
# cd ../../compile/MYKERNEL/
# make depend
# make
# make install
If the driver was previously configured as an auto-loaded module by
/boot/defaults/loader.conf, please remove the entry hpt27xx_load="YES"
from loader.conf to prevent the driver from being loaded twice.
7) Reboot from the new kernel.
3. Build/Load the driver as a kernel module
------------------------------------------------
1) Install kernel source package and building tools.
2) Extract the driver files under the kernel source tree:
# cd /usr/src/sys/
# tar xvzf /your/path/to/hpt27xx-freebsd-src-v1.0-111227.tgz
4) Build the driver module:
# cd modules/hpt27xx
# make
5) Copy the driver module to the kernel module directory
For FreeBSD 4.x:
# cp hpt27xx.ko /modules/
For FreeBSD 5.x/6.x/7.x/8.x/9.x:
# cp hpt27xx.ko /boot/kernel/
6) Reboot and load the driver under loader prompt. e.g:
BTX loader 1.00 BTX version is 1.01
Console: internal video/keyboard
BIOS driver A: is disk0
BIOS driver C: is disk2
BIOS 636kB/74512kB available memory
FreeBSD/i386 bootstrap loader, Revision 0.8
(mailto:jkh@narf.osd.bsdi.com, Sat Apr 21 08:46:19 GMT 2001)
Loading /boot/defaults/loader.conf
/kernel text=0x24f1db data=0x3007ec+0x2062c -
Hit [Enter] to boot immediagely, or any other key for command prompt.
Booting [kernel] in 9 seconds¡­
<-- press SPACE key here
Type '?' for a list of commands, 'help' for more detailed help.
ok load hpt27xx
/modules/hpt27xx.ko text=0xf571 data=0x2c8+0x254
ok boot
For FreeBSD 5.x/6.x/7.x/8.x/9.x, you can select 6 on the boot menu to get a loader
prompt.
7) You can add a below line into /boot/defaults/loader.conf to load the
driver automatically:
hpt27xx_load="YES"
Please refer to the installation guide in HighPoint FreeBSD driver release
package for more information.
#############################################################################
Technical support and service
If you have questions about installing or using your HighPoint product,
check the user's guide or readme file first, and you will find answers to
most of your questions here. If you need further assistance, please
contact us. We offer the following support and information services:
1) The HighPoint Web Site provides information on software upgrades,
answers to common questions, and other topics. The Web Site is
available from Internet 24 hours a day, 7 days a week, at
http://www.highpoint-tech.com.
2) For technical support, send e-mail to support@highpoint-tech.com
NOTE: Before you send an e-mail, please visit our Web Site
(http://www.highpoint-tech.com) to check if there is a new or
updated device driver for your system.
$FreeBSD$

File diff suppressed because it is too large Load Diff

187
sys/dev/hpt27xx/array.h Normal file
View File

@ -0,0 +1,187 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _HPT_ARRAY_H_
#define _HPT_ARRAY_H_
#define VERMAGIC_ARRAY 46
#if defined(__cplusplus)
extern "C" {
#endif
#define MAX_ARRAY_NAME 16
#ifndef MAX_MEMBERS
#define MAX_MEMBERS 16
#endif
#if MAX_MEMBERS<=16
typedef HPT_U16 HPT_MMASK;
#elif MAX_MEMBERS<=32
typedef HPT_U32 HPT_MMASK;
#elif MAX_MEMBERS<=64
typedef HPT_U64 HPT_MMASK;
#else
#error "MAX_MEMBERS too large"
#endif
#define HPT_MMASK_VALUE(x) (HPT_MMASK)((HPT_MMASK)1<<(x))
#if MAX_MEMBERS<32
#define HPT_MMASK_VALUE_SAFE(x) HPT_MMASK_VALUE(x)
#else
#define HPT_MMASK_VALUE_SAFE(x) ((x)>=MAX_MEMBERS? (HPT_MMASK)0 : HPT_MMASK_VALUE(x))
#endif
#define MAX_REBUILD_SECTORS 128
typedef struct _RAID_FLAGS {
HPT_UINT rf_need_initialize : 1;
HPT_UINT rf_need_rebuild: 1;
HPT_UINT rf_need_sync: 1;
/* ioctl flags */
HPT_UINT rf_auto_rebuild: 1;
HPT_UINT rf_rebuilding: 1;
HPT_UINT rf_verifying: 1;
HPT_UINT rf_initializing: 1;
HPT_UINT rf_abort_verifying: 1;
HPT_UINT rf_raid15: 1;
HPT_UINT rf_v3_format : 1;
HPT_UINT rf_need_transform : 1;
HPT_UINT rf_transforming : 1;
HPT_UINT rf_abort_transform : 1;
HPT_UINT rf_log_write: 1;
} RAID_FLAGS;
typedef struct transform_cmd_ext
{
HPT_LBA lba;
HPT_U16 total_sectors;
HPT_U16 finished_sectors;
} TRANSFORM_CMD_EXT , *PTRANSFORM_CMD_EXT;
#define TO_MOVE_DATA 0
#define TO_INITIALIZE 1
#define TO_INITIALIZE_ONLY 2
#define TO_MOVE_DATA_ONLY 3
typedef struct hpt_transform
{
HPT_U32 stamp;
PVDEV source;
PVDEV target;
struct list_head link;
HPT_U8 transform_from_tail;
struct tq_item task;
struct lock_request lock;
TRANSFORM_CMD_EXT cmdext;
HPT_U64 transform_point;
HPT_U16 transform_sectors_per_step;
HPT_U8 operation;
HPT_U8 disabled;
} HPT_TRANSFORM, *PHPT_TRANSFORM;
typedef struct hpt_array
{
HPT_U32 array_stamp;
HPT_U32 data_stamp;
HPT_U32 array_sn;
HPT_U8 ndisk;
HPT_U8 block_size_shift;
HPT_U16 strip_width;
HPT_U8 sector_size_shift; /*sector size = 512B<<sector_size_shift*/
HPT_U8 jid;
HPT_U8 reserved[2];
HPT_MMASK outdated_members;
HPT_MMASK offline_members;
PVDEV member[MAX_MEMBERS];
RAID_FLAGS flags;
HPT_U64 rebuilt_sectors;
HPT_U8 name[MAX_ARRAY_NAME];
PHPT_TRANSFORM transform;
TIME_RECORD create_time;
HPT_U8 description[64];
HPT_U8 create_manager[16];
#ifdef OS_SUPPORT_TASK
int floating_priority;
OSM_TASK ioctl_task;
IOCTL_ARG ioctl_arg;
char ioctl_inbuf[sizeof(PVDEV)+sizeof(HPT_U64)+sizeof(HPT_U16)];
char ioctl_outbuf[sizeof(HPT_UINT)];
#endif
} HPT_ARRAY, *PHPT_ARRAY;
#ifdef OS_SUPPORT_TASK
void ldm_start_rebuild(struct _VDEV *pArray);
#else
#define ldm_start_rebuild(pArray)
#endif
typedef struct _raw_partition{
struct _raw_partition * next;
__HPT_RAW_LBA start;
__HPT_RAW_LBA capacity;
PVDEV vd_part;
} RAW_PARTITION, *PRAW_PARTITION;
typedef struct hpt_partiton
{
PVDEV raw_disk;
__HPT_RAW_LBA des_location;
PRAW_PARTITION raw_part;
HPT_U8 del_mbr;
HPT_U8 reserved[3];
} HPT_PARTITION, *PHPT_PARTITION;
void ldm_check_array_online(PVDEV pArray);
void ldm_generic_member_failed(PVDEV member);
void ldm_sync_array_info(PVDEV pArray);
void ldm_sync_array_stamp(PVDEV pArray);
void ldm_add_spare_to_array(PVDEV pArray, PVDEV spare_partition);
#if defined(__cplusplus)
}
#endif
#endif

496
sys/dev/hpt27xx/him.h Normal file
View File

@ -0,0 +1,496 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _HPT_HIM_H_
#define _HPT_HIM_H_
#define VERMAGIC_HIM 55
#if defined(__cplusplus)
extern "C" {
#endif
#include <dev/hpt27xx/list.h>
#define SECTOR_TO_BYTE_SHIFT 9
#define SECTOR_TO_BYTE(x) ((HPT_U32)(x) << SECTOR_TO_BYTE_SHIFT)
#define BYTE_TO_SECTOR(x) ((x)>>SECTOR_TO_BYTE_SHIFT)
typedef struct _PCI_ID
{
HPT_U16 vid;
HPT_U16 did;
HPT_U32 subsys;
HPT_U8 rev;
HPT_U8 nbase;
HPT_U16 reserve;
}
PCI_ID;
typedef struct _PCI_ADDRESS
{
HPT_U8 tree;
HPT_U8 bus;
HPT_U8 device;
HPT_U8 function;
}
PCI_ADDRESS;
typedef struct _HIM_ADAPTER_CONFIG
{
PCI_ADDRESS pci_addr;
PCI_ID pci_id;
HPT_U8 max_devices;
HPT_U8 bProbeInInitializing:1;
HPT_U8 bSpinupOneDevEachTime:1;
HPT_U8 bGlobalNcq:1;
HPT_U8 bSGPIOPartSupport:1;
HPT_U8 bNeedSASIdleTimer:1;
HPT_U8 reserved:3;
HPT_U8 bDevsPerBus;
HPT_U8 first_on_slot;
HPT_U8 bChipType;
HPT_U8 bChipIntrNum;
HPT_U8 bChipFlags;
HPT_U8 bNumBuses;
HPT_U8 szVendorID[36];
HPT_U8 szProductID[36];
HPT_U32 nvramSize;
HPT_U64 nvramAddress;
HPT_U8 slot_index;
HPT_U8 reserved2[11];
}
HIM_ADAPTER_CONFIG, *PHIM_ADAPTER_CONFIG;
typedef struct _HIM_CHANNEL_CONFIG
{
HPT_U32 io_port;
HPT_U32 ctl_port;
} HIM_CHANNEL_CONFIG, *PHIM_CHANNEL_CONFIG;
typedef struct _HIM_DEVICE_FLAGS
{
HPT_UINT df_atapi :1;
HPT_UINT df_removable_drive :1;
HPT_UINT df_on_line :1;
HPT_UINT df_reduce_mode :1;
HPT_UINT df_sata :1;
HPT_UINT df_on_pm_port :1;
HPT_UINT df_support_read_ahead :1;
HPT_UINT df_read_ahead_enabled :1;
HPT_UINT df_support_write_cache :1;
HPT_UINT df_write_cache_enabled :1;
HPT_UINT df_cdrom_device :1;
HPT_UINT df_tape_device :1;
HPT_UINT df_support_tcq :1;
HPT_UINT df_tcq_enabled :1;
HPT_UINT df_support_ncq :1;
HPT_UINT df_ncq_enabled :1;
HPT_UINT df_sas :1;
HPT_UINT df_in_enclosure :1;
HPT_UINT df_ssd :1;
} DEVICE_FLAGS, *PDEVICE_FLAGS;
#pragma pack(1)
typedef struct _IDENTIFY_DATA {
HPT_U16 GeneralConfiguration;
HPT_U16 NumberOfCylinders;
HPT_U16 Reserved1;
HPT_U16 NumberOfHeads;
HPT_U16 UnformattedBytesPerTrack;
HPT_U16 UnformattedBytesPerSector;
HPT_U8 SasAddress[8];
HPT_U16 SerialNumber[10];
HPT_U16 BufferType;
HPT_U16 BufferSectorSize;
HPT_U16 NumberOfEccBytes;
HPT_U16 FirmwareRevision[4];
HPT_U16 ModelNumber[20];
HPT_U8 MaximumBlockTransfer;
HPT_U8 VendorUnique2;
HPT_U16 DoubleWordIo;
HPT_U16 Capabilities;
HPT_U16 Reserved2;
HPT_U8 VendorUnique3;
HPT_U8 PioCycleTimingMode;
HPT_U8 VendorUnique4;
HPT_U8 DmaCycleTimingMode;
HPT_U16 TranslationFieldsValid;
HPT_U16 NumberOfCurrentCylinders;
HPT_U16 NumberOfCurrentHeads;
HPT_U16 CurrentSectorsPerTrack;
HPT_U32 CurrentSectorCapacity;
HPT_U16 CurrentMultiSectorSetting;
HPT_U32 UserAddressableSectors;
HPT_U8 SingleWordDMASupport;
HPT_U8 SingleWordDMAActive;
HPT_U8 MultiWordDMASupport;
HPT_U8 MultiWordDMAActive;
HPT_U8 AdvancedPIOModes;
HPT_U8 Reserved4;
HPT_U16 MinimumMWXferCycleTime;
HPT_U16 RecommendedMWXferCycleTime;
HPT_U16 MinimumPIOCycleTime;
HPT_U16 MinimumPIOCycleTimeIORDY;
HPT_U16 Reserved5[2];
HPT_U16 ReleaseTimeOverlapped;
HPT_U16 ReleaseTimeServiceCommand;
HPT_U16 MajorRevision;
HPT_U16 MinorRevision;
HPT_U16 MaxQueueDepth;
HPT_U16 SataCapability;
HPT_U16 Reserved6[9];
HPT_U16 CommandSupport;
HPT_U16 CommandEnable;
HPT_U16 UtralDmaMode;
HPT_U16 Reserved7[11];
HPT_U32 Lba48BitLow;
HPT_U32 Lba48BitHigh;
HPT_U16 Reserved8[23];
HPT_U16 SpecialFunctionsEnabled;
HPT_U16 Reserved9[128];
}
#ifdef __GNUC__
__attribute__((packed))
#endif
IDENTIFY_DATA, *PIDENTIFY_DATA;
#pragma pack()
typedef struct _HIM_DEVICE_CONFIG
{
HPT_U64 capacity;
DEVICE_FLAGS flags;
HPT_U8 path_id;
HPT_U8 target_id;
HPT_U8 max_queue_depth;
HPT_U8 spin_up_mode;
HPT_U8 reserved;
HPT_U8 transfer_mode;
HPT_U8 bMaxShowMode;
HPT_U8 bDeUsable_Mode;
HPT_U16 max_sectors_per_cmd;
PIDENTIFY_DATA pIdentifyData;
HPT_U8 fixed_path_id; /*equals to phy id */
}
HIM_DEVICE_CONFIG, *PHIM_DEVICE_CONFIG;
#define _DIT_MODE 0
#define _DIT_601 1
#define _DIT_READ_AHEAD 2
#define _DIT_WRITE_CACHE 3
#define _DIT_TCQ 4
#define _DIT_NCQ 5
#define _DIT_BEEP_OFF 6
#define _DIT_SPIN_UP_MODE 7
#define _DIT_IDLE_STANDBY 8
#define _DIT_IDENTIFY 9
#define SPIN_UP_MODE_NOSUPPORT 0
#define SPIN_UP_MODE_FULL 1
#define SPIN_UP_MODE_STANDBY 2
struct tcq_control {
HPT_U8 enable;
HPT_U8 depth;
};
struct ncq_control {
HPT_U8 enable;
HPT_U8 depth;
};
typedef struct _HIM_ALTERABLE_DEV_INFO{
HPT_U8 type;
union {
HPT_U8 mode;
HPT_U8 enable_read_ahead;
HPT_U8 enable_read_cache;
HPT_U8 enable_write_cache;
struct tcq_control tcq;
struct ncq_control ncq;
void * adapter;
HPT_U8 spin_up_mode;
HPT_U8 idle_standby_timeout;
HPT_U8 identify_indicator;
}u;
} HIM_ALTERABLE_DEV_INFO, *PHIM_ALTERABLE_DEV_INFO;
struct _COMMAND;
struct _IOCTL_ARG;
typedef void (*PROBE_CALLBACK)(void *arg, void *dev, int index);
typedef struct _HIM {
char *name;
struct _HIM *next;
HPT_UINT max_sg_descriptors;
#define _HIM_INTERFACE(_type, _fn, _args) _type (* _fn) _args;
#include <dev/hpt27xx/himfuncs.h>
}
HIM, *PHIM;
#pragma pack(1)
#ifdef SG_FLAG_EOT
#error "don't use SG_FLAG_EOT with _SG.eot. clean the code!"
#endif
typedef struct _SG {
HPT_U32 size;
HPT_UINT eot;
union {
HPT_U8 FAR * _logical;
BUS_ADDRESS bus;
}
addr;
}
SG, *PSG;
#pragma pack()
typedef struct _AtaCommand
{
HPT_U64 Lba;
HPT_U16 nSectors;
HPT_U16 pad;
} AtaComm, *PAtaComm;
#define ATA_CMD_NOP 0x0
#define ATA_CMD_SET_FEATURES 0xef
#define ATA_CMD_FLUSH 0xE7
#define ATA_CMD_VERIFY 0x40
#define ATA_CMD_STANDBY 0xe2
#define ATA_CMD_READ_MULTI 0xC4
#define ATA_CMD_READ_MULTI_EXT 0x29
#define ATA_CMD_WRITE_MULTI 0xC5
#define ATA_CMD_WRITE_MULTI_EXT 0x39
#define ATA_CMD_WRITE_MULTI_FUA_EXT 0xCE
#define ATA_CMD_READ_DMA 0xc8 /* IDE DMA read command */
#define ATA_CMD_WRITE_DMA 0xca /* IDE DMA write command */
#define ATA_CMD_READ_DMA_EXT 0x25
#define ATA_CMD_READ_QUEUE_EXT 0x26
#define ATA_CMD_READ_MAX_ADDR 0x27
#define ATA_CMD_READ_EXT 0x24
#define ATA_CMD_VERIFY_EXT 0x42
#define ATA_CMD_WRITE_DMA_EXT 0x35
#define ATA_CMD_WRITE_QUEUE_EXT 0x36
#define ATA_CMD_WRITE_EXT 0x34
#define ATA_SET_FEATURES_XFER 0x3
#define ATA_SECTOR_SIZE 512
typedef struct _PassthroughCmd {
HPT_U16 bFeaturesReg;
HPT_U16 bSectorCountReg;
HPT_U16 bLbaLowReg;
HPT_U16 bLbaMidReg;
HPT_U16 bLbaHighReg;
HPT_U8 bDriveHeadReg;
HPT_U8 bCommandReg;
HPT_U16 nSectors;
HPT_U8 *pDataBuffer;
}
PassthroughCmd;
typedef struct _ScsiComm {
HPT_U8 cdbLength;
HPT_U8 senseLength;
HPT_U8 scsiStatus;
HPT_U8 reserve1;
HPT_U32 dataLength;
HPT_U8 *cdb;
HPT_U8 *senseBuffer;
}
ScsiComm;
#define CTRL_CMD_REBUILD 1
#define CTRL_CMD_VERIFY 2
#define CTRL_CMD_INIT 3
typedef struct _R5ControlCmd {
HPT_U64 StripeLine;
HPT_U16 Offset;
HPT_U8 Command;
HPT_U8 reserve1;
}
R5ControlCmd, *PR5ControlCmd;
typedef struct _HPT_ADDRESS
{
HPT_U8 * logical;
BUS_ADDRESS bus;
}
HPT_ADDRESS;
typedef struct ctl_pages {
HPT_ADDRESS *pages;
HPT_UINT page_size;
HPT_UINT npages;
HPT_UINT min_sg_descriptors;
} CONTROL_PAGES, *PCONTROL_PAGES;
typedef struct _R1ControlCmd {
HPT_U64 Lba;
HPT_U16 nSectors;
HPT_U8 Command; /* CTRL_CMD_XXX */
HPT_U8 reserve1;
PCONTROL_PAGES ctl_pages;
}
R1ControlCmd, *PR1ControlCmd;
typedef void (*TQ_PROC)(void *arg);
struct tq_item {
TQ_PROC proc;
void *arg;
struct tq_item *next;
};
#define INIT_TQ_ITEM(t, p, a) \
do { (t)->proc = p; (t)->arg = a; (t)->next = 0; } while (0)
typedef struct _COMMAND
{
struct _VBUS * vbus;
struct freelist *grplist;
HPT_UINT grpcnt;
struct list_head q_link;
struct tq_item done_dpc;
HPT_UINT extsize;
void *ext;
void *target;
void *priv;
HPT_UPTR priv2;
int priority;
struct lock_request *owned_lock;
struct lock_request *lock_req;
void (*dtor)(struct _COMMAND *, void *);
void *dtor_arg;
union{
AtaComm Ide;
PassthroughCmd Passthrough;
ScsiComm Scsi;
R5ControlCmd R5Control;
R1ControlCmd R1Control;
} uCmd;
HPT_U8 type; /* CMD_TYPE_* */
struct {
HPT_U8 physical_sg: 1;
HPT_U8 data_in: 1;
HPT_U8 data_out: 1;
HPT_U8 transform : 1;
HPT_U8 hard_flush: 2;
HPT_U8 from_cc: 1;
HPT_U8 force_cc: 1;
} flags;
/* return status */
HPT_U8 Result;
/* retry count */
HPT_U8 RetryCount;
PSG psg;
int (*buildsgl)(struct _COMMAND *cmd, PSG psg, int logical);
void (*done)(struct _COMMAND *cmd);
}
COMMAND, *PCOMMAND;
/* command types */
#define CMD_TYPE_IO 0
#define CMD_TYPE_CONTROL 1
#define CMD_TYPE_ATAPI 2
#define CMD_TYPE_SCSI CMD_TYPE_ATAPI
#define CMD_TYPE_PASSTHROUGH 3
#define CMD_TYPE_FLUSH 4
#define CMD_TYPE_IO_INDIRECT 0x80
/* flush command flags */
#define CF_HARD_FLUSH_CACHE 1
#define CF_HARD_FLUSH_STANDBY 2
/* command return values */
#define RETURN_PENDING 0
#define RETURN_SUCCESS 1
#define RETURN_BAD_DEVICE 2
#define RETURN_BAD_PARAMETER 3
#define RETURN_WRITE_NO_DRQ 4
#define RETURN_DEVICE_BUSY 5
#define RETURN_INVALID_REQUEST 6
#define RETURN_SELECTION_TIMEOUT 7
#define RETURN_IDE_ERROR 8
#define RETURN_NEED_LOGICAL_SG 9
#define RETURN_NEED_PHYSICAL_SG 10
#define RETURN_RETRY 11
#define RETURN_DATA_ERROR 12
#define RETURN_BUS_RESET 13
#define RETURN_BAD_TRANSFER_LENGTH 14
#define RETURN_INSUFFICIENT_MEMORY 15
#define RETURN_SECTOR_ERROR 16
#define RETURN_NEED_SPINUP 17
#if defined(__cplusplus)
}
#endif
#endif

107
sys/dev/hpt27xx/himfuncs.h Normal file
View File

@ -0,0 +1,107 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
/*
* define _HIM_INTERFACE before include this file, and
* undef it after include this file.
*/
#ifndef _HIM_INTERFACE
#error "you must define _HIM_INTERFACE before this file"
#endif
_HIM_INTERFACE(HPT_BOOL, get_supported_device_id, (int index, PCI_ID *id))
_HIM_INTERFACE(HPT_U8, get_controller_count, (PCI_ID *id, HPT_U8 *reached, PCI_ADDRESS *addr))
_HIM_INTERFACE(HPT_UINT, get_adapter_size, (const PCI_ID *id))
_HIM_INTERFACE(HPT_BOOL, create_adapter, (const PCI_ID *id, PCI_ADDRESS pciAddress, void *adapter, void *osext))
_HIM_INTERFACE(void, get_adapter_config, (void *adapter, HIM_ADAPTER_CONFIG *config))
_HIM_INTERFACE(HPT_BOOL, get_meminfo, (void *adapter))
_HIM_INTERFACE(HPT_BOOL, adapter_on_same_vbus, (void *adapter1, void *adapter2))
_HIM_INTERFACE(void, route_irq, (void *adapter, HPT_BOOL enable))
_HIM_INTERFACE(HPT_BOOL, initialize, (void *adapter))
_HIM_INTERFACE(HPT_UINT, get_device_size, (void *adapter))
_HIM_INTERFACE(HPT_BOOL, probe_device, (void *adapter, int index, void *devhandle, PROBE_CALLBACK done, void *arg))
_HIM_INTERFACE(void *, get_device, (void *adapter, int index))
_HIM_INTERFACE(void, get_device_config, (void *dev, HIM_DEVICE_CONFIG *config))
_HIM_INTERFACE(void, remove_device, (void *dev))
_HIM_INTERFACE(void, reset_device, (void * dev, void (*done)(void *arg), void *arg))
_HIM_INTERFACE(HPT_U32, get_cmdext_size, (void))
_HIM_INTERFACE(void, queue_cmd, (void *dev, struct _COMMAND *cmd))
_HIM_INTERFACE(int, read_write, (void *dev,HPT_LBA lba, HPT_U16 nsector, HPT_U8 *buffer, HPT_BOOL read))
_HIM_INTERFACE(HPT_BOOL, intr_handler, (void *adapter))
_HIM_INTERFACE(HPT_BOOL, intr_control, (void * adapter, HPT_BOOL enable))
_HIM_INTERFACE(int, get_channel_config, (void * adapter, int index, PHIM_CHANNEL_CONFIG pInfo))
_HIM_INTERFACE(int, set_device_info, (void * dev, PHIM_ALTERABLE_DEV_INFO pInfo))
_HIM_INTERFACE(void, unplug_device, (void * dev))
_HIM_INTERFACE(void, shutdown, (void *adapter))
_HIM_INTERFACE(void, suspend, (void *adapter))
_HIM_INTERFACE(void, resume, (void *adapter))
_HIM_INTERFACE(void, release_adapter, (void *adapter))
/*called after ldm_register_adapter*/
_HIM_INTERFACE(HPT_BOOL, verify_adapter, (void *adapter))
/* (optional) */
_HIM_INTERFACE(void, ioctl, (void * adapter, struct _IOCTL_ARG *arg))
_HIM_INTERFACE(int, compare_slot_seq, (void *adapter1, void *adapter2))
_HIM_INTERFACE(int, get_enclosure_count, (void *adapter))
_HIM_INTERFACE(int, get_enclosure_info, (void *adapter, int id, void *pinfo))
_HIM_INTERFACE(int, get_enclosure_info_v2, (void *adapter, int id, void *pinfo))
_HIM_INTERFACE(int, get_enclosure_info_v3, (void *adapter, int id, void *pinfo))
_HIM_INTERFACE(HPT_BOOL, flash_access, (void *adapter, HPT_U32 offset, void *value, int size, HPT_BOOL reading))
#undef _HIM_INTERFACE

View File

@ -0,0 +1,67 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
/****************************************************************************
* config.c - auto-generated file
****************************************************************************/
#include <dev/hpt27xx/os_bsd.h>
extern int init_module_him_rr2720(void);
extern int init_module_him_rr273x(void);
extern int init_module_him_rr276x(void);
extern int init_module_him_rr278x(void);
extern int init_module_vdev_raw(void);
extern int init_module_partition(void);
extern int init_module_raid0(void);
extern int init_module_raid1(void);
extern int init_module_raid5(void);
extern int init_module_jbod(void);
int init_config(void)
{
init_module_him_rr2720();
init_module_him_rr273x();
init_module_him_rr276x();
init_module_him_rr278x();
init_module_vdev_raw();
init_module_partition();
init_module_raid0();
init_module_raid1();
init_module_raid5();
init_module_jbod();
return 0;
}
char driver_name[] = "hpt27xx";
char driver_name_long[] = "RocketRAID 27xx controller driver";
char driver_ver[] = "v1.0 (" __DATE__ " " __TIME__ ")";
int osm_max_targets = 0xff;
int os_max_cache_size = 0x1000000;

View File

@ -0,0 +1,155 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#ifndef hpt27xx_CONFIG_H
#define hpt27xx_CONFIG_H
#define SUPPORT_ARRAY
#define __KERNEL__ 1
#define DRIVER_MINOR 16
#define TARGETNAME hpt27xx
#define __dummy_reg hpt27xx___dummy_reg
#define __ldm_alloc_cmd hpt27xx___ldm_alloc_cmd
#define delay_between_spinup hpt27xx_delay_between_spinup
#define dmapool_active hpt27xx_dmapool_active
#define dmapool_get_page hpt27xx_dmapool_get_page
#define dmapool_get_page_at hpt27xx_dmapool_get_page_at
#define dmapool_init hpt27xx_dmapool_init
#define dmapool_make_order hpt27xx_dmapool_make_order
#define dmapool_max_class_pages hpt27xx_dmapool_max_class_pages
#define dmapool_put_page hpt27xx_dmapool_put_page
#define dmapool_register_client hpt27xx_dmapool_register_client
#define driver_name hpt27xx_driver_name
#define driver_name_long hpt27xx_driver_name_long
#define driver_ver hpt27xx_driver_ver
#define freelist_get hpt27xx_freelist_get
#define freelist_get_dma hpt27xx_freelist_get_dma
#define freelist_put hpt27xx_freelist_put
#define freelist_put_dma hpt27xx_freelist_put_dma
#define freelist_reserve hpt27xx_freelist_reserve
#define freelist_reserve_dma hpt27xx_freelist_reserve_dma
#define gGlobalNcqFlag hpt27xx_gGlobalNcqFlag
#define gProbeInInitializing hpt27xx_gProbeInInitializing
#define gSGPIOPartSupport hpt27xx_gSGPIOPartSupport
#define gSpinupOneDevEachTime hpt27xx_gSpinupOneDevEachTime
#define g_legacy_mode hpt27xx_g_legacy_mode
#define gautorebuild hpt27xx_gautorebuild
#define grebuildpriority hpt27xx_grebuildpriority
#define him_handle_to_vbus hpt27xx_him_handle_to_vbus
#define him_list hpt27xx_him_list
#define init_config hpt27xx_init_config
#define init_module_him_rr2720 hpt27xx_init_module_him_rr2720
#define init_module_him_rr273x hpt27xx_init_module_him_rr273x
#define init_module_him_rr276x hpt27xx_init_module_him_rr276x
#define init_module_him_rr278x hpt27xx_init_module_him_rr278x
#define init_module_jbod hpt27xx_init_module_jbod
#define init_module_partition hpt27xx_init_module_partition
#define init_module_raid0 hpt27xx_init_module_raid0
#define init_module_raid1 hpt27xx_init_module_raid1
#define init_module_raid5 hpt27xx_init_module_raid5
#define init_module_vdev_raw hpt27xx_init_module_vdev_raw
#define ldm_acquire_lock hpt27xx_ldm_acquire_lock
#define ldm_add_spare_to_array hpt27xx_ldm_add_spare_to_array
#define ldm_alloc_cmds_R_6_55_75_46_64 hpt27xx_ldm_alloc_cmds_R_6_55_75_46_64
#define ldm_alloc_cmds_from_list hpt27xx_ldm_alloc_cmds_from_list
#define ldm_check_array_online hpt27xx_ldm_check_array_online
#define ldm_create_vbus hpt27xx_ldm_create_vbus
#define ldm_create_vdev hpt27xx_ldm_create_vdev
#define ldm_event_notify hpt27xx_ldm_event_notify
#define ldm_find_stamp hpt27xx_ldm_find_stamp
#define ldm_find_target hpt27xx_ldm_find_target
#define ldm_finish_cmd hpt27xx_ldm_finish_cmd
#define ldm_free_cmds hpt27xx_ldm_free_cmds
#define ldm_free_cmds_to_list hpt27xx_ldm_free_cmds_to_list
#define ldm_generic_member_failed hpt27xx_ldm_generic_member_failed
#define ldm_get_cmd_size hpt27xx_ldm_get_cmd_size
#define ldm_get_device_id hpt27xx_ldm_get_device_id
#define ldm_get_mem_info hpt27xx_ldm_get_mem_info
#define ldm_get_next_vbus hpt27xx_ldm_get_next_vbus
#define ldm_get_vbus_ext hpt27xx_ldm_get_vbus_ext
#define ldm_get_vbus_size hpt27xx_ldm_get_vbus_size
#define ldm_ide_fixstring hpt27xx_ldm_ide_fixstring
#define ldm_idle hpt27xx_ldm_idle
#define ldm_initialize_vbus_async hpt27xx_ldm_initialize_vbus_async
#define ldm_intr hpt27xx_ldm_intr
#define ldm_ioctl hpt27xx_ldm_ioctl
#define ldm_on_timer hpt27xx_ldm_on_timer
#define ldm_queue_cmd hpt27xx_ldm_queue_cmd
#define ldm_queue_task hpt27xx_ldm_queue_task
#define ldm_queue_vbus_dpc hpt27xx_ldm_queue_vbus_dpc
#define ldm_register_adapter hpt27xx_ldm_register_adapter
#define ldm_register_device hpt27xx_ldm_register_device
#define ldm_register_him_R_6_55_75_46_64 hpt27xx_ldm_register_him_R_6_55_75_46_64
#define ldm_register_vdev_class_R_6_55_75_46_64 hpt27xx_ldm_register_vdev_class_R_6_55_75_46_64
#define ldm_release_lock hpt27xx_ldm_release_lock
#define ldm_release_vbus hpt27xx_ldm_release_vbus
#define ldm_release_vdev hpt27xx_ldm_release_vdev
#define ldm_remove_timer hpt27xx_ldm_remove_timer
#define ldm_request_timer hpt27xx_ldm_request_timer
#define ldm_reset_vbus hpt27xx_ldm_reset_vbus
#define ldm_resume hpt27xx_ldm_resume
#define ldm_run hpt27xx_ldm_run
#define ldm_set_autorebuild hpt27xx_ldm_set_autorebuild
#define ldm_shutdown hpt27xx_ldm_shutdown
#define ldm_suspend hpt27xx_ldm_suspend
#define ldm_sync_array_info hpt27xx_ldm_sync_array_info
#define ldm_sync_array_stamp hpt27xx_ldm_sync_array_stamp
#define ldm_timer_probe_device hpt27xx_ldm_timer_probe_device
#define ldm_unregister_device hpt27xx_ldm_unregister_device
#define log_sector_repair hpt27xx_log_sector_repair
#define num_drives_per_spinup hpt27xx_num_drives_per_spinup
#define os_get_stamp hpt27xx_os_get_stamp
#define os_get_vbus_seq hpt27xx_os_get_vbus_seq
#define os_inb hpt27xx_os_inb
#define os_inl hpt27xx_os_inl
#define os_insw hpt27xx_os_insw
#define os_inw hpt27xx_os_inw
#define os_map_pci_bar hpt27xx_os_map_pci_bar
#define os_max_cache_size hpt27xx_os_max_cache_size
#define os_outb hpt27xx_os_outb
#define os_outl hpt27xx_os_outl
#define os_outsw hpt27xx_os_outsw
#define os_outw hpt27xx_os_outw
#define os_pci_readb hpt27xx_os_pci_readb
#define os_pci_readl hpt27xx_os_pci_readl
#define os_pci_readw hpt27xx_os_pci_readw
#define os_pci_writeb hpt27xx_os_pci_writeb
#define os_pci_writel hpt27xx_os_pci_writel
#define os_pci_writew hpt27xx_os_pci_writew
#define os_printk hpt27xx_os_printk
#define os_query_remove_device hpt27xx_os_query_remove_device
#define os_query_time hpt27xx_os_query_time
#define os_request_timer hpt27xx_os_request_timer
#define os_revalidate_device hpt27xx_os_revalidate_device
#define os_schedule_task hpt27xx_os_schedule_task
#define os_stallexec hpt27xx_os_stallexec
#define os_unmap_pci_bar hpt27xx_os_unmap_pci_bar
#define osm_max_targets hpt27xx_osm_max_targets
#define pcicfg_read_dword hpt27xx_pcicfg_read_dword
#define vbus_list hpt27xx_vbus_list
#define vdev_queue_cmd hpt27xx_vdev_queue_cmd
#endif

2112
sys/dev/hpt27xx/hptintf.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

533
sys/dev/hpt27xx/ldm.h Normal file
View File

@ -0,0 +1,533 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _HPT_LDM_H_
#define _HPT_LDM_H_
#define VERMAGIC_LDM 75
#if defined(__cplusplus)
extern "C" {
#endif
#define __hpt_set_ver(x, v1, v2, v3, v4, v5) x ## _R_ ## v1 ## _ ## v2 ## _ ## v3 ## _ ## v4 ## _ ## v5
#define _hpt_set_ver(x, v1, v2, v3, v4, v5) __hpt_set_ver(x, v1, v2, v3, v4, v5)
#define hpt_set_ver(x) _hpt_set_ver(x, VERMAGIC_OSM, VERMAGIC_HIM, VERMAGIC_LDM, VERMAGIC_ARRAY, MAX_MEMBERS)
#define ldm_register_him hpt_set_ver(ldm_register_him)
#define ldm_register_vdev_class hpt_set_ver(ldm_register_vdev_class)
#define ldm_alloc_cmds hpt_set_ver(ldm_alloc_cmds)
#ifndef HPT_INTERFACE_VERSION
#define HPT_INTERFACE_VERSION 0x02010000
#endif
#ifndef MAX_PARTITIONS_PER_DISK
#define MAX_PARTITIONS_PER_DISK 4
#endif
#if defined(__MAX_PARTITIONS_PER_DISK) && MAX_PARTITIONS_PER_DISK > __MAX_PARTITIONS_PER_DISK
#error "Please redefine MAX_PARTITIONS_PER_DISK!!!"
#endif
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
typedef char check_HPT_TIME_is_unsigned[ (HPT_TIME)(-1) > 0 ? 1 : -1 ];
#define hpt_time_after_eq(a, b) ((int)(a) - (int)(b) >= 0)
#define hpt_time_after(a, b) ((int)(a) - (int)(b) > 0)
struct freelist {
int dma;
HPT_UINT alignment;
HPT_UINT count;
HPT_UINT size;
void * head;
struct freelist *next;
#if DBG
char *tag;
HPT_UINT reserved_count;
#define freelist_debug_tag(list, _tag) (list)->tag = _tag
#else
#define freelist_debug_tag(list, _tag)
#endif
};
void freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count);
void *freelist_get(struct freelist *);
void freelist_put(struct freelist *, void *p);
void freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count);
void *freelist_get_dma(struct freelist *, BUS_ADDRESS *busaddr);
void freelist_put_dma(struct freelist *, void *p, BUS_ADDRESS busaddr);
#define freelist_reserve_with_tag(list, osext, size, count) \
do {\
freelist_debug_tag(list, #list " at " __FILE__);\
freelist_reserve(list, osext, (HPT_UINT)(size), (HPT_UINT)(count));\
}while(0)
#define freelist_reserve_dma_with_tag(list, osext, size, alignment, count) \
do {\
freelist_debug_tag(list, #list " at " __FILE__);\
freelist_reserve_dma(list, osext, (HPT_UINT)(size), (HPT_UINT)(alignment), (HPT_UINT)(count));\
}while(0)
struct lock_request {
HPT_U64 start, end;
struct lock_request *next;
struct list_head waiters; /* blocked commands */
struct tq_item callback;
int lock_cc;
};
#define INIT_LOCK_REQUEST(req, _start, _end, _cb, _arg, _cc) \
do {\
(req)->next = 0;\
(req)->start = _start;\
(req)->end = _end;\
INIT_TQ_ITEM(&(req)->callback, _cb, _arg);\
INIT_LIST_HEAD(&(req)->waiters);\
(req)->lock_cc = _cc;\
} while (0)
struct task_queue {
struct tq_item *head, *tail;
};
#define TQ_EMPTY(tq) ((tq)->head==0)
struct dmapool_order {
HPT_UINT npages;
struct tq_item wakeup_fn;
struct dmapool_order *next;
};
struct dmapool_client {
void * handle;
HPT_UINT (*shrink)(void *handle, HPT_UINT npages);
int (*resume)(void *handle);
struct dmapool_client *next;
};
typedef struct _VBUS * PVBUS;
typedef struct _VDEV * PVDEV;
void dmapool_register_client(PVBUS vbus, struct dmapool_client *client);
void dmapool_active(PVBUS vbus);
/* return 0 if the request is immediately satisfied, non-zero otherwise. */
int dmapool_make_order(PVBUS vbus, struct dmapool_order *order);
void *dmapool_get_page(PVBUS vbus, BUS_ADDRESS *busaddr);
void *dmapool_get_page_at(PVBUS vbus, void *p, BUS_ADDRESS *busaddr);
void dmapool_put_page(PVBUS vbus, void *p, BUS_ADDRESS busaddr);
void dmapool_init(PVBUS vbus);
HPT_UINT dmapool_max_class_pages(PVBUS vbus);
struct timer_call {
HPT_U32 interval; /*microseconds*/
HPT_TIME expire_time; /*microseconds*/
void (*proc)(void * arg);
void * arg;
struct timer_call ** pprev;
struct timer_call * next;
};
#define ldm_init_timer(timer) do { (timer)->next=0; (timer)->pprev=0; } while (0)
#define INIT_TIMER_CALL(timer, _interval, _proc, _arg) \
do { \
HPT_ASSERT((timer)->next==0 && (timer)->pprev==0);\
(timer)->interval = _interval;\
(timer)->proc = _proc;\
(timer)->arg = _arg;\
} while(0)
void ldm_request_timer(PVBUS vbus, struct timer_call * tc);
void ldm_remove_timer(PVBUS vbus, struct timer_call * tc);
void ldm_on_timer(PVBUS vbus);
typedef struct _LDM_ADAPTER
{
struct _LDM_ADAPTER *next;
HIM *him;
void *him_handle;
PVBUS vbus;
struct freelist freelist_dev;
int devid_start;
struct freelist freelist_plugged_dpc;
HPT_BOOL master;
}
LDM_ADAPTER, *PLDM_ADAPTER;
typedef struct _IOCTL_ARG
{
struct list_head link;
PVBUS vbus;
HPT_U32 dwIoControlCode;
HPT_U32 nInBufferSize;
HPT_U32 nOutBufferSize;
void * lpInBuffer;
void * lpOutBuffer;
HPT_U32 *lpBytesReturned;
void * ioctl_cmnd;
void (* done)(struct _IOCTL_ARG *);
int result; /* HPT_IOCTL_RESULT_ */
struct tq_item dpc;
} IOCTL_ARG;
#define HPT_IOCTL_RESULT_OK 0
#define HPT_IOCTL_RESULT_FAILED (-1)
#define HPT_IOCTL_RESULT_INVALID (-2)
#define HPT_IOCTL_RESULT_RETRY (-3)
#define HPT_IOCTL_RESULT_WRONG_VBUS (-4)
void ldm_ioctl( PVBUS vbus, IOCTL_ARG *IAPnt);
void ldm_set_autorebuild(PVBUS vbus, int enable);
HPT_U32 ldm_get_device_id(PVDEV vd); /* for ioctl */
#ifndef __HPT_RAW_LBA
#define __HPT_RAW_LBA HPT_RAW_LBA
#endif
#include <dev/hpt27xx/array.h>
typedef struct hpt_raw_disk
{
#ifdef SUPPORT_ARRAY
PRAW_PARTITION raw_part_list;
__HPT_RAW_LBA max_available_capacity;
__HPT_RAW_LBA total_available_capacity;
#endif
__HPT_RAW_LBA real_capacity;
__HPT_RAW_LBA head_position;
HPT_U16 max_sectors_per_cmd;
HPT_U8 max_queue_depth;
HPT_U8 user_select_mode;
HPT_UINT uninitialized : 1;
HPT_UINT legacy_disk : 1;
HPT_UINT is_spare : 1;
HPT_UINT v3_format : 1;
HPT_UINT need_sync : 1;
HPT_UINT temp_spare : 1;
HPT_UINT need_check_array : 1;
HPT_UINT df_user_mode_set: 1;
HPT_UINT df_read_ahead_set: 1;
HPT_UINT enable_read_ahead : 1;
HPT_UINT df_write_cache_set: 1;
HPT_UINT enable_write_cache : 1;
HPT_UINT df_tcq_set: 1;
HPT_UINT enable_tcq : 1;
HPT_UINT df_ncq_set: 1;
HPT_UINT enable_ncq : 1;
HIM * him;
int index;
PLDM_ADAPTER adapter;
void * phy_dev;
char model[40];
struct tq_item reset_dpc;
int reset_pending;
struct tq_item fail_dpc;
int fail_pending;
}
HPT_RAW_DISK, *PHPT_RAW_DISK;
struct vdev_class
{
struct vdev_class *next;
HPT_U8 __type;
HPT_U8 stripped; /* RAID0,3,5,6 */
HPT_U8 redundancy; /* RAID1-1, RAID3/5-1, RAID6-2 */
HPT_U8 must_init; /* RAID3,5,6 */
HPT_U8 docache;
HPT_UINT vbus_ext_size;
HPT_UINT vbus_ext_offset; /* used by LDM */
HPT_UINT dev_ext_size;
HPT_UINT cmd_ext_size;
void (*get_mem_info)(PVBUS vbus, void *osext, int phydev_count);
void (*queue_cmd)(PCOMMAND cmd);
void (*member_failed)(struct _VDEV * vd);
void (*initialize)(PVBUS vbus);
void (*release)(PVBUS vbus);
int (*add)(PVDEV vd);
void (*remove)(PVDEV vd);
void (*reset)(PVDEV vd);
void (*sync_stamp)(PVDEV vd);
int (*support_type)(int type);
};
#define VDEV_CLASS_CONSTRUCTOR(type, prefix) { \
0, \
type, \
prefix ## _stripped, \
prefix ## _redundancy, \
prefix ## _must_init, \
0, \
(HPT_UINT)(prefix ## _vbus_ext_size), \
0, \
(HPT_UINT)(prefix ## _dev_ext_size), \
(HPT_UINT)(prefix ## _cmd_ext_size), \
prefix ## _get_mem_info, \
prefix ## _queue_cmd, \
prefix ## _member_failed, \
prefix ## _initialize, \
prefix ## _release, \
prefix ## _add, \
prefix ## _remove, \
prefix ## _reset, \
prefix ## _sync_stamp, \
0 \
}
#define VD_RAW 1
#define VD_PARTITION 4
#define mIsArray(vdev_type) ((vdev_type)>VD_PARTITION)
#define VD_RAID0 5
#define VD_RAID1 6
#define VD_JBOD 7
#define VD_RAID5 8
#define VD_RAID6 9
#define VD_RAID3 10
#define VD_RAID4 11
#define VD_RAID1E 12
#define MAX_VD_TYPE_ID 12
struct vdev_class *ldm_find_vdev_class(HPT_U8 type);
typedef struct _VDEV {
PVBUS vbus;
struct vdev_class *Class;
HPT_U8 type;
PVDEV parent;
void * ext;
HPT_U64 capacity;
int target_id;
HPT_UINT cmds_per_request;
union {
#ifdef SUPPORT_ARRAY
HPT_ARRAY array;
HPT_PARTITION partition;
#endif
HPT_RAW_DISK raw;
} u;
HPT_U8 vf_online : 1;
HPT_U8 vf_bootmark : 1;
HPT_U8 vf_bootable : 1;
HPT_U8 vf_resetting: 1;
HPT_U8 vf_quiesced: 1;
HPT_U8 vf_clslock: 1;
HPT_U8 cache_policy; /* see CACHE_POLICY_* */
HPT_UINT cq_len;
HPT_UINT cmds_sent;
struct list_head link;
struct list_head cq_wait_send;
struct list_head cq_sent;
HPT_U32 last_active;
int cq_priority;
struct list_head cq_wait_lock;
struct lock_request *locks_granted;
struct lock_request *locks_wait;
HPT_U32 ioctl_id;
void * cc_ext;
}
VDEV;
#define CACHE_POLICY_NONE 0
#define CACHE_POLICY_WRITE_THROUGH 1
#define CACHE_POLICY_WRITE_BACK 2
extern HIM *him_list;
void ldm_register_him(PHIM him);
void ldm_register_vdev_class(struct vdev_class *Class);
HPT_BOOL ldm_register_adapter(PLDM_ADAPTER adapter);
int init_config(void);
HPT_UINT ldm_get_vbus_size(void);
void ldm_create_vbus(PVBUS vbus, void *osext);
void ldm_get_mem_info(PVBUS vbus, void *osext);
void *ldm_get_vbus_ext(PVBUS vbus, struct vdev_class *Class);
PVBUS ldm_get_next_vbus(PVBUS vbus, void **posext);
#define ldm_for_each_vbus(vbus, vbus_ext) \
for (vbus = ldm_get_next_vbus(0, (void **)(void *)&vbus_ext); vbus; \
vbus = ldm_get_next_vbus(vbus, (void **)(void *)&vbus_ext))
void ldm_initialize_vbus_async(PVBUS vbus, PLDM_ADAPTER master_adapter, void (*done)(void *osext));
/* ldm_initialize_vbus is deprecated since it will hold the CPU too long. */
#define ldm_initialize_vbus(vbus, adapter) ldm_initialize_vbus_async(vbus, adapter, 0)
void ldm_release_vbus(PVBUS vbus);
PVDEV ldm_create_vdev(PVBUS vbus, HPT_U8 type);
void ldm_release_vdev(PVDEV vd);
PVDEV ldm_find_target(PVBUS vbus, int id);
PVDEV ldm_find_stamp(PVBUS vbus, HPT_U32 stamp, int seq);
PCOMMAND ldm_alloc_cmds(PVBUS vbus, HPT_UINT cnt);
void ldm_free_cmds(PCOMMAND cmd);
HPT_UINT ldm_get_cmd_size(void);
PCOMMAND ldm_alloc_cmds_from_list(PVBUS vbus, struct freelist *list, HPT_UINT cnt);
void ldm_free_cmds_to_list(struct freelist *list, PCOMMAND cmd);
PCOMMAND __ldm_alloc_cmd(struct freelist *list);
#ifdef OS_SUPPORT_TASK
#define CMD_SET_PRIORITY(cmd, pri) cmd->priority = (pri)
#else
#define CMD_SET_PRIORITY(cmd, pri)
#endif
#define CMD_GROUP_GET(grp, cmd) \
do {\
grp->grplist->count++;\
cmd = __ldm_alloc_cmd(grp->grplist);\
cmd->vbus = grp->vbus;\
cmd->grplist = grp->grplist;\
CMD_SET_PRIORITY(cmd, grp->priority);\
} while(0)
#define CMD_GROUP_PUT(grp, cmd) \
do {\
freelist_put(grp->grplist, cmd);\
grp->grplist->count--;\
} while (0)
void ldm_queue_cmd(PCOMMAND cmd);
void vdev_queue_cmd(PCOMMAND cmd);
void ldm_finish_cmd(PCOMMAND cmd);
int ldm_acquire_lock(PVDEV vd, struct lock_request *req);
void ldm_release_lock(PVDEV vd, struct lock_request *req);
void ldm_queue_task(struct task_queue *tq, struct tq_item *t);
void ldm_queue_vbus_dpc(PVBUS vbus, struct tq_item *t);
HPT_BOOL ldm_intr(PVBUS vbus);
void ldm_run(PVBUS vbus);
int ldm_idle(PVBUS vbus);
int ldm_reset_vbus(PVBUS vbus);
void ldm_suspend(PVBUS vbus);
void ldm_resume(PVBUS vbus);
void ldm_shutdown(PVBUS vbus);/*shutdown all the controllers*/
#define HIM_EVENT_DEVICE_REMOVED 1
#define HIM_EVENT_DEVICE_PLUGGED 2
#define HIM_EVENT_DEVICE_ERROR 3
#define HIM_EVENT_RESET_REQUIRED 4
#define HIM_EVENT_QUIESCE_DEVICE 5
#define HIM_EVENT_UNQUIESCE_DEVICE 6
#define HIM_EVENT_CONFIG_CHANGED 7
void ldm_event_notify(HPT_U32 event, void *arg1, void *arg2);
void log_sector_repair(PVDEV vd, int success, HPT_LBA lba, HPT_U16 nsectors);
void ldm_register_device(PVDEV vd);
void ldm_unregister_device(PVDEV vd);
PVBUS him_handle_to_vbus(void * him_handle);
void ldm_ide_fixstring (HPT_U8 *s, const int bytecount);
#if defined(__cplusplus)
}
#endif
#endif

130
sys/dev/hpt27xx/list.h Normal file
View File

@ -0,0 +1,130 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _HPT_LIST_H_
#define _HPT_LIST_H_
#ifndef _LINUX_LIST_H
#ifndef HPT_INLINE
#define HPT_INLINE __inline
#endif
struct list_head {
struct list_head *next, *prev;
};
#define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr); (ptr)->prev = (ptr); } while (0)
static HPT_INLINE void __list_add(struct list_head * _new, struct list_head * prev, struct list_head * next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
static HPT_INLINE void list_add(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head, head->next);
}
static HPT_INLINE void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
static HPT_INLINE void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
static HPT_INLINE void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static HPT_INLINE void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
static HPT_INLINE int list_empty(struct list_head *head)
{
HPT_ASSERT(!(head->next==head && head->prev!=head));
return head->next == head;
}
static HPT_INLINE void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
static HPT_INLINE void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
static HPT_INLINE void list_splice_init(struct list_head *list, struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(HPT_UPTR)(&((type *)0)->member)))
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#define get_first_item(attached, type, member) \
((type *)((char *)((attached)->next)-(HPT_UPTR)(&((type *)0)->member)))
#endif
#endif

370
sys/dev/hpt27xx/os_bsd.c Normal file
View File

@ -0,0 +1,370 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#include <dev/hpt27xx/os_bsd.h>
/* hardware access */
HPT_U8 os_inb (void *port) { return inb((unsigned)(HPT_UPTR)port); }
HPT_U16 os_inw (void *port) { return inw((unsigned)(HPT_UPTR)port); }
HPT_U32 os_inl (void *port) { return inl((unsigned)(HPT_UPTR)port); }
void os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); }
void os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); }
void os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); }
void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count)
{ insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
void os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count)
{ outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
HPT_U32 __dummy_reg = 0;
/* PCI configuration space */
HPT_U8 os_pci_readb (void *osext, HPT_U8 offset)
{
return pci_read_config(((PHBA)osext)->pcidev, offset, 1);
}
HPT_U16 os_pci_readw (void *osext, HPT_U8 offset)
{
return pci_read_config(((PHBA)osext)->pcidev, offset, 2);
}
HPT_U32 os_pci_readl (void *osext, HPT_U8 offset)
{
return pci_read_config(((PHBA)osext)->pcidev, offset, 4);
}
void os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value)
{
pci_write_config(((PHBA)osext)->pcidev, offset, value, 1);
}
void os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value)
{
pci_write_config(((PHBA)osext)->pcidev, offset, value, 2);
}
void os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value)
{
pci_write_config(((PHBA)osext)->pcidev, offset, value, 4);
}
#if __FreeBSD_version < 500043
/* PCI space access */
HPT_U8 pcicfg_read_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
{
HPT_U8 v;
pcicfgregs pciref;
pciref.bus = bus;
pciref.slot = dev;
pciref.func = func;
v = pci_cfgread(&pciref, reg, 1);
return v;
}
HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
{
HPT_U32 v;
pcicfgregs pciref;
pciref.bus = bus;
pciref.slot = dev;
pciref.func = func;
v = pci_cfgread(&pciref, reg, 4);
return v;
}
void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v)
{
pcicfgregs pciref;
pciref.hose = -1;
pciref.bus = bus;
pciref.slot = dev;
pciref.func = func;
pci_cfgwrite(&pciref, reg, v, 1);
}
void pcicfg_write_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U32 v)
{
pcicfgregs pciref;
pciref.hose = -1;
pciref.bus = bus;
pciref.slot = dev;
pciref.func = func;
pci_cfgwrite(&pciref, reg, v, 4);
}/* PCI space access */
#else
HPT_U8 pcicfg_read_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
{
return (HPT_U8)pci_cfgregread(bus, dev, func, reg, 1);
}
HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
{
return (HPT_U32)pci_cfgregread(bus, dev, func, reg, 4);;
}
void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v)
{
pci_cfgregwrite(bus, dev, func, reg, v, 1);
}
void pcicfg_write_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U32 v)
{
pci_cfgregwrite(bus, dev, func, reg, v, 4);
}/* PCI space access */
#endif
void *os_map_pci_bar(
void *osext,
int index,
HPT_U32 offset,
HPT_U32 length
)
{
PHBA hba = (PHBA)osext;
HPT_U32 base;
hba->pcibar[index].rid = 0x10 + index * 4;
base = pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4);
if (base & 1) {
hba->pcibar[index].type = SYS_RES_IOPORT;
hba->pcibar[index].res = bus_alloc_resource(hba->pcidev,
hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE);
hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1);
} else {
hba->pcibar[index].type = SYS_RES_MEMORY;
hba->pcibar[index].res = bus_alloc_resource(hba->pcidev,
hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE);
hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset;
}
return hba->pcibar[index].base;
}
void os_unmap_pci_bar(void *osext, void *base)
{
PHBA hba = (PHBA)osext;
int index;
for (index=0; index<6; index++) {
if (hba->pcibar[index].base==base) {
bus_release_resource(hba->pcidev, hba->pcibar[index].type,
hba->pcibar[index].rid, hba->pcibar[index].res);
hba->pcibar[index].base = 0;
return;
}
}
}
void freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count)
{
PVBUS_EXT vbus_ext = osext;
if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
vbus_ext = ((PHBA)osext)->vbus_ext;
list->next = vbus_ext->freelist_head;
vbus_ext->freelist_head = list;
list->dma = 0;
list->size = size;
list->head = 0;
#if DBG
list->reserved_count =
#endif
list->count = count;
}
void *freelist_get(struct freelist *list)
{
void * result;
if (list->count) {
HPT_ASSERT(list->head);
result = list->head;
list->head = *(void **)result;
list->count--;
return result;
}
return 0;
}
void freelist_put(struct freelist * list, void *p)
{
HPT_ASSERT(list->dma==0);
list->count++;
*(void **)p = list->head;
list->head = p;
}
void freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count)
{
PVBUS_EXT vbus_ext = osext;
if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
vbus_ext = ((PHBA)osext)->vbus_ext;
list->next = vbus_ext->freelist_dma_head;
vbus_ext->freelist_dma_head = list;
list->dma = 1;
list->alignment = alignment;
list->size = size;
list->head = 0;
#if DBG
list->reserved_count =
#endif
list->count = count;
}
void *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr)
{
void *result;
HPT_ASSERT(list->dma);
result = freelist_get(list);
if (result)
*busaddr = *(BUS_ADDRESS *)((void **)result+1);
return result;
}
void freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr)
{
HPT_ASSERT(list->dma);
list->count++;
*(void **)p = list->head;
*(BUS_ADDRESS *)((void **)p+1) = busaddr;
list->head = p;
}
HPT_U32 os_get_stamp(void)
{
HPT_U32 stamp;
do { stamp = random(); } while (stamp==0);
return stamp;
}
void os_stallexec(HPT_U32 microseconds)
{
DELAY(microseconds);
}
static void os_timer_for_ldm(void *arg)
{
PVBUS_EXT vbus_ext = (PVBUS_EXT)arg;
ldm_on_timer((PVBUS)vbus_ext->vbus);
}
void os_request_timer(void * osext, HPT_U32 interval)
{
PVBUS_EXT vbus_ext = osext;
HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
untimeout(os_timer_for_ldm, vbus_ext, vbus_ext->timer);
vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext, interval * hz / 1000000);
}
HPT_TIME os_query_time(void)
{
return ticks * (1000000 / hz);
}
void os_schedule_task(void *osext, OSM_TASK *task)
{
PVBUS_EXT vbus_ext = osext;
HPT_ASSERT(task->next==0);
if (vbus_ext->tasks==0)
vbus_ext->tasks = task;
else {
OSM_TASK *t = vbus_ext->tasks;
while (t->next) t = t->next;
t->next = task;
}
if (vbus_ext->worker.ta_context)
TASK_ENQUEUE(&vbus_ext->worker);
}
int os_revalidate_device(void *osext, int id)
{
return 0;
}
int os_query_remove_device(void *osext, int id)
{
PVBUS_EXT vbus_ext = (PVBUS_EXT)osext;
struct cam_periph *periph = NULL;
struct cam_path *path;
int status,retval = 0;
status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0);
if (status == CAM_REQ_CMP) {
if((periph = cam_periph_find(path, "da")) != NULL){
if(periph->refcount >= 1)
retval = -1;
}
xpt_free_path(path);
}
return retval;
}
HPT_U8 os_get_vbus_seq(void *osext)
{
return ((PVBUS_EXT)osext)->sim->path_id;
}
int os_printk(char *fmt, ...)
{
va_list args;
static char buf[512];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
return printf("%s: %s\n", driver_name, buf);
}
#if DBG
void os_check_stack(const char *location, int size){}
void __os_dbgbreak(const char *file, int line)
{
printf("*** break at %s:%d ***", file, line);
while (1);
}
int hpt_dbg_level = 1;
#endif

263
sys/dev/hpt27xx/os_bsd.h Normal file
View File

@ -0,0 +1,263 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _OS_BSD_H
#define _OS_BSD_H
#ifndef DBG
#define DBG 0
#endif
#include <sys/param.h>
#include <sys/types.h>
#include <sys/cons.h>
#if (__FreeBSD_version >= 500000)
#include <sys/time.h>
#include <sys/systm.h>
#else
#include <machine/clock.h> /*to support DELAY function under 4.x BSD versions*/
#endif
#include <sys/stat.h>
#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/libkern.h>
#include <sys/kernel.h>
#if (__FreeBSD_version >= 500000)
#include <sys/kthread.h>
#include <sys/mutex.h>
#include <sys/module.h>
#endif
#include <sys/eventhandler.h>
#include <sys/bus.h>
#include <sys/taskqueue.h>
#include <sys/ioccom.h>
#include <machine/resource.h>
#if __FreeBSD_version >= 500043
#include <machine/pci_cfgreg.h>
#endif
#include <machine/bus.h>
#include <machine/stdarg.h>
#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#if (__FreeBSD_version >= 500000)
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#else
#include <pci/pcivar.h>
#include <pci/pcireg.h>
#endif
#if (__FreeBSD_version <= 500043)
#include <sys/devicestat.h>
#endif
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#include <cam/cam_debug.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_periph.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#if (__FreeBSD_version < 500043)
#include <sys/bus_private.h>
#endif
typedef struct _INQUIRYDATA {
u_char DeviceType : 5;
u_char DeviceTypeQualifier : 3;
u_char DeviceTypeModifier : 7;
u_char RemovableMedia : 1;
u_char Versions;
u_char ResponseDataFormat;
u_char AdditionalLength;
u_char Reserved[2];
u_char SoftReset : 1;
u_char CommandQueue : 1;
u_char Reserved2 : 1;
u_char LinkedCommands : 1;
u_char Synchronous : 1;
u_char Wide16Bit : 1;
u_char Wide32Bit : 1;
u_char RelativeAddressing : 1;
u_char VendorId[8];
u_char ProductId[16];
u_char ProductRevisionLevel[4];
u_char VendorSpecific[20];
u_char Reserved3[40];
}
__attribute__((packed))
INQUIRYDATA, *PINQUIRYDATA;
#endif
/* private headers */
#include <dev/hpt27xx/osm.h>
#include <dev/hpt27xx/him.h>
#include <dev/hpt27xx/ldm.h>
/* driver parameters */
extern char driver_name[];
extern char driver_name_long[];
extern char driver_ver[];
extern int osm_max_targets;
/*
* adapter/vbus extensions:
* each physical controller has an adapter_ext, passed to him.create_adapter()
* each vbus has a vbus_ext passed to ldm_create_vbus().
*/
#define EXT_TYPE_HBA 1
#define EXT_TYPE_VBUS 2
typedef struct _hba {
int ext_type;
LDM_ADAPTER ldm_adapter;
device_t pcidev;
PCI_ADDRESS pciaddr;
struct _vbus_ext *vbus_ext;
struct _hba *next;
struct {
struct resource *res;
int type;
int rid;
void *base;
}
pcibar[6];
struct resource *irq_res;
void *irq_handle;
}
HBA, *PHBA;
typedef struct _os_cmdext {
struct _vbus_ext *vbus_ext;
struct _os_cmdext *next;
union ccb *ccb;
bus_dmamap_t dma_map;
SG psg[os_max_sg_descriptors];
}
OS_CMDEXT, *POS_CMDEXT;
typedef struct _vbus_ext {
int ext_type;
struct _vbus_ext *next;
PHBA hba_list;
struct freelist *freelist_head;
struct freelist *freelist_dma_head;
struct cam_sim *sim; /* sim for this vbus */
struct cam_path *path; /* peripheral, path, tgt, lun with this vbus */
#if (__FreeBSD_version >= 500000)
struct mtx lock; /* general purpose lock */
#else
int hpt_splx;
#endif
bus_dma_tag_t io_dmat; /* I/O buffer DMA tag */
POS_CMDEXT cmdext_list;
OSM_TASK *tasks;
struct task worker;
struct callout_handle timer;
eventhandler_tag shutdown_eh;
/* the LDM vbus instance continues */
unsigned long vbus[0] __attribute__((aligned(sizeof(unsigned long))));
}
VBUS_EXT, *PVBUS_EXT;
#if __FreeBSD_version >= 500000
#define hpt_lock_vbus(vbus_ext) mtx_lock(&(vbus_ext)->lock)
#define hpt_unlock_vbus(vbus_ext) mtx_unlock(&(vbus_ext)->lock)
#else
static __inline void hpt_lock_vbus(PVBUS_EXT vbus_ext)
{
vbus_ext->hpt_splx = splcam();
}
static __inline void hpt_unlock_vbus(PVBUS_EXT vbus_ext)
{
splx(vbus_ext->hpt_splx);
}
#endif
#define HPT_OSM_TIMEOUT (20*hz) /* timeout value for OS commands */
#define HPT_DO_IOCONTROL _IOW('H', 0, HPT_IOCTL_PARAM)
#define HPT_SCAN_BUS _IO('H', 1)
#if __FreeBSD_version >= 501000
#define TASK_ENQUEUE(task) taskqueue_enqueue(taskqueue_swi_giant,(task));
#else
#define TASK_ENQUEUE(task) taskqueue_enqueue(taskqueue_swi,(task));
#endif
#if __FreeBSD_version >= 500000
static __inline int hpt_sleep(PVBUS_EXT vbus_ext, void *ident, int priority, const char *wmesg, int timo)
{
return msleep(ident, &vbus_ext->lock, priority, wmesg, timo);
}
#else
static __inline int hpt_sleep(PVBUS_EXT vbus_ext, void *ident, int priority, const char *wmesg, int timo)
{
int retval = 0;
asleep(ident, priority, wmesg, timo);
hpt_unlock_vbus(vbus_ext);
retval = await(priority, timo);
hpt_lock_vbus(vbus_ext);
return retval;
}
#endif
#if __FreeBSD_version < 501000
#define READ_16 0x88
#define WRITE_16 0x8a
#define SERVICE_ACTION_IN 0x9e
#endif
#define HPT_DEV_MAJOR 200

240
sys/dev/hpt27xx/osm.h Normal file
View File

@ -0,0 +1,240 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
#ifndef _HPT_OSM_H_
#define _HPT_OSM_H_
#define VERMAGIC_OSM 6
#define MAX_MEMBERS 64
#define os_max_queue_comm 32
#define os_max_sg_descriptors 18
extern int os_max_cache_size;
#define DMAPOOL_PAGE_SIZE 0x1000 /* PAGE_SIZE (i386/x86_64) */
#define os_max_cache_pages (os_max_cache_size/DMAPOOL_PAGE_SIZE)
/* data types */
typedef unsigned int HPT_UINT, HPT_U32;
typedef unsigned long HPT_UPTR;
typedef unsigned short HPT_U16;
typedef unsigned char HPT_U8;
typedef unsigned long HPT_TIME;
typedef unsigned long long HPT_U64;
#define CPU_TO_LE64(x) (x)
#define CPU_TO_LE32(x) (x)
#define CPU_TO_LE16(x) (x)
#define LE32_TO_CPU(x) (x)
#define LE16_TO_CPU(x) (x)
#define LE64_TO_CPU(x) (x)
static __inline HPT_U64 CPU_TO_BE64(HPT_U64 x)
{
HPT_U8 *p = (HPT_U8 *)&x;
return ((HPT_U64)p[0] << 56) |
((HPT_U64)p[1] << 48) |
((HPT_U64)p[2] << 40) |
((HPT_U64)p[3] << 32) |
((HPT_U64)p[4] << 24) |
((HPT_U64)p[5] << 16) |
((HPT_U64)p[6] << 8) |
p[7];
}
static __inline HPT_U32 CPU_TO_BE32(HPT_U32 x)
{
HPT_U8 *p = (HPT_U8 *)&x;
return ((HPT_U32)p[0] << 24) |
((HPT_U32)p[1] << 16) |
((HPT_U32)p[2] << 8) | p[3];
}
static __inline HPT_U16 CPU_TO_BE16(HPT_U16 x)
{
return ((HPT_U8)x << 8) | (x>>8);
}
#define BE16_TO_CPU(x) CPU_TO_BE16(x)
#define BE32_TO_CPU(x) CPU_TO_BE32(x)
#define BE64_TO_CPU(x) CPU_TO_BE64(x)
#define FAR
#define EXTERN_C
typedef void * HPT_PTR;
typedef HPT_U64 HPT_LBA;
typedef HPT_U64 HPT_RAW_LBA;
#define MAX_LBA_VALUE 0xffffffffffffffffull
#define MAX_RAW_LBA_VALUE MAX_LBA_VALUE
#define RAW_LBA(x) (x)
#define LO_LBA(x) ((HPT_U32)(x))
#define HI_LBA(x) (sizeof(HPT_LBA)>4? (HPT_U32)((x)>>32) : 0)
#define LBA_FORMAT_STR "0x%llX"
typedef HPT_U64 BUS_ADDRESS;
#define LO_BUSADDR(x) ((HPT_U32)(x))
#define HI_BUSADDR(x) (sizeof(BUS_ADDRESS)>4? (x)>>32 : 0)
typedef unsigned char HPT_BOOL;
#define HPT_TRUE 1
#define HPT_FALSE 0
typedef struct _TIME_RECORD {
HPT_U32 seconds:6; /* 0 - 59 */
HPT_U32 minutes:6; /* 0 - 59 */
HPT_U32 month:4; /* 1 - 12 */
HPT_U32 hours:6; /* 0 - 59 */
HPT_U32 day:5; /* 1 - 31 */
HPT_U32 year:5; /* 0=2000, 31=2031 */
} TIME_RECORD;
/* hardware access */
HPT_U8 os_inb (void *port);
HPT_U16 os_inw (void *port);
HPT_U32 os_inl (void *port);
void os_outb (void *port, HPT_U8 value);
void os_outw (void *port, HPT_U16 value);
void os_outl (void *port, HPT_U32 value);
void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count);
void os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count);
extern HPT_U32 __dummy_reg; /* to avoid the compiler warning */
#define os_readb(addr) (*(HPT_U8 *)&__dummy_reg = *(volatile HPT_U8 *)(addr))
#define os_readw(addr) (*(HPT_U16 *)&__dummy_reg = *(volatile HPT_U16 *)(addr))
#define os_readl(addr) (*(HPT_U32 *)&__dummy_reg = *(volatile HPT_U32 *)(addr))
#define os_writeb(addr, val) *(volatile HPT_U8 *)(addr) = (HPT_U8)(val)
#define os_writew(addr, val) *(volatile HPT_U16 *)(addr) = (HPT_U16)(val)
#define os_writel(addr, val) *(volatile HPT_U32 *)(addr) = (HPT_U32)(val)
/* PCI configuration space for specified device*/
HPT_U8 os_pci_readb (void *osext, HPT_U8 offset);
HPT_U16 os_pci_readw (void *osext, HPT_U8 offset);
HPT_U32 os_pci_readl (void *osext, HPT_U8 offset);
void os_pci_writeb(void *osext, HPT_U8 offset, HPT_U8 value);
void os_pci_writew(void *osext, HPT_U8 offset, HPT_U16 value);
void os_pci_writel(void *osext, HPT_U8 offset, HPT_U32 value);
/* obsolute interface */
#define MAX_PCI_BUS_NUMBER 0xff
#define MAX_PCI_DEVICE_NUMBER 32
#define MAX_PCI_FUNC_NUMBER 1
HPT_U8 pcicfg_read_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg);
HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg);
void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v);
void pcicfg_write_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U32 v);
void *os_map_pci_bar(
void *osext,
int index,
HPT_U32 offset,
HPT_U32 length
);
void os_unmap_pci_bar(void *osext, void *base);
#define os_kmap_sgptr(psg) (psg->addr._logical)
#define os_kunmap_sgptr(ptr)
#define os_set_sgptr(psg, ptr) (psg)->addr._logical = (ptr)
/* timer */
void *os_add_timer(void *osext, HPT_U32 microseconds, void (*proc)(void *), void *arg);
void os_del_timer(void *handle);
void os_request_timer(void * osext, HPT_U32 interval);
HPT_TIME os_query_time(void);
/* task */
#define OS_SUPPORT_TASK
typedef struct _OSM_TASK {
struct _OSM_TASK *next;
void (*func)(void *vbus, void *data);
void *data;
}
OSM_TASK;
void os_schedule_task(void *osext, OSM_TASK *task);
/* misc */
HPT_U32 os_get_stamp(void);
void os_stallexec(HPT_U32 microseconds);
#ifndef _SYS_LIBKERN_H_
#define memcpy(dst, src, size) __builtin_memcpy((dst), (src), (size))
#define memcmp(dst, src, size) __builtin_memcmp((dst), (src), (size))
#define strcpy(dst, src) __builtin_strcpy((dst), (src))
static __inline void * memset(void *dst, int c, unsigned long size)
{
char *p;
for (p=(char*)dst; size; size--,p++) *p = c;
return dst;
}
#endif
#define farMemoryCopy(a,b,c) memcpy((char *)(a), (char *)(b), (HPT_U32)c)
#define os_register_device(osext, target_id)
#define os_unregister_device(osext, target_id)
int os_query_remove_device(void *osext, int target_id);
int os_revalidate_device(void *osext, int target_id);
HPT_U8 os_get_vbus_seq(void *osext);
/* debug support */
int os_printk(char *fmt, ...);
#if DBG
extern int hpt_dbg_level;
#define KdPrint(x) do { if (hpt_dbg_level) os_printk x; } while (0)
void __os_dbgbreak(const char *file, int line);
#define os_dbgbreak() __os_dbgbreak(__FILE__, __LINE__)
#define HPT_ASSERT(x) do { if (!(x)) os_dbgbreak(); } while (0)
void os_check_stack(const char *location, int size);
#define HPT_CHECK_STACK(size) os_check_stack(__FUNCTION__, (size))
#else
#define KdPrint(x)
#define HPT_ASSERT(x)
#define HPT_CHECK_STACK(size)
#endif
#define OsPrint(x) do { os_printk x; } while (0)
#endif

1421
sys/dev/hpt27xx/osm_bsd.c Normal file

File diff suppressed because it is too large Load Diff

56
sys/dev/hpt27xx/wj.h Normal file
View File

@ -0,0 +1,56 @@
/*-
* Copyright (c) 2011 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.
*
* $FreeBSD$
*/
#include <dev/hpt27xx/hpt27xx_config.h>
/*
* NVRAM write journaling interface.
*/
#ifndef _WJ_H_
#define _WJ_H_
#if defined(SUPPORT_BBU) || defined(SUPPORT_NVRAM)
void wj_init(PVBUS vbus, void *nvram_addr, HPT_U32 nvram_size);
void *wj_add_entry(PVBUS vbus, PVDEV vd, HPT_LBA lba, HPT_U16 sectors);
void *wj_get_entry(PVBUS vbus, PVDEV *vd_p, HPT_LBA *lba_p, HPT_U16 *sectors_p);
void wj_del_entry(PVBUS vbus, void *handle);
void wj_del_vd(PVBUS vbus, PVDEV vd);
void wj_sync_stamp(PVBUS vbus, PVDEV vd);
#else
#define wj_add_entry(vbus, vd, lba, sectors) 0
#define wj_get_entry(vbus, vd_p, lba_p, sectors_p) 0
#define wj_del_entry(vbus, handle) 0
#define wj_del_vd(vbus, vd) 0
#define wj_sync_stamp(vbus, vd) 0
#endif
#endif

View File

@ -705,6 +705,10 @@ device aacp # SCSI Passthrough interface (optional, CAM required)
#
device asr
#
# Highpoint RocketRAID 27xx.
device hpt27xx
#
# Highpoint RocketRAID 182x.
device hptmv

View File

@ -108,6 +108,7 @@ SUBDIR= ${_3dfx} \
hatm \
hifn \
hme \
${_hpt27xx} \
${_hptiop} \
${_hptmv} \
${_hptrr} \
@ -507,6 +508,7 @@ _coretemp= coretemp
_ctau= ctau
_dpt= dpt
_ex= ex
_hpt27xx= hpt27xx
_hptiop= hptiop
_hptmv= hptmv
_hptrr= hptrr
@ -582,6 +584,7 @@ _et= et
_em= em
_exca= exca
_ext2fs= ext2fs
_hpt27xx= hpt27xx
_hptiop= hptiop
_hptmv= hptmv
_hptrr= hptrr

View File

@ -0,0 +1,14 @@
# $FreeBSD$
HPT27XX= ${.CURDIR}/../../dev/hpt27xx
.PATH: ${HPT27XX}
KMOD= hpt27xx
SRCS= bus_if.h device_if.h pci_if.h
SRCS+= opt_cam.h opt_scsi.h
SRCS+= os_bsd.h os_bsd.c osm_bsd.c hpt27xx_config.c
OBJS+= hpt27xx_lib.o
hpt27xx_lib.o:
uudecode -p < ${HPT27XX}/$(MACHINE_ARCH)-elf.hpt27xx_lib.o.uu > ${.TARGET}
.include <bsd.kmod.mk>