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:
parent
fae00455b5
commit
49b3fc4062
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user