Various fixes to hptmv(4):

- Replace the global driver lock with a per-instance device lock.
- Use the per-instance device lock instead of Giant for the CAM sim lock.
- Add global locks to protect the adapter list and DPC queues.
- Use wakeup() and mtx_sleep() to wait for certain events like the
  controller going idle rather than polling via timeouts passed to
  tsleep().
- Use callout(9) instead of timeout(9).
- Mark the interrupt handler MPSAFE.
- Remove compat shims for FreeBSD versions older than 8.0.

Reviewed by:	Steve Chang <ychang@highpoint-tech.com>
This commit is contained in:
John Baldwin 2014-08-05 23:58:49 +00:00
parent fae00455b5
commit 49b3fc4062
6 changed files with 195 additions and 380 deletions

View File

@ -40,20 +40,12 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/kthread.h>
#if (__FreeBSD_version >= 500000)
#include <sys/mutex.h>
#include <sys/module.h>
#endif
#include <sys/sx.h>
#if (__FreeBSD_version >= 500000)
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#else
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <sys/wait.h>
#include <sys/sysproto.h>
#endif
#ifndef __KERNEL__
#define __KERNEL__
@ -119,6 +111,7 @@ static void HPTLIBAPI fOsCommandDone(_VBUS_ARG PCommand pCmd);
static void ccb_done(union ccb *ccb);
static void hpt_queue_ccb(union ccb **ccb_Q, union ccb *ccb);
static void hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb);
static void hpt_intr_locked(IAL_ADAPTER_T *pAdapter);
static void hptmv_free_edma_queues(IAL_ADAPTER_T *pAdapter);
static void hptmv_free_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
static void handleEdmaError(_VBUS_ARG PCommand pCmd);
@ -143,6 +136,8 @@ static MV_BOOLEAN hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter,
#define ccb_ccb_ptr spriv_ptr0
#define ccb_adapter ccb_h.spriv_ptr1
static struct sx hptmv_list_lock;
SX_SYSINIT(hptmv_list_lock, &hptmv_list_lock, "hptmv list");
IAL_ADAPTER_T *gIal_Adapter = 0;
IAL_ADAPTER_T *pCurAdapter = 0;
static MV_SATA_CHANNEL gMvSataChannels[MAX_VBUS][MV_SATA_CHANNELS_NUM];
@ -159,48 +154,11 @@ UCHAR DPC_Request_Nums = 0;
static ST_HPT_DPC DpcQueue[MAX_DPC];
static int DpcQueue_First=0;
static int DpcQueue_Last = 0;
static struct mtx DpcQueue_Lock;
MTX_SYSINIT(hpmtv_dpc_lock, &DpcQueue_Lock, "hptmv dpc", MTX_DEF);
char DRIVER_VERSION[] = "v1.16";
#if (__FreeBSD_version >= 500000)
static struct mtx driver_lock;
intrmask_t lock_driver()
{
intrmask_t spl = 0;
mtx_lock(&driver_lock);
return spl;
}
void unlock_driver(intrmask_t spl)
{
mtx_unlock(&driver_lock);
}
#else
static int driver_locked = 0;
intrmask_t lock_driver()
{
intrmask_t spl = splcam();
loop:
while (driver_locked)
tsleep(&driver_locked, PRIBIO, "hptlck", hz);
atomic_add_int(&driver_locked, 1);
if (driver_locked>1) {
atomic_subtract_int(&driver_locked, 1);
goto loop;
}
return spl;
}
void unlock_driver(intrmask_t spl)
{
atomic_subtract_int(&driver_locked, 1);
if (driver_locked==0) {
wakeup(&driver_locked);
}
splx(spl);
}
#endif
/*******************************************************************************
* Name: hptmv_free_channel
*
@ -790,7 +748,8 @@ hptmv_handle_event(void * data, int flag)
IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)data;
MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
MV_U8 channelIndex;
mtx_assert(&pAdapter->lock, MA_OWNED);
/* mvOsSemTake(&pMvSataAdapter->semaphore); */
for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
{
@ -898,7 +857,7 @@ hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter, MV_EVENT_TYPE eventType,
KdPrint(("RR18xx [%d,%d]: device connected event received\n",
pMvSataAdapter->adapterId, channel));
/* Delete previous timers (if multiple drives connected in the same time */
pAdapter->event_timer_connect = timeout(hptmv_handle_event_connect, pAdapter, 10*hz);
callout_reset(&pAdapter->event_timer_connect, 10 * hz, hptmv_handle_event_connect, pAdapter);
}
else if (param1 == EVENT_DISCONNECT)
{
@ -907,7 +866,7 @@ hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter, MV_EVENT_TYPE eventType,
pMvSataAdapter->adapterId, channel));
device_change(pAdapter, channel, FALSE);
/* Delete previous timers (if multiple drives disconnected in the same time */
/*pAdapter->event_timer_disconnect = timeout(hptmv_handle_event_disconnect, pAdapter, 10*hz); */
/*callout_reset(&pAdapter->event_timer_disconnect, 10 * hz, hptmv_handle_event_disconnect, pAdapter); */
/*It is not necessary to wait, handle it directly*/
hptmv_handle_event_disconnect(pAdapter);
}
@ -1286,18 +1245,6 @@ dmamap_put(PBUS_DMAMAP p)
p->pAdapter->pbus_dmamap_list = p;
}
/*Since mtx not provide the initialize when declare, so we Final init here to initialize the global mtx*/
#if __FreeBSD_version >= 500000
#define override_kernel_driver()
static void hpt_init(void *dummy)
{
override_kernel_driver();
mtx_init(&driver_lock, "hptsleeplock", NULL, MTX_DEF);
}
SYSINIT(hptinit, SI_SUB_CONFIGURE, SI_ORDER_FIRST, hpt_init, NULL);
#endif
static int num_adapters = 0;
static int
init_adapter(IAL_ADAPTER_T *pAdapter)
@ -1308,8 +1255,11 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
PVDevice pVDev;
intrmask_t oldspl = lock_driver();
mtx_init(&pAdapter->lock, "hptsleeplock", NULL, MTX_DEF);
callout_init_mtx(&pAdapter->event_timer_connect, &pAdapter->lock, 0);
callout_init_mtx(&pAdapter->event_timer_disconnect, &pAdapter->lock, 0);
sx_xlock(&hptmv_list_lock);
pAdapter->next = 0;
if(gIal_Adapter == 0){
@ -1320,6 +1270,7 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
pCurAdapter->next = pAdapter;
pCurAdapter = pAdapter;
}
sx_xunlock(&hptmv_list_lock);
pAdapter->outstandingCommands = 0;
@ -1337,10 +1288,8 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
MAX_SG_DESCRIPTORS, /* nsegments */
0x10000, /* maxsegsize */
BUS_DMA_WAITOK, /* flags */
#if __FreeBSD_version>502000
busdma_lock_mutex, /* lockfunc */
&driver_lock, /* lockfuncarg */
#endif
&pAdapter->lock, /* lockfuncarg */
&pAdapter->io_dma_parent /* tag */))
{
return ENXIO;
@ -1350,7 +1299,6 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
if (hptmv_allocate_edma_queues(pAdapter))
{
MV_ERROR("RR18xx: Failed to allocate memory for EDMA queues\n");
unlock_driver(oldspl);
return ENOMEM;
}
@ -1363,7 +1311,6 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
{
MV_ERROR("RR18xx: Failed to remap memory space\n");
hptmv_free_edma_queues(pAdapter);
unlock_driver(oldspl);
return ENXIO;
}
else
@ -1393,7 +1340,6 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
unregister:
bus_release_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, rid, pAdapter->mem_res);
hptmv_free_edma_queues(pAdapter);
unlock_driver(oldspl);
return ENXIO;
}
pAdapter->ver_601 = pMvSataAdapter->pcbVersion;
@ -1438,7 +1384,7 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
free(pAdapter->pbus_dmamap, M_DEVBUF);
goto unregister;
}
callout_handle_init(&pmap->timeout_ch);
callout_init_mtx(&pmap->timeout, &pAdapter->lock, 0);
}
/* setup PRD Tables */
KdPrint(("Allocate PRD Tables\n"));
@ -1537,7 +1483,6 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
#endif
mvSataUnmaskAdapterInterrupt(pMvSataAdapter);
unlock_driver(oldspl);
return 0;
}
@ -2036,20 +1981,7 @@ hpt_attach(device_t dev)
struct cam_devq *devq;
struct cam_sim *hpt_vsim;
printf("%s Version %s \n", DRIVER_NAME, DRIVER_VERSION);
if (!pAdapter)
{
pAdapter = (IAL_ADAPTER_T *)malloc(sizeof (IAL_ADAPTER_T), M_DEVBUF, M_NOWAIT);
#if __FreeBSD_version > 410000
device_set_softc(dev, (void *)pAdapter);
#else
device_set_driver(dev, (driver_t *)pAdapter);
#endif
}
if (!pAdapter) return (ENOMEM);
bzero(pAdapter, sizeof(IAL_ADAPTER_T));
device_printf(dev, "%s Version %s \n", DRIVER_NAME, DRIVER_VERSION);
pAdapter->hpt_dev = dev;
@ -2064,13 +1996,9 @@ hpt_attach(device_t dev)
return(ENXIO);
}
#if __FreeBSD_version <700000
if (bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM,
hpt_intr, pAdapter, &pAdapter->hpt_intr))
#else
if (bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM,
if (bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq,
INTR_TYPE_CAM | INTR_MPSAFE,
NULL, hpt_intr, pAdapter, &pAdapter->hpt_intr))
#endif
{
hpt_printk(("can't set up interrupt\n"));
free(pAdapter, M_DEVBUF);
@ -2100,25 +2028,19 @@ hpt_attach(device_t dev)
/*
* Construct our SIM entry
*/
#if __FreeBSD_version <700000
hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll, __str(PROC_DIR_NAME),
pAdapter, device_get_unit(pAdapter->hpt_dev), 1, 8, devq);
#else
hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll, __str(PROC_DIR_NAME),
pAdapter, device_get_unit(pAdapter->hpt_dev), &Giant, 1, 8, devq);
#endif
pAdapter, device_get_unit(pAdapter->hpt_dev),
&pAdapter->lock, 1, 8, devq);
if (hpt_vsim == NULL) {
cam_simq_free(devq);
return ENOMEM;
}
#if __FreeBSD_version <700000
if (xpt_bus_register(hpt_vsim, 0) != CAM_SUCCESS)
#else
mtx_lock(&pAdapter->lock);
if (xpt_bus_register(hpt_vsim, dev, 0) != CAM_SUCCESS)
#endif
{
cam_sim_free(hpt_vsim, /*free devq*/ TRUE);
mtx_unlock(&pAdapter->lock);
hpt_vsim = NULL;
return ENXIO;
}
@ -2129,9 +2051,11 @@ hpt_attach(device_t dev)
{
xpt_bus_deregister(cam_sim_path(hpt_vsim));
cam_sim_free(hpt_vsim, /*free_devq*/TRUE);
mtx_unlock(&pAdapter->lock);
hpt_vsim = NULL;
return ENXIO;
}
mtx_unlock(&pAdapter->lock);
xpt_setup_ccb(&(ccb->ccb_h), pAdapter->path, /*priority*/5);
ccb->ccb_h.func_code = XPT_SASYNC_CB;
@ -2164,7 +2088,11 @@ hpt_detach(device_t dev)
static void
hpt_poll(struct cam_sim *sim)
{
hpt_intr((void *)cam_sim_softc(sim));
IAL_ADAPTER_T *pAdapter;
pAdapter = cam_sim_softc(sim);
hpt_intr_locked((void *)cam_sim_softc(sim));
}
/****************************************************************
@ -2174,9 +2102,19 @@ hpt_poll(struct cam_sim *sim)
static void
hpt_intr(void *arg)
{
IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)arg;
intrmask_t oldspl = lock_driver();
IAL_ADAPTER_T *pAdapter;
pAdapter = arg;
mtx_lock(&pAdapter->lock);
hpt_intr_locked(pAdapter);
mtx_unlock(&pAdapter->lock);
}
static void
hpt_intr_locked(IAL_ADAPTER_T *pAdapter)
{
mtx_assert(&pAdapter->lock, MA_OWNED);
/* KdPrintI(("----- Entering Isr() -----\n")); */
if (mvSataInterruptServiceRoutine(&pAdapter->mvSataAdapter) == MV_TRUE)
{
@ -2185,7 +2123,6 @@ hpt_intr(void *arg)
}
/* KdPrintI(("----- Leaving Isr() -----\n")); */
unlock_driver(oldspl);
}
/**********************************************************
@ -2228,11 +2165,11 @@ hpt_shutdown(device_t dev)
IAL_ADAPTER_T *pAdapter;
pAdapter = device_get_softc(dev);
if (pAdapter == NULL)
return (EINVAL);
EVENTHANDLER_DEREGISTER(shutdown_final, pAdapter->eh);
mtx_lock(&pAdapter->lock);
FlushAdapter(pAdapter);
mtx_unlock(&pAdapter->lock);
/* give the flush some time to happen,
*otherwise "shutdown -p now" will make file system corrupted */
DELAY(1000 * 1000 * 5);
@ -2288,6 +2225,7 @@ ccb_done(union ccb *ccb)
{
if(DPC_Request_Nums == 0)
Check_Idle_Call(pAdapter);
wakeup(pAdapter);
}
}
@ -2301,11 +2239,11 @@ ccb_done(union ccb *ccb)
void
hpt_action(struct cam_sim *sim, union ccb *ccb)
{
intrmask_t oldspl;
IAL_ADAPTER_T * pAdapter = (IAL_ADAPTER_T *) cam_sim_softc(sim);
PBUS_DMAMAP pmap;
_VBUS_INST(&pAdapter->VBus)
mtx_assert(&pAdapter->lock, MA_OWNED);
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("hpt_action\n"));
KdPrint(("hpt_action(%lx,%lx{%x})\n", (u_long)sim, (u_long)ccb, ccb->ccb_h.func_code));
@ -2327,7 +2265,6 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
return;
}
oldspl = lock_driver();
if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
Check_Idle_Call(pAdapter);
@ -2340,7 +2277,6 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
hpt_queue_ccb(&pAdapter->pending_Q, ccb);
else
OsSendCommand(_VBUS_P ccb);
unlock_driver(oldspl);
/* KdPrint(("leave scsiio\n")); */
break;
@ -2348,9 +2284,7 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
case XPT_RESET_BUS:
KdPrint(("reset bus\n"));
oldspl = lock_driver();
fResetVBus(_VBUS_P0);
unlock_driver(oldspl);
xpt_done(ccb);
break;
@ -2374,29 +2308,7 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
break;
case XPT_CALC_GEOMETRY:
#if __FreeBSD_version >= 500000
cam_calc_geometry(&ccb->ccg, 1);
#else
{
struct ccb_calc_geometry *ccg;
u_int32_t size_mb;
u_int32_t secs_per_cylinder;
ccg = &ccb->ccg;
size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size);
if (size_mb > 1024 ) {
ccg->heads = 255;
ccg->secs_per_track = 63;
} else {
ccg->heads = 64;
ccg->secs_per_track = 32;
}
secs_per_cylinder = ccg->heads * ccg->secs_per_track;
ccg->cylinders = ccg->volume_size / secs_per_cylinder;
ccb->ccb_h.status = CAM_REQ_CMP;
}
#endif
xpt_done(ccb);
break;
@ -2482,20 +2394,20 @@ hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb)
***************************************************************************/
static void hpt_worker_thread(void)
{
intrmask_t oldspl;
for(;;) {
mtx_lock(&DpcQueue_Lock);
while (DpcQueue_First!=DpcQueue_Last) {
ST_HPT_DPC p;
oldspl = lock_driver();
p = DpcQueue[DpcQueue_First];
DpcQueue_First++;
DpcQueue_First %= MAX_DPC;
DPC_Request_Nums++;
unlock_driver(oldspl);
mtx_unlock(&DpcQueue_Lock);
p.dpc(p.pAdapter, p.arg, p.flags);
oldspl = lock_driver();
mtx_lock(&p.pAdapter->lock);
mtx_lock(&DpcQueue_Lock);
DPC_Request_Nums--;
/* since we may have prevented Check_Idle_Call, do it here */
if (DPC_Request_Nums==0) {
@ -2505,28 +2417,22 @@ static void hpt_worker_thread(void)
CheckPendingCall(_VBUS_P0);
}
}
unlock_driver(oldspl);
mtx_unlock(&p.pAdapter->lock);
mtx_unlock(&DpcQueue_Lock);
/*Schedule out*/
#if (__FreeBSD_version < 500000)
YIELD_THREAD;
#else
#if (__FreeBSD_version > 700033)
pause("sched", 1);
#else
tsleep((caddr_t)hpt_worker_thread, PPAUSE, "sched", 1);
#endif
#endif
if (SIGISMEMBER(curproc->p_siglist, SIGSTOP)) {
/* abort rebuilding process. */
IAL_ADAPTER_T *pAdapter;
PVDevice pArray;
PVBus _vbus_p;
int i;
sx_slock(&hptmv_list_lock);
pAdapter = gIal_Adapter;
while(pAdapter != 0){
mtx_lock(&pAdapter->lock);
_vbus_p = &pAdapter->VBus;
for (i=0;i<MAX_ARRAY_PER_VBUS;i++)
@ -2540,34 +2446,24 @@ static void hpt_worker_thread(void)
pArray->u.array.rf_abort_rebuild = 1;
}
}
mtx_unlock(&pAdapter->lock);
pAdapter = pAdapter->next;
}
sx_sunlock(&hptmv_list_lock);
}
mtx_lock(&DpcQueue_Lock);
}
mtx_unlock(&DpcQueue_Lock);
/*Remove this debug option*/
/*
#ifdef DEBUG
if (SIGISMEMBER(curproc->p_siglist, SIGSTOP))
#if (__FreeBSD_version > 700033)
pause("hptrdy", 2*hz);
#else
tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz);
#endif
#endif
*/
#if (__FreeBSD_version >= 800002)
kproc_suspend_check(curproc);
#elif (__FreeBSD_version >= 500043)
kthread_suspend_check(curproc);
#else
kproc_suspend_loop(curproc);
#endif
#if (__FreeBSD_version > 700033)
pause("hptrdy", 2*hz); /* wait for something to do */
#else
tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz); /* wait for something to do */
#endif
pause("-", 2*hz); /* wait for something to do */
}
}
@ -2586,6 +2482,7 @@ launch_worker_thread(void)
kproc_start(&hpt_kp);
sx_slock(&hptmv_list_lock);
for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) {
_VBUS_INST(&pAdapTemp->VBus)
@ -2601,17 +2498,13 @@ launch_worker_thread(void)
(UCHAR)((pVDev->u.array.CriticalMembers || pVDev->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
}
}
sx_sunlock(&hptmv_list_lock);
/*
* hpt_worker_thread needs to be suspended after shutdown sync, when fs sync finished.
*/
#if (__FreeBSD_version < 500043)
EVENTHANDLER_REGISTER(shutdown_post_sync, shutdown_kproc, hptdaemonproc,
SHUTDOWN_PRI_LAST);
#else
EVENTHANDLER_REGISTER(shutdown_post_sync, kproc_shutdown, hptdaemonproc,
SHUTDOWN_PRI_LAST);
#endif
}
/*
*SYSINIT(hptwt, SI_SUB_KTHREAD_IDLE, SI_ORDER_FIRST, launch_worker_thread, NULL);
@ -2721,10 +2614,12 @@ SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
static void
hpt_timeout(void *arg)
{
_VBUS_INST(&((PBUS_DMAMAP)((union ccb *)arg)->ccb_adapter)->pAdapter->VBus)
intrmask_t oldspl = lock_driver();
PBUS_DMAMAP pmap = (PBUS_DMAMAP)((union ccb *)arg)->ccb_adapter;
IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
_VBUS_INST(&pAdapter->VBus)
mtx_assert(&pAdapter->lock, MA_OWNED);
fResetVBus(_VBUS_P0);
unlock_driver(oldspl);
}
static void
@ -2766,7 +2661,7 @@ hpt_io_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
}
}
pmap->timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz);
callout_reset(&pmap->timeout, 20 * hz, hpt_timeout, ccb);
pVDev->pfnSendCommand(_VBUS_P pCmd);
CheckPendingCall(_VBUS_P0);
}
@ -2964,6 +2859,8 @@ OsSendCommand(_VBUS_ARG union ccb *ccb)
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
dmamap_put(pmap);
pAdapter->outstandingCommands--;
if (pAdapter->outstandingCommands == 0)
wakeup(pAdapter);
xpt_done(ccb);
}
goto Command_Complished;
@ -2987,8 +2884,8 @@ fOsCommandDone(_VBUS_ARG PCommand pCmd)
IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
KdPrint(("fOsCommandDone(pcmd=%p, result=%d)\n", pCmd, pCmd->Result));
untimeout(hpt_timeout, (caddr_t)ccb, pmap->timeout_ch);
callout_stop(&pmap->timeout);
switch(pCmd->Result) {
case RETURN_SUCCESS:
@ -3032,9 +2929,11 @@ hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T * pAdapter, void *arg, UCHAR flags)
{
int p;
mtx_lock(&DpcQueue_Lock);
p = (DpcQueue_Last + 1) % MAX_DPC;
if (p==DpcQueue_First) {
KdPrint(("DPC Queue full!\n"));
mtx_unlock(&DpcQueue_Lock);
return -1;
}
@ -3043,6 +2942,7 @@ hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T * pAdapter, void *arg, UCHAR flags)
DpcQueue[DpcQueue_Last].arg = arg;
DpcQueue[DpcQueue_Last].flags = flags;
DpcQueue_Last = p;
mtx_unlock(&DpcQueue_Lock);
return 0;
}

View File

@ -132,11 +132,6 @@ typedef struct _VDevice_Ext
#define LongDiv(x, y) (x / (UINT)(y))
#define LongRem(x, y) (x % (UINT)(y))
#define LongMul(x, y) (x * y)
/* Minimum and maximum macros */
#if (__FreeBSD_version < 501000)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/*************************************************************************
* C library
@ -151,9 +146,6 @@ unsigned HPTLIBAPI os_strlen(const char *s);
#define memcpy os_memcpy
#define memset os_memset
#define strlen os_strlen
#elif (__FreeBSD_version <= 410000)
#define memcpy(d, s, len) bcopy((s),(d),(len))
#define memset(d, s, len) bzero((d),(len))
#endif
#define ZeroMemory(a, b) memset((char *)a, 0, b)
#define MemoryCopy(a,b,c) memcpy((char *)(a), (char *)(b), (UINT)(c))

View File

@ -65,8 +65,8 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
PVDevice pSubArray, pVDev;
UINT i, iarray, ichan;
struct cam_periph *periph = NULL;
intrmask_t oldspl;
mtx_lock(&pAdapter->lock);
#ifdef SUPPORT_ARRAY
if (length>=8 && strncmp(buffer, "rebuild ", 8)==0)
{
@ -74,7 +74,6 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
length-=8;
if (length>=5 && strncmp(buffer, "start", 5)==0)
{
oldspl = lock_driver();
for(i = 0; i < MAX_ARRAY_PER_VBUS; i++)
if ((pArray=ArrayTables(i))->u.array.dArStamp==0)
continue;
@ -83,12 +82,11 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray,
(UCHAR)((pArray->u.array.CriticalMembers || pArray->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
}
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
return orig_length;
}
else if (length>=4 && strncmp(buffer, "stop", 4)==0)
{
oldspl = lock_driver();
for(i = 0; i < MAX_ARRAY_PER_VBUS; i++)
if ((pArray=ArrayTables(i))->u.array.dArStamp==0)
continue;
@ -96,7 +94,7 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
if (pArray->u.array.rf_rebuilding)
pArray->u.array.rf_abort_rebuild = 1;
}
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
return orig_length;
}
else if (length>=3 && buffer[1]==','&& buffer[0]>='1'&& buffer[2]>='1')
@ -107,17 +105,24 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
if(iarray >= MAX_VDEVICE_PER_VBUS || ichan >= MV_SATA_CHANNELS_NUM) return -EINVAL;
pArray = _vbus_p->pVDevice[iarray];
if (!pArray || (pArray->vf_online == 0)) return -EINVAL;
if (!pArray || (pArray->vf_online == 0)) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
for (i=0;i<MV_SATA_CHANNELS_NUM;i++)
if(i == ichan)
goto rebuild;
mtx_unlock(&pAdapter->lock);
return -EINVAL;
rebuild:
pVDev = &pAdapter->VDevices[ichan];
if(!pVDev->u.disk.df_on_line || pVDev->pParent) return -EINVAL;
if(!pVDev->u.disk.df_on_line || pVDev->pParent) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
/* Not allow to use a mounted disk ??? test*/
for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++)
@ -127,6 +132,7 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
if (periph != NULL && periph->refcount >= 1)
{
hpt_printk(("Can not use disk used by OS!\n"));
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
/* the Mounted Disk isn't delete */
@ -139,15 +145,13 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
{
pSubArray = pArray;
loop:
oldspl = lock_driver();
if(hpt_add_disk_to_array(_VBUS_P VDEV_TO_ID(pSubArray), VDEV_TO_ID(pVDev)) == -1) {
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
pSubArray->u.array.rf_auto_rebuild = 0;
pSubArray->u.array.rf_abort_rebuild = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pSubArray, DUPLICATE);
unlock_driver(oldspl);
break;
}
case VD_RAID_0:
@ -159,8 +163,10 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
goto loop;
}
default:
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
mtx_unlock(&pAdapter->lock);
return orig_length;
}
}
@ -175,24 +181,31 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
if (length>=1 && *buffer>='1')
{
iarray = *buffer-'1';
if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL;
if(iarray >= MAX_VDEVICE_PER_VBUS) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
pArray = _vbus_p->pVDevice[iarray];
if (!pArray || (pArray->vf_online == 0)) return -EINVAL;
if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5)
if (!pArray || (pArray->vf_online == 0)) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
if(pArray->VDeviceType != VD_RAID_1 && pArray->VDeviceType != VD_RAID_5) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
if (!(pArray->u.array.rf_need_rebuild ||
pArray->u.array.rf_rebuilding ||
pArray->u.array.rf_verifying ||
pArray->u.array.rf_initializing))
{
oldspl = lock_driver();
pArray->u.array.RebuildSectors = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, VERIFY);
unlock_driver(oldspl);
}
mtx_unlock(&pAdapter->lock);
return orig_length;
}
}
@ -203,16 +216,21 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
if (length>=1 && *buffer>='1')
{
iarray = *buffer-'1';
if(iarray >= MAX_VDEVICE_PER_VBUS) return -EINVAL;
if(iarray >= MAX_VDEVICE_PER_VBUS) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
pArray = _vbus_p->pVDevice[iarray];
if (!pArray || (pArray->vf_online == 0)) return -EINVAL;
if (!pArray || (pArray->vf_online == 0)) {
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
if(pArray->u.array.rf_verifying)
{
oldspl = lock_driver();
pArray->u.array.rf_abort_rebuild = 1;
unlock_driver(oldspl);
}
mtx_unlock(&pAdapter->lock);
return orig_length;
}
}
@ -226,6 +244,7 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
_vbus_(r5.enable_write_back) = *buffer-'0';
if (_vbus_(r5.enable_write_back))
hpt_printk(("RAID5 write back enabled"));
mtx_unlock(&pAdapter->lock);
return orig_length;
}
}
@ -239,6 +258,7 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
length-=9;
if (length>=1 && *buffer>='0' && *buffer<='3') {
hpt_dbg_level = *buffer-'0';
mtx_unlock(&pAdapter->lock);
return orig_length;
}
}
@ -246,6 +266,7 @@ hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
/* TO DO */
}
#endif
mtx_unlock(&pAdapter->lock);
return -EINVAL;
}
@ -486,12 +507,12 @@ hpt_get_info(IAL_ADAPTER_T *pAdapter, HPT_GET_INFO *pinfo)
PVDevice pVDev;
#ifndef FOR_DEMO
mtx_lock(&pAdapter->lock);
if (pAdapter->beeping) {
intrmask_t oldspl = lock_driver();
pAdapter->beeping = 0;
BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress);
unlock_driver(oldspl);
}
mtx_unlock(&pAdapter->lock);
#endif
hpt_copy_info(pinfo, "Controller #%d:\n\n", pAdapter->mvSataAdapter.adapterId);
@ -610,16 +631,16 @@ hpt_status(FORMAL_HANDLER_ARGS)
#define xhptregister_node(name) hptregister_node(name)
#if (__FreeBSD_version < 500043)
#define hptregister_node(name) \
SYSCTL_NODE(, OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node") \
SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \
NULL, 0, hpt_status, "A", "Get/Set " #name " state")
#else
#if __FreeBSD_version >= 1100024
#define hptregister_node(name) \
SYSCTL_ROOT_NODE(OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node"); \
SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \
NULL, 0, hpt_status, "A", "Get/Set " #name " state");
NULL, 0, hpt_status, "A", "Get/Set " #name " state")
#else
#define hptregister_node(name) \
SYSCTL_NODE(, OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node"); \
SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \
NULL, 0, hpt_status, "A", "Get/Set " #name " state")
#endif
xhptregister_node(PROC_DIR_NAME);

View File

@ -33,13 +33,6 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#if (__FreeBSD_version < 500000)
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/wait.h>
#include <sys/sysproto.h>
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
@ -66,7 +59,7 @@ static int event_queue_head=0, event_queue_tail=0;
static int hpt_get_event(PHPT_EVENT pEvent);
static int hpt_set_array_state(DEVICEID idArray, DWORD state);
static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter);
static void lock_driver_idle(IAL_ADAPTER_T *pAdapter);
static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd);
static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd,
FPSCAT_GATH pSgTable, int logical);
@ -158,6 +151,7 @@ ioctl_ReportEvent(UCHAR event, PVOID param)
get_disk_location(&((PVDevice)param)->u.disk, &controller, &channel);
hpt_printk(("Device removed: controller %d channel %d\n", controller, channel));
}
wakeup(param);
}
static int
@ -195,30 +189,17 @@ hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
/* just to prevent driver from sending more commands */
static void HPTLIBAPI nothing(_VBUS_ARG void *notused){}
intrmask_t
void
lock_driver_idle(IAL_ADAPTER_T *pAdapter)
{
intrmask_t oldspl;
_VBUS_INST(&pAdapter->VBus)
oldspl = lock_driver();
mtx_lock(&pAdapter->lock);
while (pAdapter->outstandingCommands) {
KdPrint(("outstandingCommands is %d, wait..\n", pAdapter->outstandingCommands));
if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
unlock_driver(oldspl);
/*Schedule out*/
#if (__FreeBSD_version < 500000)
YIELD_THREAD;
#else
#if (__FreeBSD_version > 700033)
pause("switch", 1);
#else
tsleep(lock_driver_idle, PPAUSE, "switch", 1);
#endif
#endif
oldspl = lock_driver();
mtx_sleep(pAdapter, &pAdapter->lock, 0, "hptidle", 0);
}
CheckIdleCall(_VBUS_P0);
return oldspl;
}
int Kernel_DeviceIoControl(_VBUS_ARG
@ -329,9 +310,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
default:
{
PVDevice pVDev;
#ifdef SUPPORT_ARRAY
intrmask_t oldspl;
#endif
switch(dwIoControlCode) {
/* read-only ioctl functions can be called directly. */
case HPT_IOCTL_GET_VERSION:
@ -382,13 +361,13 @@ int Kernel_DeviceIoControl(_VBUS_ARG
* create_array, and other functions can't be executed while channel is
* perform I/O commands. Wait until driver is idle.
*/
oldspl = lock_driver_idle(pAdapter);
lock_driver_idle(pAdapter);
if (hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize,
lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) {
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
return -1;
}
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
}
else
return -1;
@ -401,7 +380,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
case HPT_IOCTL_CREATE_ARRAY:
{
pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt;
oldspl = lock_driver();
mtx_lock(&pAdapter->lock);
if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE)
{
(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0;
@ -415,7 +394,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
{
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY);
}
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
break;
}
@ -423,7 +402,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
case HPT_IOCTL_CREATE_ARRAY_V2:
{
pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt;
oldspl = lock_driver();
mtx_lock(&pAdapter->lock);
if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE) {
(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE);
@ -432,7 +411,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
} else if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY) {
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY);
}
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
break;
}
case HPT_IOCTL_ADD_DISK_TO_ARRAY:
@ -441,23 +420,16 @@ int Kernel_DeviceIoControl(_VBUS_ARG
pAdapter=(IAL_ADAPTER_T *)pArray->pVBus->OsExt;
if(pArray->u.array.rf_rebuilding == 0)
{
DWORD timeout = 0;
oldspl = lock_driver();
mtx_lock(&pAdapter->lock);
pArray->u.array.rf_auto_rebuild = 0;
pArray->u.array.rf_abort_rebuild = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
unlock_driver(oldspl);
while (!pArray->u.array.rf_rebuilding)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)Kernel_DeviceIoControl, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*3)
if (mtx_sleep(pArray, &pAdapter->lock, 0, "hptwait", hz * 3) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
}
@ -475,9 +447,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
static int
hpt_get_event(PHPT_EVENT pEvent)
{
intrmask_t oldspl = lock_driver();
int ret = event_queue_remove(pEvent);
unlock_driver(oldspl);
return ret;
}
@ -487,8 +457,6 @@ hpt_set_array_state(DEVICEID idArray, DWORD state)
IAL_ADAPTER_T *pAdapter;
PVDevice pVDevice = ID_TO_VDEV(idArray);
int i;
DWORD timeout = 0;
intrmask_t oldspl;
if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1;
if(!mIsArray(pVDevice))
@ -501,32 +469,27 @@ hpt_set_array_state(DEVICEID idArray, DWORD state)
{
case MIRROR_REBUILD_START:
{
mtx_lock(&pAdapter->lock);
if (pVDevice->u.array.rf_rebuilding ||
pVDevice->u.array.rf_verifying ||
pVDevice->u.array.rf_initializing)
pVDevice->u.array.rf_initializing) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
pVDevice->u.array.rf_auto_rebuild = 0;
pVDevice->u.array.rf_abort_rebuild = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice,
(UCHAR)((pVDevice->u.array.CriticalMembers || pVDevice->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
unlock_driver(oldspl);
while (!pVDevice->u.array.rf_rebuilding)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*20)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptwait", hz * 20) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
@ -537,25 +500,22 @@ hpt_set_array_state(DEVICEID idArray, DWORD state)
if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1)
hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state);
}
if(pVDevice->u.array.rf_rebuilding != 1)
mtx_lock(&pAdapter->lock);
if(pVDevice->u.array.rf_rebuilding != 1) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
pVDevice->u.array.rf_abort_rebuild = 1;
unlock_driver(oldspl);
while (pVDevice->u.array.rf_abort_rebuild)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*20)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptabrt", hz * 20) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
@ -563,98 +523,86 @@ hpt_set_array_state(DEVICEID idArray, DWORD state)
{
/*if(pVDevice->u.array.rf_verifying)
return -1;*/
mtx_lock(&pAdapter->lock);
if (pVDevice->u.array.rf_rebuilding ||
pVDevice->u.array.rf_verifying ||
pVDevice->u.array.rf_initializing)
pVDevice->u.array.rf_initializing) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
pVDevice->u.array.RebuildSectors = 0;
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
unlock_driver(oldspl);
while (!pVDevice->u.array.rf_verifying)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*20)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptvrfy", hz * 20) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
case AS_VERIFY_ABORT:
{
if(pVDevice->u.array.rf_verifying != 1)
mtx_lock(&pAdapter->lock);
if(pVDevice->u.array.rf_verifying != 1) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
pVDevice->u.array.rf_abort_rebuild = 1;
unlock_driver(oldspl);
while (pVDevice->u.array.rf_abort_rebuild)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*80)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptvrfy", hz * 80) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
case AS_INITIALIZE_START:
{
mtx_lock(&pAdapter->lock);
if (pVDevice->u.array.rf_rebuilding ||
pVDevice->u.array.rf_verifying ||
pVDevice->u.array.rf_initializing)
pVDevice->u.array.rf_initializing) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
unlock_driver(oldspl);
while (!pVDevice->u.array.rf_initializing)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*80)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptinit", hz * 80) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
case AS_INITIALIZE_ABORT:
{
if(pVDevice->u.array.rf_initializing != 1)
mtx_lock(&pAdapter->lock);
if(pVDevice->u.array.rf_initializing != 1) {
mtx_unlock(&pAdapter->lock);
return -1;
}
oldspl = lock_driver();
pVDevice->u.array.rf_abort_rebuild = 1;
unlock_driver(oldspl);
while (pVDevice->u.array.rf_abort_rebuild)
{
#if (__FreeBSD_version > 700033)
pause("pause", 1);
#else
tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
#endif
if ( timeout >= hz*80)
if (mtx_sleep(pVDevice, &pAdapter->lock, 0,
"hptinit", hz * 80) != 0)
break;
timeout ++;
}
mtx_unlock(&pAdapter->lock);
}
break;
@ -739,21 +687,19 @@ thread_io_done(_VBUS_ARG PCommand pCmd)
void
hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
{
DWORD timeout = 0;
ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
PCommand pCmd;
UINT result;
int needsync=0, retry=0, needdelete=0;
void *buffer = 0;
intrmask_t oldspl;
_VBUS_INST(&pAdapter->VBus)
if (pArray->u.array.rf_broken==1 ||
pArray->u.array.RebuildSectors>=capacity)
return;
oldspl = lock_driver();
mtx_lock(&pAdapter->lock);
switch(flags)
{
@ -797,9 +743,7 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
#define MAX_REBUILD_SECTORS 0x40
/* take care for discontinuous buffer in R1ControlSgl */
unlock_driver(oldspl);
buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
oldspl = lock_driver();
if(!buffer) {
FreeCommand(_VBUS_P pCmd);
hpt_printk(("can't allocate rebuild buffer\n"));
@ -854,12 +798,7 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
CheckPendingCall(_VBUS_P0);
if (!End_Job) {
unlock_driver(oldspl);
while (!End_Job) {
tsleep((caddr_t)pCmd, PPAUSE, "pause", hz);
if (timeout++>60) break;
}
oldspl = lock_driver();
mtx_sleep(pCmd, &pAdapter->lock, 0, "hptrbld", hz * 60);
if (!End_Job) {
hpt_printk(("timeout, reset\n"));
fResetVBus(_VBUS_P0);
@ -868,9 +807,7 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
result = pCmd->Result;
FreeCommand(_VBUS_P pCmd);
unlock_driver(oldspl);
if (buffer) free(buffer, M_DEVBUF);
oldspl = lock_driver();
KdPrintI(("cmd finished %d", result));
switch(result)
@ -1000,18 +937,7 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
KdPrintI(("currcmds is %d, wait..\n", pAdapter->outstandingCommands));
/* put this to have driver stop processing system commands quickly */
if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
unlock_driver(oldspl);
/*Schedule out*/
#if (__FreeBSD_version < 500000)
YIELD_THREAD;
#else
#if (__FreeBSD_version > 700033)
pause("switch", 1);
#else
tsleep(hpt_rebuild_data_block, PPAUSE, "switch", 1);
#endif
#endif
oldspl = lock_driver();
mtx_sleep(pAdapter, &pAdapter->lock, 0, "hptidle", 0);
}
if (needsync) SyncArrayInfo(pArray);
@ -1019,5 +945,5 @@ hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
fDeleteArray(_VBUS_P pArray, TRUE);
Check_Idle_Call(pAdapter);
unlock_driver(oldspl);
mtx_unlock(&pAdapter->lock);
}

View File

@ -33,17 +33,7 @@
#include <sys/bus.h>
#include <machine/resource.h>
#if __FreeBSD_version >= 500043
#include <machine/pci_cfgreg.h>
#endif
#if (__FreeBSD_version < 500043)
#include <sys/bus_private.h>
#endif
#if (__FreeBSD_version < 500000)
#include <machine/clock.h>
#endif
#ifndef __KERNEL__
#define __KERNEL__

View File

@ -33,18 +33,10 @@
#include <sys/eventhandler.h>
#include <sys/devicestat.h>
#if (__FreeBSD_version < 500043)
#include <stddef.h>
#include <sys/buf.h>
#endif
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#if (__FreeBSD_version < 600000)
#include <machine/bus_memio.h>
#endif
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/bus.h>
@ -63,9 +55,6 @@
extern intrmask_t lock_driver(void);
extern void unlock_driver(intrmask_t spl);
typedef struct
{
UCHAR status; /* 0 nonbootable; 80h bootable */
@ -153,13 +142,14 @@ typedef struct _BUS_DMAMAP
{ struct _BUS_DMAMAP *next;
struct IALAdapter *pAdapter;
bus_dmamap_t dma_map;
struct callout_handle timeout_ch;
struct callout timeout;
SCAT_GATH psg[MAX_SG_DESCRIPTORS];
} BUS_DMAMAP, *PBUS_DMAMAP;
typedef struct IALAdapter
{
struct cam_path *path;
struct mtx lock;
bus_dma_tag_t io_dma_parent; /* I/O buffer DMA tag */
PBUS_DMAMAP pbus_dmamap_list;
@ -183,8 +173,8 @@ typedef struct IALAdapter
dma_addr_t responsesArrayBaseDmaAlignedAddr;
SATA_EVENT sataEvents[MV_SATA_CHANNELS_NUM];
struct callout_handle event_timer_connect;
struct callout_handle event_timer_disconnect;
struct callout event_timer_connect;
struct callout event_timer_disconnect;
struct _VBus VBus;
struct _VDevice VDevices[MV_SATA_CHANNELS_NUM];
@ -254,10 +244,6 @@ hpt_get_periph(int path_id,int target_id)
return periph;
}
#if (__FreeBSD_version < 500000)
#define YIELD_THREAD yield(curproc, 0)
#endif
#ifdef __i386__
#define BITS_PER_LONG 32
#define VDEV_TO_ID(pVDev) (DEVICEID)(pVDev)