summaryrefslogtreecommitdiffstats
path: root/sys/dev/arcmsr/arcmsr.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2006-12-13 08:46:03 +0000
committerscottl <scottl@FreeBSD.org>2006-12-13 08:46:03 +0000
commitfa86a137f6cb6ffe0e265d2bc73bc96a123f1aec (patch)
treed74ea96841ca777407003c43eeec9e914c2be0d9 /sys/dev/arcmsr/arcmsr.c
parentf4831848ed1f837feb17e335f16a2dcfc71e137c (diff)
downloadFreeBSD-src-fa86a137f6cb6ffe0e265d2bc73bc96a123f1aec.zip
FreeBSD-src-fa86a137f6cb6ffe0e265d2bc73bc96a123f1aec.tar.gz
Update to version 1.20.00.13 of the arcmsr driver. This fixes many bugs
as well as adds support for newer controllers. Many thanks to Areca for their continued support. Submitted by: Erich Chen
Diffstat (limited to 'sys/dev/arcmsr/arcmsr.c')
-rw-r--r--sys/dev/arcmsr/arcmsr.c3490
1 files changed, 1574 insertions, 1916 deletions
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index 4da0343..7d8d807 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -4,47 +4,56 @@
** FILE NAME : arcmsr.c
** BY : Erich Chen
** Description: SCSI RAID Device Driver for
-** ARECA (ARC1110/1120/1160/1210/1220/1260) SATA RAID HOST Adapter
-** ARCMSR RAID Host adapter[RAID controller:INTEL 331(PCI-X) 341(PCI-EXPRESS) chip set]
+** ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX) SATA/SAS RAID HOST Adapter
+** ARCMSR RAID Host adapter
+** [RAID controller:INTEL 331(PCI-X) 341(PCI-EXPRESS) chip set]
******************************************************************************************
************************************************************************
**
-** Copyright (c) 2004-2006 ARECA Co. Ltd.
-** Erich Chen, Taipei Taiwan All rights reserved.
+** Copyright (c) 2004-2006 ARECA Co. Ltd.
+** Erich Chen, Taipei Taiwan All rights reserved.
**
-** Redistribution and use in source and binary forms,with or without
-** modification,are permitted provided that the following conditions
+** 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.
+** 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
+** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES,INCLUDING,BUT NOT LIMITED TO,THE IMPLIED WARRANTIES
+** 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 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
+** IN NO EVENT SHALL THE AUTHOR 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.
+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**************************************************************************
** History
**
** REV# DATE NAME DESCRIPTION
** 1.00.00.00 3/31/2004 Erich Chen First release
** 1.20.00.02 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error
+** 1.20.00.03 4/19/2005 Erich Chen add SATA 24 Ports adapter type support
+** clean unused function
+** 1.20.00.12 9/12/2005 Erich Chen bug fix with abort command handling,
+** firmware version check
+** and firmware update notify for hardware bug fix
+** handling if none zero high part physical address
+** of srb resource
+** 1.20.00.13 8/18/2006 Erich Chen remove pending srb and report busy
+** add iop message xfer
+** with scsi pass-through command
+** add new device id of sas raid adapters
+** code fit for SPARC64 & PPC
******************************************************************************************
-** $FreeBSD$
-*/
-#define ARCMSR_DEBUG0 0
-/*
-**********************************
+* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -80,104 +89,84 @@
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
-/*
+/*
**************************************************************************
-** Define the OS version specific locks
**************************************************************************
*/
#if __FreeBSD_version >= 500005
#include <sys/selinfo.h>
- #include <sys/mutex.h>
+ #include <sys/mutex.h>
+ #include <sys/endian.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
- #define ARCMSR_LOCK_INIT(l, s) mtx_init(l, s,NULL, MTX_DEF|MTX_RECURSE)
- #define ARCMSR_LOCK_ACQUIRE(l) mtx_lock(l)
- #define ARCMSR_LOCK_RELEASE(l) mtx_unlock(l)
- typedef struct mtx arcmsr_lock_t;
+ #define ARCMSR_LOCK_INIT(l, s) mtx_init(l, s, NULL, MTX_DEF|MTX_RECURSE)
+ #define ARCMSR_LOCK_ACQUIRE(l) mtx_lock(l)
+ #define ARCMSR_LOCK_RELEASE(l) mtx_unlock(l)
+ #define ARCMSR_LOCK_TRY(l) mtx_trylock(l)
+ #define arcmsr_htole32(x) htole32(x)
+ typedef struct mtx arcmsr_lock_t;
#else
#include <sys/select.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
- #define ARCMSR_LOCK_INIT(l, s) simple_lock_init(l)
- #define ARCMSR_LOCK_ACQUIRE(l) simple_lock(l)
- #define ARCMSR_LOCK_RELEASE(l) simple_unlock(l)
- typedef struct simplelock arcmsr_lock_t;
+ #define ARCMSR_LOCK_INIT(l, s) simple_lock_init(l)
+ #define ARCMSR_LOCK_ACQUIRE(l) simple_lock(l)
+ #define ARCMSR_LOCK_RELEASE(l) simple_unlock(l)
+ #define ARCMSR_LOCK_TRY(l) simple_lock_try(l)
+ #define arcmsr_htole32(x) (x)
+ typedef struct simplelock arcmsr_lock_t;
#endif
#include <dev/arcmsr/arcmsr.h>
+#define ARCMSR_SRBS_POOL_SIZE ((sizeof(struct CommandControlBlock) * ARCMSR_MAX_FREESRB_NUM)+0x20)
/*
**************************************************************************
-** __FreeBSD_version 502010
**************************************************************************
*/
-static VOID arcmsr_interrupt(VOID *arg);
-static LONG arcmsr_probe(device_t dev);
-static LONG arcmsr_attach(device_t dev);
-static LONG arcmsr_detach(device_t dev);
-static VOID arcmsr_shutdown(device_t dev);
-#if 0
-ULONG arcmsr_make_timespec(ULONG year,ULONG mon,ULONG day,ULONG hour,ULONG min,ULONG sec);
-ULONG arcmsr_getcmos_time(VOID);
-#endif
-LONG arcmsr_queue_dpc(PACB pACB,DPCFUN dpcfun,VOID *arg);
-LONG arcmsr_iop_ioctlcmd(PACB pACB,ULONG ioctl_cmd,caddr_t arg);
-BOOLEAN arcmsr_seek_cmd2abort(union ccb * pabortccb);
-BOOLEAN arcmsr_wait_msgint_ready(PACB pACB);
-PSRB arcmsr_get_freesrb(PACB pACB);
-VOID arcmsr_free_resource(PACB pACB);
-VOID arcmsr_bus_reset(PACB pACB);
-VOID arcmsr_stop_adapter_bgrb(PACB pACB);
-VOID arcmsr_start_adapter_bgrb(PACB pACB);
-VOID arcmsr_iop_init(PACB pACB);
-VOID arcmsr_do_dpcQ(PACB pACB);
-VOID arcmsr_flush_adapter_cache(PACB pACB);
-VOID arcmsr_do_thread_works(VOID *arg);
-VOID arcmsr_queue_wait2go_srb(PACB pACB,PSRB pSRB);
-VOID arcmsr_post_wait2go_srb(PACB pACB);
-VOID arcmsr_post_Qbuffer(PACB pACB);
-VOID arcmsr_abort_allcmd(PACB pACB);
-VOID arcmsr_srb_complete(PSRB pSRB);
-VOID arcmsr_iop_reset(PACB pACB);
-VOID arcmsr_report_SenseInfoBuffer(PSRB pSRB);
-VOID arcmsr_build_srb(PSRB pSRB, bus_dma_segment_t *dm_segs, LONG nseg);
+#define CHIP_REG_READ32(r) bus_space_read_4(acb->btag, acb->bhandle, offsetof(struct MessageUnit,r))
+#define CHIP_REG_WRITE32(r,d) bus_space_write_4(acb->btag, acb->bhandle, offsetof(struct MessageUnit,r), d)
/*
-*****************************************************************************************
-** Character device switch table
-**struct cdevsw {
-** d_open_t *d_open;
-** d_close_t *d_close;
-** d_read_t *d_read;
-** d_write_t *d_write;
-** d_ioctl_t *d_ioctl;
-** d_poll_t *d_poll;
-** d_mmap_t *d_mmap;
-** d_strategy_t *d_strategy;
-** const char *d_name; "" base device name, e.g. 'vn'
-** int d_maj;
-** d_dump_t *d_dump;
-** d_psize_t *d_psize;
-** u_int d_flags;
-** int d_bmaj;
-** d_kqfilter_t *d_kqfilter; "" additions below are not binary compatible with 4.2 and below
-**};
-******************************************************************************************
+**************************************************************************
+**************************************************************************
*/
+static struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb);
+static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb);
+static u_int8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb);
+static u_int32_t arcmsr_probe(device_t dev);
+static u_int32_t arcmsr_attach(device_t dev);
+static u_int32_t arcmsr_detach(device_t dev);
+static u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg);
+static void arcmsr_iop_parking(struct AdapterControlBlock *acb);
+static void arcmsr_shutdown(device_t dev);
+static void arcmsr_interrupt(void *arg);
+static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb);
+static void arcmsr_free_resource(struct AdapterControlBlock *acb);
+static void arcmsr_bus_reset(struct AdapterControlBlock *acb);
+static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
+static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
+static void arcmsr_iop_init(struct AdapterControlBlock *acb);
+static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
+static void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb);
+static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb);
+static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag);
+static void arcmsr_iop_reset(struct AdapterControlBlock *acb);
+static void arcmsr_report_sense_info(struct CommandControlBlock *srb);
+static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t * dm_segs, u_int32_t nseg);
+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb);
+static int arcmsr_resume(device_t dev);
+static int arcmsr_suspend(device_t dev);
/*
**************************************************************************
-** Insert a delay in micro-seconds and milli-seconds.
-** static void MDELAY(LONG ms) { while (ms--) UDELAY(1000); }
**************************************************************************
*/
-static VOID UDELAY(LONG us) { DELAY(us); }
+static void UDELAY(u_int32_t us) { DELAY(us); }
/*
**************************************************************************
-**
**************************************************************************
*/
static bus_dmamap_callback_t arcmsr_map_freesrb;
static bus_dmamap_callback_t arcmsr_executesrb;
/*
**************************************************************************
-**
**************************************************************************
*/
static d_open_t arcmsr_open;
@@ -188,75 +177,80 @@ static device_method_t arcmsr_methods[]={
DEVMETHOD(device_probe, arcmsr_probe),
DEVMETHOD(device_attach, arcmsr_attach),
DEVMETHOD(device_detach, arcmsr_detach),
- DEVMETHOD(device_shutdown, arcmsr_shutdown),
- { 0,0 }
+ DEVMETHOD(device_shutdown, arcmsr_shutdown),
+ DEVMETHOD(device_suspend, arcmsr_suspend),
+ DEVMETHOD(device_resume, arcmsr_resume),
+
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ { 0, 0 }
};
static driver_t arcmsr_driver={
- "arcmsr",arcmsr_methods,sizeof(struct _ACB)
+ "arcmsr", arcmsr_methods, sizeof(struct AdapterControlBlock)
};
static devclass_t arcmsr_devclass;
-DRIVER_MODULE(arcmsr,pci,arcmsr_driver,arcmsr_devclass,0,0);
-MODULE_DEPEND(arcmsr, pci, 1, 1, 1);
-MODULE_DEPEND(arcmsr, cam, 1, 1, 1);
-
-#if __FreeBSD_version >= 502010
+DRIVER_MODULE(arcmsr, pci, arcmsr_driver, arcmsr_devclass, 0, 0);
+#ifndef BUS_DMA_COHERENT
+ #define BUS_DMA_COHERENT 0x04 /* hint: map memory in a coherent way */
+#endif
+#if __FreeBSD_version >= 501000
+ #ifndef D_NEEDGIANT
+ #define D_NEEDGIANT 0x00400000 /* driver want Giant */
+ #endif
+ #ifndef D_VERSION
+ #define D_VERSION 0x20011966
+ #endif
static struct cdevsw arcmsr_cdevsw={
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = arcmsr_open, /* open */
- .d_close = arcmsr_close, /* close */
- .d_ioctl = arcmsr_ioctl, /* ioctl */
- .d_name = "arcmsr", /* name */
+ #if __FreeBSD_version > 502010
+ .d_version = D_VERSION,
+ #endif
+ .d_flags = D_NEEDGIANT,
+ .d_open = arcmsr_open, /* open */
+ .d_close = arcmsr_close, /* close */
+ .d_ioctl = arcmsr_ioctl, /* ioctl */
+ .d_name = "arcmsr", /* name */
};
#else
#define ARCMSR_CDEV_MAJOR 180
static struct cdevsw arcmsr_cdevsw = {
- arcmsr_open, /* open */
- arcmsr_close, /* close */
- noread, /* read */
- nowrite, /* write */
- arcmsr_ioctl, /* ioctl */
- nopoll, /* poll */
- nommap, /* mmap */
- nostrategy, /* strategy */
- "arcmsr", /* name */
- ARCMSR_CDEV_MAJOR, /* major */
- nodump, /* dump */
- nopsize, /* psize */
- 0 /* flags */
+ arcmsr_open, /* open */
+ arcmsr_close, /* close */
+ noread, /* read */
+ nowrite, /* write */
+ arcmsr_ioctl, /* ioctl */
+ nopoll, /* poll */
+ nommap, /* mmap */
+ nostrategy, /* strategy */
+ "arcmsr", /* name */
+ ARCMSR_CDEV_MAJOR, /* major */
+ nodump, /* dump */
+ nopsize, /* psize */
+ 0 /* flags */
};
#endif
#if __FreeBSD_version < 500005
- static int arcmsr_open(dev_t dev, int flags, int fmt, struct proc *proc)
+ static int arcmsr_open(dev_t dev, int flags, int fmt, struct proc *proc)
#else
#if __FreeBSD_version < 503000
- static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc)
+ static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc)
#else
- static int arcmsr_open(struct cdev *dev, int flags, int fmt, d_thread_t *proc)
+ static int arcmsr_open(struct cdev *dev, int flags, int fmt, d_thread_t *proc)
#endif
#endif
{
#if __FreeBSD_version < 503000
- PACB pACB=dev->si_drv1;
- #else
+ struct AdapterControlBlock *acb=dev->si_drv1;
+ #else
int unit = minor(dev);
- PACB pACB = devclass_get_softc(arcmsr_devclass, unit);
- #endif
-
- if(pACB==NULL)
- {
+ struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
+ #endif
+ if(acb==NULL) {
return ENXIO;
}
- /* Check to make sure the device isn't already open */
- if (pACB->acb_flags & ACB_F_IOCTL_OPEN)
- {
- return EBUSY;
- }
- pACB->acb_flags |= ACB_F_IOCTL_OPEN;
return 0;
}
/*
@@ -264,400 +258,189 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1);
**************************************************************************
*/
#if __FreeBSD_version < 500005
- static int arcmsr_close(dev_t dev, int flags, int fmt, struct proc *proc)
+ static int arcmsr_close(dev_t dev, int flags, int fmt, struct proc *proc)
#else
#if __FreeBSD_version < 503000
- static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc)
+ static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc)
#else
- static int arcmsr_close(struct cdev *dev, int flags, int fmt, d_thread_t *proc)
+ static int arcmsr_close(struct cdev *dev, int flags, int fmt, d_thread_t *proc)
#endif
#endif
{
#if __FreeBSD_version < 503000
- PACB pACB=dev->si_drv1;
- #else
+ struct AdapterControlBlock *acb=dev->si_drv1;
+ #else
int unit = minor(dev);
- PACB pACB = devclass_get_softc(arcmsr_devclass, unit);
- #endif
-
- if(pACB==NULL)
- {
+ struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
+ #endif
+ if(acb==NULL) {
return ENXIO;
}
- pACB->acb_flags &= ~ACB_F_IOCTL_OPEN;
return 0;
}
/*
**************************************************************************
-**ENOENT
-**ENOIOCTL
-**ENOMEM
-**EINVAL
**************************************************************************
*/
#if __FreeBSD_version < 500005
- static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct proc *proc)
+ static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct proc *proc)
#else
#if __FreeBSD_version < 503000
- static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
+ static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc)
#else
- static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg,int flags, d_thread_t *proc)
+ static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, d_thread_t *proc)
#endif
#endif
{
#if __FreeBSD_version < 503000
- PACB pACB=dev->si_drv1;
- #else
+ struct AdapterControlBlock *acb=dev->si_drv1;
+ #else
int unit = minor(dev);
- PACB pACB = devclass_get_softc(arcmsr_devclass, unit);
- #endif
-
- if(pACB==NULL)
- {
- return ENXIO;
- }
- return(arcmsr_iop_ioctlcmd(pACB,ioctl_cmd,arg));
-}
-/*
-**************************************************************************
-**************************************************************************
-*/
-LONG arcmsr_queue_dpc(PACB pACB,DPCFUN dpcfun,VOID *arg)
-{
- ULONG s;
- UCHAR index_pointer;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_queue_dpc................. \n");
- #endif
-
- s=splcam();
- index_pointer=(pACB->dpcQ_tail + 1) % ARCMSR_MAX_DPC;
- if(index_pointer==pACB->dpcQ_head)
- {
- splx(s);
- printf("DPC Queue full!\n");
- return -1;
- }
- pACB->dpcQ[pACB->dpcQ_tail].dpcfun=dpcfun;
- pACB->dpcQ[pACB->dpcQ_tail].arg=arg;
- pACB->dpcQ_tail=index_pointer;
- /*
- *********************************************************
- *********************************************************
- */
- wakeup(pACB->kthread_proc);
-
- splx(s);
- return 0;
-}
-/*
-**************************************************************************
-** arcmsr_do_dpcQ
-** execute dpc routine by kernel thread
-***************************************************************************
-*/
-VOID arcmsr_do_dpcQ(PACB pACB)
-{
- #if ARCMSR_DEBUG0
- printf("arcmsr_do_dpcQ................. \n");
+ struct AdapterControlBlock *acb = devclass_get_softc(arcmsr_devclass, unit);
#endif
- /*
- ******************************************
- ******************************************
- */
- while (pACB->dpcQ_head!=pACB->dpcQ_tail)
- {
- ULONG s;
- DPC dpc;
- /* got a "dpc routine" */
- s=splcam();
- dpc=pACB->dpcQ[pACB->dpcQ_head];
- pACB->dpcQ_head++;
- pACB->dpcQ_head %=ARCMSR_MAX_DPC;
- splx(s);
- /* execute this "dpc routine" */
- dpc.dpcfun(dpc.arg);
+ if(acb==NULL) {
+ return ENXIO;
}
- return;
+ return(arcmsr_iop_ioctlcmd(acb, ioctl_cmd, arg));
}
-#if 0
/*
-**********************************************************************
-** <second> bit 05,04,03,02,01,00: 0 - 59
-** <minute> bit 11,10,09,08,07,06: 0 - 59
-** <month> bit 15,14,13,12: 1 - 12
-** <hour> bit 21,20,19,18,17,16: 0 - 59
-** <day> bit 26,25,24,23,22: 1 - 31
-** <year> bit 31,30,29,28,27: 0=2000,31=2031
-**********************************************************************
+*******************************************************************************
+*******************************************************************************
*/
-ULONG arcmsr_make_timespec(ULONG year,ULONG mon,ULONG day,ULONG hour,ULONG min,ULONG sec)
+static int arcmsr_suspend(device_t dev)
{
- return((year<<27)|(day<<22)|(hour<<16)|(mon<<12)|(min<<6)|(sec));
+ struct AdapterControlBlock *acb = device_get_softc(dev);
+ u_int32_t intmask_org;
+
+ /* disable all outbound interrupt */
+ intmask_org=CHIP_REG_READ32(outbound_intmask);
+ CHIP_REG_WRITE32(outbound_intmask, (intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE));
+ /* flush controller */
+ arcmsr_iop_parking(acb);
+ return(0);
}
/*
-********************************************************************
-********************************************************************
+*******************************************************************************
+*******************************************************************************
*/
-ULONG arcmsr_getcmos_time(VOID)
+static int arcmsr_resume(device_t dev)
{
- ULONG year,mon,day,hour,min,sec;
+ struct AdapterControlBlock *acb = device_get_softc(dev);
- #if ARCMSR_DEBUG0
- printf("arcmsr_getcmos_time \n");
- #endif
- sec=bcd2bin(rtcin(RTC_SEC));
- min=bcd2bin(rtcin(RTC_MIN));
- hour=bcd2bin(rtcin(RTC_HRS));
- day=bcd2bin(rtcin(RTC_DAY));
- mon=bcd2bin(rtcin(RTC_MONTH));
- year=bcd2bin(rtcin(RTC_YEAR));
- if((year +=1900) < 1970)
- year +=100;
- return arcmsr_make_timespec(year,mon,day,hour,min,sec);
+ arcmsr_iop_init(acb);
+ return(0);
}
-#endif
/*
*********************************************************************************
-** Asynchronous notification handler.
*********************************************************************************
*/
-static VOID arcmsr_async(VOID *cb_arg, ULONG code, struct cam_path *path, VOID *arg)
+static void arcmsr_async(void *cb_arg, u_int32_t code, struct cam_path *path, void *arg)
{
- PACB pACB;
- UCHAR target_id,target_lun;
- struct cam_sim *sim;
- ULONG s;
- #if ARCMSR_DEBUG0
- printf("arcmsr_async.......................................... \n");
- #endif
- s=splcam();
+ struct AdapterControlBlock *acb;
+ u_int8_t target_id, target_lun;
+ struct cam_sim * sim;
sim=(struct cam_sim *) cb_arg;
- pACB =(PACB) cam_sim_softc(sim);
- switch (code)
- {
+ acb =(struct AdapterControlBlock *) cam_sim_softc(sim);
+ switch (code) {
case AC_LOST_DEVICE:
target_id=xpt_path_target_id(path);
- target_lun=xpt_path_lun_id(path);
- if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN))
- {
+ target_lun=xpt_path_lun_id(path);
+ if((target_id > ARCMSR_MAX_TARGETID) || (target_lun > ARCMSR_MAX_TARGETLUN)) {
break;
}
- printf("%s:scsi id%d lun%d device lost \n",device_get_name(pACB->pci_dev),target_id,target_lun);
+ printf("%s:scsi id%d lun%d device lost \n"
+ , device_get_name(acb->pci_dev), target_id, target_lun);
break;
default:
break;
}
- splx(s);
-}
-/*
-**************************************************************************
-* arcmsr_do_thread_works
-* execute programs schedule by kernel thread
-* execute programs schedule by kernel thread
-* :do background rebuilding
-*
-* tsleep(void *ident,int priority,const char *wmesg,int timo)
-* tsleep()
-* General sleep call. Suspends the current process until a wakeup is
-* performed on the specified identifier. The process will then be made
-* runnable with the specified priority. Sleeps at most timo/hz seconds
-* (0 means no timeout). If pri includes PCATCH flag, signals are checked
-* before and after sleeping, else signals are not checked. Returns 0 if
-* awakened, EWOULDBLOCK if the timeout expires. If PCATCH is set and a
-* signal needs to be delivered, ERESTART is returned if the current system
-* call should be restarted if possible, and EINTR is returned if the system
-* call should be interrupted by the signal (return EINTR).
-*
-* await(int priority, int timo)
-* await() - wait for async condition to occur. The process blocks until
-* wakeup() is called on the most recent asleep() address. If wakeup is called
-* priority to await(), await() winds up being a NOP.
-*
-* If await() is called more then once (without an intervening asleep() call),
-* await() is still effectively a NOP but it calls mi_switch() to give other
-* processes some cpu before returning. The process is left runnable.
-*
-* <<<<<<<< EXPERIMENTAL, UNTESTED >>>>>>>>>>
-* asleep(void *ident, int priority, const char *wmesg, int timo)
-* asleep() - async sleep call. Place process on wait queue and return
-* immediately without blocking. The process stays runnable until await()
-* is called. If ident is NULL, remove process from wait queue if it is still
-* on one.
-*
-* Only the most recent sleep condition is effective when making successive
-* calls to asleep() or when calling tsleep().
-*
-* The timeout, if any, is not initiated until await() is called. The sleep
-* priority, signal, and timeout is specified in the asleep() call but may be
-* overriden in the await() call.
-*
-* <<<<<<<< EXPERIMENTAL, UNTESTED >>>>>>>>>>
-* :do background rebuilding
-***************************************************************************
-*/
-VOID arcmsr_do_thread_works(VOID *arg)
-{
- PACB pACB=(PACB) arg;
- ARCMSR_LOCK_INIT(&pACB->arcmsr_kthread_lock, "arcmsr kthread lock");
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_do_thread_works................. \n");
- #endif
-
- ARCMSR_LOCK_ACQUIRE(&pACB->arcmsr_kthread_lock);
- while(1)
- {
- tsleep((caddr_t)pACB->kthread_proc, PRIBIO | PWAIT, "arcmsr", hz/4);/*.25 sec*/
- /*
- ** if do_dpcQ_semaphore is signal
- ** do following works
- */
- arcmsr_do_dpcQ(pACB); /*see if there were some dpc routine need to execute*/
- if(pACB->acb_flags & ACB_F_STOP_THREAD)
- {
- ARCMSR_LOCK_RELEASE(&pACB->arcmsr_kthread_lock);
- break;
- }
- }
- kthread_exit(0);
- return;
}
/*
************************************************************************
-**
-**
************************************************************************
*/
-VOID arcmsr_flush_adapter_cache(PACB pACB)
+static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
{
- #if ARCMSR_DEBUG0
- printf("arcmsr_flush_adapter_cache..............\n");
- #endif
- CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0,ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'flush adapter cache' timeout \n"
+ , acb->pci_unit);
+ }
return;
}
/*
**********************************************************************
-**
-**
-**
**********************************************************************
*/
-BOOLEAN arcmsr_wait_msgint_ready(PACB pACB)
+static u_int8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb)
{
- ULONG Index;
- UCHAR Retries=0x00;
- do
- {
- for(Index=0; Index < 500000; Index++)
- {
- if(CHIP_REG_READ32(&pACB->pmu->outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT)
- {
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);/*clear interrupt*/
- return TRUE;
+ u_int32_t Index;
+ u_int8_t Retries=0x00;
+
+ do {
+ for(Index=0; Index < 100; Index++) {
+ if(CHIP_REG_READ32(outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
+ /*clear interrupt*/
+ CHIP_REG_WRITE32(outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT);
+ return 0x00;
}
/* one us delay */
- UDELAY(10);
- }/*max 5 seconds*/
- }while(Retries++ < 24);/*max 2 minutes*/
- return FALSE;
+ UDELAY(10000);
+ }/*max 1 seconds*/
+ }while(Retries++ < 20);/*max 20 sec*/
+ return 0xff;
}
/*
**********************************************************************
-**
-** Q back this SRB into ACB ArraySRB
-**
**********************************************************************
*/
-VOID arcmsr_srb_complete(PSRB pSRB)
+static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag)
{
- ULONG s;
- PACB pACB=pSRB->pACB;
- union ccb *pccb=pSRB->pccb;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_srb_complete: pSRB=%p srb_doneindex=%x srb_startindex=%x\n",pSRB,pACB->srb_doneindex,pACB->srb_startindex);
- #endif
+ struct AdapterControlBlock *acb=srb->acb;
+ union ccb * pccb=srb->pccb;
- if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
- {
+ if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
bus_dmasync_op_t op;
- if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
- {
+ if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
op = BUS_DMASYNC_POSTREAD;
- }
- else
- {
+ } else {
op = BUS_DMASYNC_POSTWRITE;
}
- bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
- bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
- }
- s=splcam();
- atomic_subtract_int(&pACB->srboutstandingcount,1);
- pSRB->startdone=ARCMSR_SRB_DONE;
- pSRB->srb_flags=0;
- pACB->psrbringQ[pACB->srb_doneindex]=pSRB;
- pACB->srb_doneindex++;
- pACB->srb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
- splx(s);
- xpt_done(pccb);
+ bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
+ bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
+ }
+ ARCMSR_LOCK_ACQUIRE(&acb->workingQ_done_lock);
+ if(stand_flag==1) {
+ atomic_subtract_int(&acb->srboutstandingcount, 1);
+ }
+ srb->startdone=ARCMSR_SRB_DONE;
+ srb->srb_flags=0;
+ acb->srbworkingQ[acb->workingsrb_doneindex]=srb;
+ acb->workingsrb_doneindex++;
+ acb->workingsrb_doneindex %= ARCMSR_MAX_FREESRB_NUM;
+ ARCMSR_LOCK_RELEASE(&acb->workingQ_done_lock);
+ xpt_done(pccb);
return;
}
/*
**********************************************************************
-** if scsi error do auto request sense
**********************************************************************
*/
-VOID arcmsr_report_SenseInfoBuffer(PSRB pSRB)
-{
- union ccb *pccb=pSRB->pccb;
- PSENSE_DATA psenseBuffer=(PSENSE_DATA)&pccb->csio.sense_data;
- #if ARCMSR_DEBUG0
- printf("arcmsr_report_SenseInfoBuffer...........\n");
- #endif
-
- pccb->ccb_h.status|=CAM_REQ_CMP;
- if(psenseBuffer)
- {
- memset(psenseBuffer, 0, sizeof(pccb->csio.sense_data));
- memcpy(psenseBuffer,pSRB->arcmsr_cdb.SenseData,get_min(sizeof(struct _SENSE_DATA),sizeof(pccb->csio.sense_data)));
- psenseBuffer->ErrorCode=0x70;
- psenseBuffer->Valid=1;
- pccb->ccb_h.status|=CAM_AUTOSNS_VALID;
- }
- return;
-}
-/*
-*********************************************************************
-** to insert pSRB into tail of pACB wait exec srbQ
-*********************************************************************
-*/
-VOID arcmsr_queue_wait2go_srb(PACB pACB,PSRB pSRB)
+static void arcmsr_report_sense_info(struct CommandControlBlock *srb)
{
- ULONG s;
- LONG i=0;
- #if ARCMSR_DEBUG0
- printf("arcmsr_qtail_wait2go_srb:......................................... \n");
- #endif
-
- s=splcam();
- while(1)
- {
- if(pACB->psrbwait2go[i]==NULL)
- {
- pACB->psrbwait2go[i]=pSRB;
- atomic_add_int(&pACB->srbwait2gocount,1);
- splx(s);
- return;
- }
- i++;
- i%=ARCMSR_MAX_OUTSTANDING_CMD;
+ union ccb * pccb=srb->pccb;
+
+ pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
+ pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
+ if(&pccb->csio.sense_data) {
+ memset(&pccb->csio.sense_data, 0, sizeof(pccb->csio.sense_data));
+ memcpy(&pccb->csio.sense_data, srb->arcmsr_cdb.SenseData,
+ get_min(sizeof(struct SENSE_DATA), sizeof(pccb->csio.sense_data)));
+ ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70); /* Valid,ErrorCode */
+ pccb->ccb_h.status |= CAM_AUTOSNS_VALID;
}
return;
}
@@ -666,164 +449,126 @@ VOID arcmsr_queue_wait2go_srb(PACB pACB,PSRB pSRB)
**
*********************************************************************
*/
-VOID arcmsr_abort_allcmd(PACB pACB)
+static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
{
- CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0,ARCMSR_INBOUND_MESG0_ABORT_CMD);
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'abort all outstanding command' timeout \n"
+ , acb->pci_unit);
+ }
return;
}
-
/*
****************************************************************************
-** Routine Description: Reset 80331 iop.
-** Arguments:
-** Return Value: Nothing.
****************************************************************************
*/
-VOID arcmsr_iop_reset(PACB pACB)
+static void arcmsr_iop_reset(struct AdapterControlBlock *acb)
{
- PSRB pSRB,pfreesrb;
- ULONG intmask_org,mask;
- LONG i=0;
+ struct CommandControlBlock *srb;
+ u_int32_t intmask_org, mask;
+ u_int32_t i=0;
- #if ARCMSR_DEBUG0
- printf("arcmsr_iop_reset: reset iop controller......................................\n");
- #endif
- if(pACB->srboutstandingcount!=0)
+ if(acb->srboutstandingcount!=0)
{
- /* Q back all outstanding srb into wait exec psrb Q*/
- #if ARCMSR_DEBUG0
- printf("arcmsr_iop_reset: srboutstandingcount=%d ...\n",pACB->srboutstandingcount);
- #endif
- /* disable all outbound interrupt */
- intmask_org=CHIP_REG_READ32(&pACB->pmu->outbound_intmask);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
- /* talk to iop 331 outstanding command aborted*/
- arcmsr_abort_allcmd(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_iop_reset: wait 'abort all outstanding command' timeout.................in \n");
- }
+ /* talk to iop 331 outstanding command aborted*/
+ arcmsr_abort_allcmd(acb);
+ UDELAY(3000*1000);/*wait for 3 sec for all command aborted*/
+ /* disable all outbound interrupt */
+ intmask_org=CHIP_REG_READ32(outbound_intmask);
+ CHIP_REG_WRITE32(outbound_intmask
+ , intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
/*clear all outbound posted Q*/
- for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++)
- {
- CHIP_REG_READ32(&pACB->pmu->outbound_queueport);
+ for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++) {
+ CHIP_REG_READ32(outbound_queueport);
}
- pfreesrb=pACB->pfreesrb;
- for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++)
- {
- pSRB=&pfreesrb[i];
- if(pSRB->startdone==ARCMSR_SRB_START)
- {
- pSRB->startdone=ARCMSR_SRB_ABORTED;
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
+ for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
+ srb=acb->psrb_pool[i];
+ if(srb->startdone==ARCMSR_SRB_START) {
+ srb->startdone=ARCMSR_SRB_ABORTED;
+ srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+ arcmsr_srb_complete(srb, 1);
}
}
/* enable all outbound interrupt */
- mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org & mask);
- atomic_set_int(&pACB->srboutstandingcount,0);
+ mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE
+ |ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE);
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org & mask);
/* post abort all outstanding command message to RAID controller */
}
- i=0;
- while(pACB->srbwait2gocount > 0)
- {
- pSRB=pACB->psrbwait2go[i];
- if(pSRB!=NULL)
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_iop_reset:abort command... srbwait2gocount=%d ...\n",pACB->srbwait2gocount);
- #endif
- pACB->psrbwait2go[i]=NULL;
- pSRB->startdone=ARCMSR_SRB_ABORTED;
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
- atomic_subtract_int(&pACB->srbwait2gocount,1);
- }
- i++;
- i%=ARCMSR_MAX_OUTSTANDING_CMD;
- }
+ atomic_set_int(&acb->srboutstandingcount, 0);
+ acb->workingsrb_doneindex=0;
+ acb->workingsrb_startindex=0;
return;
}
/*
**********************************************************************
-**
-** PAGE_SIZE=4096 or 8192,PAGE_SHIFT=12
**********************************************************************
*/
-VOID arcmsr_build_srb(PSRB pSRB, bus_dma_segment_t *dm_segs, LONG nseg)
+static void arcmsr_build_srb(struct CommandControlBlock *srb, bus_dma_segment_t *dm_segs, u_int32_t nseg)
{
- PARCMSR_CDB pARCMSR_CDB=&pSRB->arcmsr_cdb;
- PCHAR psge=(PCHAR)&pARCMSR_CDB->u;
- ULONG address_lo,address_hi;
- union ccb *pccb=pSRB->pccb;
- struct ccb_scsiio *pcsio=&pccb->csio;
- LONG arccdbsize=0x30;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_build_srb........................... \n");
- #endif
- memset(pARCMSR_CDB,0,sizeof(struct _ARCMSR_CDB));
- pARCMSR_CDB->Bus=0;
- pARCMSR_CDB->TargetID=pccb->ccb_h.target_id;
- pARCMSR_CDB->LUN=pccb->ccb_h.target_lun;
- pARCMSR_CDB->Function=1;
- pARCMSR_CDB->CdbLength=(UCHAR)pcsio->cdb_len;
- pARCMSR_CDB->Context=(CPT2INT)pARCMSR_CDB;
- bcopy(pcsio->cdb_io.cdb_bytes, pARCMSR_CDB->Cdb, pcsio->cdb_len);
- if(nseg != 0)
- {
- PACB pACB=pSRB->pACB;
- bus_dmasync_op_t op;
- LONG length,i,cdb_sgcount=0;
-
- /* map stor port SG list to our iop SG List.*/
- for(i=0;i<nseg;i++)
- {
+ struct ARCMSR_CDB * arcmsr_cdb= &srb->arcmsr_cdb;
+ u_int8_t * psge=(u_int8_t *)&arcmsr_cdb->u;
+ u_int32_t address_lo, address_hi;
+ union ccb * pccb=srb->pccb;
+ struct ccb_scsiio * pcsio= &pccb->csio;
+ u_int32_t arccdbsize=0x30;
+
+ memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB));
+ arcmsr_cdb->Bus=0;
+ arcmsr_cdb->TargetID=pccb->ccb_h.target_id;
+ arcmsr_cdb->LUN=pccb->ccb_h.target_lun;
+ arcmsr_cdb->Function=1;
+ arcmsr_cdb->CdbLength=(u_int8_t)pcsio->cdb_len;
+ arcmsr_cdb->Context=(unsigned long)arcmsr_cdb;
+ bcopy(pcsio->cdb_io.cdb_bytes, arcmsr_cdb->Cdb, pcsio->cdb_len);
+ if(nseg != 0) {
+ struct AdapterControlBlock *acb=srb->acb;
+ bus_dmasync_op_t op;
+ u_int32_t length, i, cdb_sgcount=0;
+
+ if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
+ op=BUS_DMASYNC_PREREAD;
+ } else {
+ op=BUS_DMASYNC_PREWRITE;
+ arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_WRITE;
+ srb->srb_flags|=SRB_FLAG_WRITE;
+ }
+ bus_dmamap_sync(acb->dm_segs_dmat, srb->dm_segs_dmamap, op);
+ for(i=0;i<nseg;i++) {
/* Get the physical address of the current data pointer */
- length=(ULONG) dm_segs[i].ds_len;
- address_lo=dma_addr_lo32(dm_segs[i].ds_addr);
- address_hi=dma_addr_hi32(dm_segs[i].ds_addr);
- if(address_hi==0)
- {
- PSG32ENTRY pdma_sg=(PSG32ENTRY)psge;
+ length=arcmsr_htole32(dm_segs[i].ds_len);
+ address_lo=arcmsr_htole32(dma_addr_lo32(dm_segs[i].ds_addr));
+ address_hi=arcmsr_htole32(dma_addr_hi32(dm_segs[i].ds_addr));
+ if(address_hi==0) {
+ struct SG32ENTRY * pdma_sg=(struct SG32ENTRY *)psge;
pdma_sg->address=address_lo;
pdma_sg->length=length;
- psge += sizeof(SG32ENTRY);
- arccdbsize += sizeof(SG32ENTRY);
- }
- else
- {
- LONG sg64s_size=0,tmplength=length;
+ psge += sizeof(struct SG32ENTRY);
+ arccdbsize += sizeof(struct SG32ENTRY);
+ } else {
+ u_int32_t sg64s_size=0, tmplength=length;
- #if ARCMSR_DEBUG0
- printf("arcmsr_build_srb: !!!!!!!!!!!......address_hi=%x.... \n",address_hi);
- #endif
- while(1)
- {
- LONG64 span4G,length0;
- PSG64ENTRY pdma_sg=(PSG64ENTRY)psge;
+ while(1) {
+ u_int64_t span4G, length0;
+ struct SG64ENTRY * pdma_sg=(struct SG64ENTRY *)psge;
- span4G=(LONG64)address_lo + tmplength;
+ span4G=(u_int64_t)address_lo + tmplength;
pdma_sg->addresshigh=address_hi;
pdma_sg->address=address_lo;
- if(span4G > 0x100000000)
- {
+ if(span4G > 0x100000000) {
/*see if cross 4G boundary*/
length0=0x100000000-address_lo;
- pdma_sg->length=(ULONG)length0|IS_SG64_ADDR;
+ pdma_sg->length=(u_int32_t)length0|IS_SG64_ADDR;
address_hi=address_hi+1;
address_lo=0;
- tmplength=tmplength-(LONG)length0;
- sg64s_size += sizeof(SG64ENTRY);
- psge += sizeof(SG64ENTRY);
+ tmplength=tmplength-(u_int32_t)length0;
+ sg64s_size += sizeof(struct SG64ENTRY);
+ psge += sizeof(struct SG64ENTRY);
cdb_sgcount++;
- }
- else
- {
- pdma_sg->length=tmplength|IS_SG64_ADDR;
- sg64s_size += sizeof(SG64ENTRY);
- psge += sizeof(SG64ENTRY);
+ } else {
+ pdma_sg->length=tmplength|IS_SG64_ADDR;
+ sg64s_size += sizeof(struct SG64ENTRY);
+ psge += sizeof(struct SG64ENTRY);
break;
}
}
@@ -831,1157 +576,1020 @@ VOID arcmsr_build_srb(PSRB pSRB, bus_dma_segment_t *dm_segs, LONG nseg)
}
cdb_sgcount++;
}
- pARCMSR_CDB->sgcount=(UCHAR)cdb_sgcount;
- pARCMSR_CDB->DataLength=pcsio->dxfer_len;
- if( arccdbsize > 256)
- {
- pARCMSR_CDB->Flags|=ARCMSR_CDB_FLAG_SGL_BSIZE;
+ arcmsr_cdb->sgcount=(u_int8_t)cdb_sgcount;
+ arcmsr_cdb->DataLength=pcsio->dxfer_len;
+ if( arccdbsize > 256) {
+ arcmsr_cdb->Flags|=ARCMSR_CDB_FLAG_SGL_BSIZE;
}
- if((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
- {
- op=BUS_DMASYNC_PREREAD;
- }
- else
- {
- op=BUS_DMASYNC_PREWRITE;
- pARCMSR_CDB->Flags|=ARCMSR_CDB_FLAG_WRITE;
- pSRB->srb_flags|=SRB_FLAG_WRITE;
- }
- bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
}
- #if ARCMSR_DEBUG0
- printf("arcmsr_build_srb: pSRB=%p cmd=%x xferlength=%d arccdbsize=%d sgcount=%d\n",pSRB,pcsio->cdb_io.cdb_bytes[0],pARCMSR_CDB->DataLength,arccdbsize,pARCMSR_CDB->sgcount);
- #endif
return;
}
/*
**************************************************************************
-**
-** arcmsr_post_srb - Send a protocol specific ARC send postcard to a AIOC .
-** handle: Handle of registered ARC protocol driver
-** adapter_id: AIOC unique identifier(integer)
-** pPOSTCARD_SEND: Pointer to ARC send postcard
-**
-** This routine posts a ARC send postcard to the request post FIFO of a
-** specific ARC adapter.
-**
**************************************************************************
*/
-static VOID arcmsr_post_srb(PACB pACB,PSRB pSRB)
+static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb)
{
- ULONG cdb_shifted_phyaddr=(ULONG) pSRB->cdb_shifted_phyaddr;
- PARCMSR_CDB pARCMSR_CDB=(PARCMSR_CDB)&pSRB->arcmsr_cdb;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_post_srb: pSRB=%p cdb_shifted_phyaddr=%x\n",pSRB,cdb_shifted_phyaddr);
- #endif
- atomic_add_int(&pACB->srboutstandingcount,1);
- pSRB->startdone=ARCMSR_SRB_START;
- if(pARCMSR_CDB->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE)
- {
- CHIP_REG_WRITE32(&pACB->pmu->inbound_queueport,cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
- }
- else
- {
- CHIP_REG_WRITE32(&pACB->pmu->inbound_queueport,cdb_shifted_phyaddr);
+ u_int32_t cdb_shifted_phyaddr=(u_int32_t) srb->cdb_shifted_phyaddr;
+ struct ARCMSR_CDB * arcmsr_cdb=(struct ARCMSR_CDB *)&srb->arcmsr_cdb;
+
+ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap,
+ (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
+ atomic_add_int(&acb->srboutstandingcount, 1);
+ srb->startdone=ARCMSR_SRB_START;
+ if(arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
+ CHIP_REG_WRITE32(inbound_queueport, cdb_shifted_phyaddr|ARCMSR_SRBPOST_FLAG_SGL_BSIZE);
+ } else {
+ CHIP_REG_WRITE32(inbound_queueport, cdb_shifted_phyaddr);
}
return;
}
/*
-**************************************************************************
-**
-**
-**************************************************************************
-*/
-VOID arcmsr_post_wait2go_srb(PACB pACB)
-{
- ULONG s;
- PSRB pSRB;
- LONG i=0;
- #if ARCMSR_DEBUG0
- printf("arcmsr_post_wait2go_srb:srbwait2gocount=%d srboutstandingcount=%d\n",pACB->srbwait2gocount,pACB->srboutstandingcount);
- #endif
- s=splcam();
- while((pACB->srbwait2gocount > 0) && (pACB->srboutstandingcount < ARCMSR_MAX_OUTSTANDING_CMD))
- {
- pSRB=pACB->psrbwait2go[i];
- if(pSRB!=NULL)
- {
- pACB->psrbwait2go[i]=NULL;
- arcmsr_post_srb(pACB,pSRB);
- atomic_subtract_int(&pACB->srbwait2gocount,1);
- }
- i++;
- i%=ARCMSR_MAX_OUTSTANDING_CMD;
- }
- splx(s);
- return;
-}
-/*
**********************************************************************
-** Function: arcmsr_post_Qbuffer
-** Output:
**********************************************************************
*/
-VOID arcmsr_post_Qbuffer(PACB pACB)
+static void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb)
{
- ULONG s;
- PUCHAR pQbuffer;
- PQBUFFER pwbuffer=(PQBUFFER)&pACB->pmu->ioctl_wbuffer;
- PUCHAR iop_data=(PUCHAR)pwbuffer->data;
- LONG allxfer_len=0;
-
- s=splcam();
- while((pACB->wqbuf_firstindex!=pACB->wqbuf_lastindex) && (allxfer_len<124))
- {
- pQbuffer=&pACB->wqbuffer[pACB->wqbuf_firstindex];
- memcpy(iop_data,pQbuffer,1);
- pACB->wqbuf_firstindex++;
- pACB->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */
- iop_data++;
- allxfer_len++;
- }
- pwbuffer->data_len=allxfer_len;
- /*
- ** push inbound doorbell and wait reply at hwinterrupt routine for next Qbuffer post
- */
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell,ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
- splx(s);
+ u_int8_t * pQbuffer;
+ struct QBUFFER * pwbuffer=(struct QBUFFER *)&acb->pmu->message_wbuffer;
+ u_int8_t * iop_data=(u_int8_t *)pwbuffer->data;
+ u_int32_t allxfer_len=0;
+
+ if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
+ acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
+ while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) && (allxfer_len<124)) {
+ pQbuffer= &acb->wqbuffer[acb->wqbuf_firstindex];
+ memcpy(iop_data, pQbuffer, 1);
+ acb->wqbuf_firstindex++;
+ acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
+ iop_data++;
+ allxfer_len++;
+ }
+ pwbuffer->data_len=allxfer_len;
+ /*
+ ** push inbound doorbell and wait reply at hwinterrupt routine for next Qbuffer post
+ */
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
+ }
return;
}
/*
************************************************************************
-**
-**
************************************************************************
*/
-VOID arcmsr_stop_adapter_bgrb(PACB pACB)
+static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
{
- #if ARCMSR_DEBUG0
- printf("arcmsr_stop_adapter_bgrb..............\n");
- #endif
- pACB->acb_flags |= ACB_F_MSG_STOP_BGRB;
- pACB->acb_flags &= ~ACB_F_MSG_START_BGRB;
- CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0,ARCMSR_INBOUND_MESG0_STOP_BGRB);
+ acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'stop adapter rebulid' timeout \n"
+ , acb->pci_unit);
+ }
return;
}
/*
************************************************************************
-**
-**
************************************************************************
*/
-static VOID arcmsr_poll(struct cam_sim * psim)
+static void arcmsr_poll(struct cam_sim * psim)
{
arcmsr_interrupt(cam_sim_softc(psim));
return;
}
/*
**********************************************************************
-** Function: arcmsr_interrupt
-** Output: VOID
-** CAM Status field values
-**typedef enum {
-** CAM_REQ_INPROG, CCB request is in progress
-** CAM_REQ_CMP, CCB request completed without error
-** CAM_REQ_ABORTED, CCB request aborted by the host
-** CAM_UA_ABORT, Unable to abort CCB request
-** CAM_REQ_CMP_ERR, CCB request completed with an error
-** CAM_BUSY, CAM subsytem is busy
-** CAM_REQ_INVALID, CCB request was invalid
-** CAM_PATH_INVALID, Supplied Path ID is invalid
-** CAM_DEV_NOT_THERE, SCSI Device Not Installed/there
-** CAM_UA_TERMIO, Unable to terminate I/O CCB request
-** CAM_SEL_TIMEOUT, Target Selection Timeout
-** CAM_CMD_TIMEOUT, Command timeout
-** CAM_SCSI_STATUS_ERROR, SCSI error, look at error code in CCB
-** CAM_MSG_REJECT_REC, Message Reject Received
-** CAM_SCSI_BUS_RESET, SCSI Bus Reset Sent/Received
-** CAM_UNCOR_PARITY, Uncorrectable parity error occurred
-** CAM_AUTOSENSE_FAIL=0x10, Autosense: request sense cmd fail
-** CAM_NO_HBA, No HBA Detected error
-** CAM_DATA_RUN_ERR, Data Overrun error
-** CAM_UNEXP_BUSFREE, Unexpected Bus Free
-** CAM_SEQUENCE_FAIL, Target Bus Phase Sequence Failure
-** CAM_CCB_LEN_ERR, CCB length supplied is inadequate
-** CAM_PROVIDE_FAIL, Unable to provide requested capability
-** CAM_BDR_SENT, A SCSI BDR msg was sent to target
-** CAM_REQ_TERMIO, CCB request terminated by the host
-** CAM_UNREC_HBA_ERROR, Unrecoverable Host Bus Adapter Error
-** CAM_REQ_TOO_BIG, The request was too large for this host
-** CAM_REQUEUE_REQ,
-** * This request should be requeued to preserve
-** * transaction ordering. This typically occurs
-** * when the SIM recognizes an error that should
-** * freeze the queue and must place additional
-** * requests for the target at the sim level
-** * back into the XPT queue.
-**
-** CAM_IDE=0x33, Initiator Detected Error
-** CAM_RESRC_UNAVAIL, Resource Unavailable
-** CAM_UNACKED_EVENT, Unacknowledged Event by Host
-** CAM_MESSAGE_RECV, Message Received in Host Target Mode
-** CAM_INVALID_CDB, Invalid CDB received in Host Target Mode
-** CAM_LUN_INVALID, Lun supplied is invalid
-** CAM_TID_INVALID, Target ID supplied is invalid
-** CAM_FUNC_NOTAVAIL, The requested function is not available
-** CAM_NO_NEXUS, Nexus is not established
-** CAM_IID_INVALID, The initiator ID is invalid
-** CAM_CDB_RECVD, The SCSI CDB has been received
-** CAM_LUN_ALRDY_ENA, The LUN is already eanbeld for target mode
-** CAM_SCSI_BUSY, SCSI Bus Busy
-**
-** CAM_DEV_QFRZN=0x40, The DEV queue is frozen w/this err
-**
-** Autosense data valid for target
-** CAM_AUTOSNS_VALID=0x80,
-** CAM_RELEASE_SIMQ=0x100, SIM ready to take more commands
-** CAM_SIM_QUEUED =0x200, SIM has this command in it's queue
-**
-** CAM_STATUS_MASK=0x3F, Mask bits for just the status #
-**
-** Target Specific Adjunct Status
-** CAM_SENT_SENSE=0x40000000 sent sense with status
-**} cam_status;
**********************************************************************
*/
-static VOID arcmsr_interrupt(VOID *arg)
+static void arcmsr_interrupt(void *arg)
{
- PACB pACB=(PACB)arg;
- PSRB pSRB;
- ULONG flagpsrb,outbound_intstatus,outbound_doorbell;
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *)arg;
+ struct CommandControlBlock *srb;
+ u_int32_t flag_srb, outbound_intstatus, outbound_doorbell;
- #if ARCMSR_DEBUG0
- printf("arcmsr_interrupt..............\n");
- #endif
/*
*********************************************
- ** check outbound intstatus À˹µL¶l®t«öªù¹a
+ ** check outbound intstatus
*********************************************
*/
- outbound_intstatus=CHIP_REG_READ32(&pACB->pmu->outbound_intstatus) & pACB->outbound_int_enable;
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intstatus, outbound_intstatus);/*clear interrupt*/
- if(outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT)
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_interrupt:..........ARCMSR_MU_OUTBOUND_DOORBELL_INT\n");
- #endif
+ outbound_intstatus=CHIP_REG_READ32(outbound_intstatus) & acb->outbound_int_enable;
+ CHIP_REG_WRITE32(outbound_intstatus, outbound_intstatus);/*clear interrupt*/
+ if(outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) {
/*
*********************************************
- ** DOORBELL ¥m¾´! ¬O§_¦³¶l¥ó­nñ¦¬
+ ** DOORBELL
*********************************************
*/
- outbound_doorbell=CHIP_REG_READ32(&pACB->pmu->outbound_doorbell);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_doorbell,outbound_doorbell);/*clear interrupt */
- if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
- {
- PQBUFFER prbuffer=(PQBUFFER)&pACB->pmu->ioctl_rbuffer;
- PUCHAR iop_data=(PUCHAR)prbuffer->data;
- PUCHAR pQbuffer;
- LONG my_empty_len,iop_len,rqbuf_firstindex,rqbuf_lastindex;
- ULONG s;
- /*check this iop data if overflow my rqbuffer*/
- s=splcam();
- rqbuf_lastindex=pACB->rqbuf_lastindex;
- rqbuf_firstindex=pACB->rqbuf_firstindex;
+ outbound_doorbell=CHIP_REG_READ32(outbound_doorbell);
+ CHIP_REG_WRITE32(outbound_doorbell, outbound_doorbell);/*clear interrupt */
+ if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
+ struct QBUFFER * prbuffer=(struct QBUFFER *)&acb->pmu->message_rbuffer;
+ u_int8_t * iop_data=(u_int8_t *)prbuffer->data;
+ u_int8_t * pQbuffer;
+ u_int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
+
+ /*check this iop data if overflow my rqbuffer*/
+ rqbuf_lastindex=acb->rqbuf_lastindex;
+ rqbuf_firstindex=acb->rqbuf_firstindex;
iop_len=prbuffer->data_len;
- my_empty_len=(rqbuf_firstindex-rqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
- if(my_empty_len>=iop_len)
- {
- while(iop_len > 0)
- {
- pQbuffer=&pACB->rqbuffer[pACB->rqbuf_lastindex];
- memcpy(pQbuffer,iop_data,1);
- pACB->rqbuf_lastindex++;
- pACB->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;/*if last index number set it to 0 */
+ my_empty_len=(rqbuf_firstindex-rqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
+ if(my_empty_len>=iop_len) {
+ while(iop_len > 0) {
+ pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex];
+ memcpy(pQbuffer, iop_data, 1);
+ acb->rqbuf_lastindex++;
+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
iop_data++;
iop_len--;
}
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);/*signature, let IOP331 know data has been readed */
- }
- else
- {
- pACB->acb_flags|=ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /*signature, let IOP331 know data has been readed */
+ } else {
+ acb->acb_flags|=ACB_F_IOPDATA_OVERFLOW;
}
- splx(s);
}
- if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK)
- {
- ULONG s;
+ if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
+ acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
/*
*********************************************
- ** ¬Ý¬Ý¬O§_ÁÙ¦³¶l¥ó­n¶¶¹D±H¥X
*********************************************
*/
- s=splcam();
- if(pACB->wqbuf_firstindex!=pACB->wqbuf_lastindex)
- {
- PUCHAR pQbuffer;
- PQBUFFER pwbuffer=(PQBUFFER)&pACB->pmu->ioctl_wbuffer;
- PUCHAR iop_data=(PUCHAR)pwbuffer->data;
- LONG allxfer_len=0;
-
- while((pACB->wqbuf_firstindex!=pACB->wqbuf_lastindex) && (allxfer_len<124))
- {
- pQbuffer=&pACB->wqbuffer[pACB->wqbuf_firstindex];
- memcpy(iop_data,pQbuffer,1);
- pACB->wqbuf_firstindex++;
- pACB->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */
+ if(acb->wqbuf_firstindex!=acb->wqbuf_lastindex) {
+ u_int8_t * pQbuffer;
+ struct QBUFFER * pwbuffer=(struct QBUFFER *)&acb->pmu->message_wbuffer;
+ u_int8_t * iop_data=(u_int8_t *)pwbuffer->data;
+ u_int32_t allxfer_len=0;
+
+ acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
+ while((acb->wqbuf_firstindex!=acb->wqbuf_lastindex) && (allxfer_len<124)) {
+ pQbuffer= &acb->wqbuffer[acb->wqbuf_firstindex];
+ memcpy(iop_data, pQbuffer, 1);
+ acb->wqbuf_firstindex++;
+ acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
iop_data++;
allxfer_len++;
}
pwbuffer->data_len=allxfer_len;
/*
- ** push inbound doorbell tell iop driver data write ok and wait reply on next hwinterrupt for next Qbuffer post
+ ** push inbound doorbell tell iop driver data write ok
+ ** and wait reply on next hwinterrupt for next Qbuffer post
*/
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell,ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK);
}
- else
- {
- pACB->acb_flags |= ACB_F_IOCTL_WQBUFFER_CLEARED;
+ if(acb->wqbuf_firstindex==acb->wqbuf_lastindex) {
+ acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
}
- splx(s);
}
}
- if(outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT)
- {
+ if(outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) {
+ int target, lun;
/*
*****************************************************************************
** areca cdb command done
*****************************************************************************
*/
- while(1)
- {
- if((flagpsrb=CHIP_REG_READ32(&pACB->pmu->outbound_queueport)) == 0xFFFFFFFF)
- {
+ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ while(1) {
+ if((flag_srb=CHIP_REG_READ32(outbound_queueport)) == 0xFFFFFFFF) {
break;/*chip FIFO no srb for completion already*/
}
/* check if command done with no error*/
- pSRB=(PSRB)(CINT2P)(pACB->vir2phy_offset+(flagpsrb << 5));/*frame must be 32 bytes aligned*/
- if((pSRB->pACB!=pACB) || (pSRB->startdone!=ARCMSR_SRB_START))
- {
- if(pSRB->startdone==ARCMSR_SRB_ABORTED)
- {
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
- break;
+ srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));
+ /*frame must be 32 bytes aligned*/
+ if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
+ if(srb->startdone==ARCMSR_SRB_ABORTED) {
+ printf("arcmsr%d: srb='%p' isr got aborted command \n"
+ , acb->pci_unit, srb);
+ srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+ arcmsr_srb_complete(srb, 1);
+ continue;
}
- printf("arcmsr_interrupt:got an illegal srb command done ...pACB=%p pSRB=%p srboutstandingcount=%d .....\n",pACB,pSRB,pACB->srboutstandingcount);
- break;
+ printf("arcmsr%d: isr get an illegal srb command done"
+ "acb='%p' srb='%p' srbacb='%p' startdone=0x%x"
+ "srboutstandingcount=%d \n",
+ acb->pci_unit, acb, srb, srb->acb,
+ srb->startdone, acb->srboutstandingcount);
+ continue;
}
- if((flagpsrb & ARCMSR_SRBREPLY_FLAG_ERROR)==0)
- {
- pSRB->pccb->ccb_h.status=CAM_REQ_CMP;
- arcmsr_srb_complete(pSRB);
- }
- else
- {
- switch(pSRB->arcmsr_cdb.DeviceStatus)
- {
- case ARCMSR_DEV_SELECT_TIMEOUT:
- {
- #if ARCMSR_DEBUG0
- printf("pSRB=%p ......ARCMSR_DEV_SELECT_TIMEOUT\n",pSRB);
- #endif
- pSRB->pccb->ccb_h.status=CAM_SEL_TIMEOUT;
- arcmsr_srb_complete(pSRB);
+ target=srb->pccb->ccb_h.target_id;
+ lun=srb->pccb->ccb_h.target_lun;
+ if((flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR)==0) {
+ if(acb->devstate[target][lun]==ARECA_RAID_GONE) {
+ acb->devstate[target][lun]=ARECA_RAID_GOOD;
+ }
+ srb->pccb->ccb_h.status |= CAM_REQ_CMP;
+ arcmsr_srb_complete(srb, 1);
+ } else {
+ switch(srb->arcmsr_cdb.DeviceStatus) {
+ case ARCMSR_DEV_SELECT_TIMEOUT: {
+ acb->devstate[target][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_SEL_TIMEOUT;
+ arcmsr_srb_complete(srb, 1);
}
break;
case ARCMSR_DEV_ABORTED:
- {
- #if ARCMSR_DEBUG0
- printf("pSRB=%p ......ARCMSR_DEV_ABORTED\n",pSRB);
- #endif
- pSRB->pccb->ccb_h.status=CAM_DEV_NOT_THERE;
- arcmsr_srb_complete(pSRB);
- }
- break;
- case ARCMSR_DEV_INIT_FAIL:
- {
- #if ARCMSR_DEBUG0
- printf("pSRB=%p .....ARCMSR_DEV_INIT_FAIL\n",pSRB);
- #endif
- pSRB->pccb->ccb_h.status=CAM_DEV_NOT_THERE;
- arcmsr_srb_complete(pSRB);
+ case ARCMSR_DEV_INIT_FAIL: {
+ acb->devstate[target][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+ arcmsr_srb_complete(srb, 1);
}
break;
- case SCSISTAT_CHECK_CONDITION:
- {
- #if ARCMSR_DEBUG0
- printf("pSRB=%p .....SCSISTAT_CHECK_CONDITION\n",pSRB);
- #endif
- arcmsr_report_SenseInfoBuffer(pSRB);
- arcmsr_srb_complete(pSRB);
+ case SCSISTAT_CHECK_CONDITION: {
+ acb->devstate[target][lun]=ARECA_RAID_GOOD;
+ arcmsr_report_sense_info(srb);
+ arcmsr_srb_complete(srb, 1);
}
break;
default:
- /* error occur Q all error srb to errorsrbpending Q*/
- printf("arcmsr_interrupt:command error done ......but got unknow DeviceStatus=%x....\n",pSRB->arcmsr_cdb.DeviceStatus);
- pSRB->pccb->ccb_h.status=CAM_UNCOR_PARITY;/*unknow error or crc error just for retry*/
- arcmsr_srb_complete(pSRB);
+ printf("arcmsr%d: scsi id=%d lun=%d"
+ "isr get command error done,"
+ "but got unknow DeviceStatus=0x%x \n"
+ , acb->pci_unit, target, lun
+ ,srb->arcmsr_cdb.DeviceStatus);
+ acb->devstate[target][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY;
+ /*unknow error or crc error just for retry*/
+ arcmsr_srb_complete(srb, 1);
break;
}
}
} /*drain reply FIFO*/
}
- if(pACB->srbwait2gocount != 0)
- {
- arcmsr_post_wait2go_srb(pACB);/*try to post all pending srb*/
- }
- return;
+ return;
}
/*
-***********************************************************************
+*******************************************************************************
**
-**int copyin __P((const void *udaddr, void *kaddr, size_t len));
-**int copyout __P((const void *kaddr, void *udaddr, size_t len));
+*******************************************************************************
+*/
+static void arcmsr_iop_parking(struct AdapterControlBlock *acb)
+{
+ if(acb!=NULL) {
+ /* stop adapter background rebuild */
+ if(acb->acb_flags & ACB_F_MSG_START_BGRB) {
+ arcmsr_stop_adapter_bgrb(acb);
+ arcmsr_flush_adapter_cache(acb);
+ }
+ }
+}
+/*
+***********************************************************************
**
-**ENOENT "" No such file or directory ""
-**ENOIOCTL "" ioctl not handled by this layer ""
-**ENOMEM "" Cannot allocate memory ""
-**EINVAL "" Invalid argument ""
************************************************************************
*/
-LONG arcmsr_iop_ioctlcmd(PACB pACB,ULONG ioctl_cmd,caddr_t arg)
+u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_cmd, caddr_t arg)
{
- PCMD_IO_CONTROL pccbioctl=(PCMD_IO_CONTROL) arg;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_iop_ioctlcmd................. \n");
- #endif
+ struct CMD_MESSAGE_FIELD * pcmdmessagefld;
+ u_int32_t retvalue=EINVAL;
- if(memcmp(pccbioctl->Signature,"ARCMSR",6)!=0)
- {
- return EINVAL;
+ pcmdmessagefld=(struct CMD_MESSAGE_FIELD *) arg;
+ if(memcmp(pcmdmessagefld->cmdmessage.Signature, "ARCMSR", 6)!=0) {
+ return retvalue;
}
- switch(ioctl_cmd)
- {
- case ARCMSR_IOCTL_READ_RQBUFFER:
- {
- ULONG s;
- PCMD_IOCTL_FIELD pccbioctlfld=(PCMD_IOCTL_FIELD)arg;
- PUCHAR pQbuffer,ptmpQbuffer=pccbioctlfld->ioctldatabuffer;
- LONG allxfer_len=0;
-
- s=splcam();
- while((pACB->rqbuf_firstindex!=pACB->rqbuf_lastindex) && (allxfer_len<1031))
- {
+ ARCMSR_LOCK_ACQUIRE(&acb->qbuffer_lock);
+ switch(ioctl_cmd) {
+ case ARCMSR_MESSAGE_READ_RQBUFFER: {
+ u_int8_t * pQbuffer;
+ u_int8_t * ptmpQbuffer=pcmdmessagefld->messagedatabuffer;
+ u_int32_t allxfer_len=0;
+
+ while((acb->rqbuf_firstindex!=acb->rqbuf_lastindex) && (allxfer_len<1031)) {
/*copy READ QBUFFER to srb*/
- pQbuffer=&pACB->rqbuffer[pACB->rqbuf_firstindex];
- memcpy(ptmpQbuffer,pQbuffer,1);
- pACB->rqbuf_firstindex++;
- pACB->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; /*if last index number set it to 0 */
+ pQbuffer= &acb->rqbuffer[acb->rqbuf_firstindex];
+ memcpy(ptmpQbuffer, pQbuffer, 1);
+ acb->rqbuf_firstindex++;
+ acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
ptmpQbuffer++;
allxfer_len++;
}
- if(pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW)
- {
- PQBUFFER prbuffer=(PQBUFFER)&pACB->pmu->ioctl_rbuffer;
- PUCHAR pQbuffer;
- PUCHAR iop_data=(PUCHAR)prbuffer->data;
- LONG iop_len;
+ if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ struct QBUFFER * prbuffer=(struct QBUFFER *)&acb->pmu->message_rbuffer;
+ u_int8_t * iop_data=(u_int8_t *)prbuffer->data;
+ u_int32_t iop_len;
- pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- iop_len=(LONG)prbuffer->data_len;
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ iop_len=(u_int32_t)prbuffer->data_len;
/*this iop data does no chance to make me overflow again here, so just do it*/
- while(iop_len>0)
- {
- pQbuffer=&pACB->rqbuffer[pACB->rqbuf_lastindex];
- memcpy(pQbuffer,iop_data,1);
- pACB->rqbuf_lastindex++;
- pACB->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;/*if last index number set it to 0 */
+ while(iop_len>0) {
+ pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex];
+ memcpy(pQbuffer, iop_data, 1);
+ acb->rqbuf_lastindex++;
+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
iop_data++;
iop_len--;
}
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);/*signature, let IOP331 know data has been readed */
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /*signature, let IOP331 know data has been readed */
}
- pccbioctl->Length=allxfer_len;
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- splx(s);
- return ARC_IOCTL_SUCCESS;
+ pcmdmessagefld->cmdmessage.Length=allxfer_len;
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_WRITE_WQBUFFER:
- {
- ULONG s;
- PCMD_IOCTL_FIELD pccbioctlfld=(PCMD_IOCTL_FIELD)arg;
- LONG my_empty_len,user_len,wqbuf_firstindex,wqbuf_lastindex;
- PUCHAR pQbuffer,ptmpuserbuffer=pccbioctlfld->ioctldatabuffer;
-
- s=splcam();
- user_len=pccbioctl->Length;
-
- /*check if data xfer length of this request will overflow my array qbuffer */
- wqbuf_lastindex=pACB->wqbuf_lastindex;
- wqbuf_firstindex=pACB->wqbuf_firstindex;
- my_empty_len=(wqbuf_firstindex-wqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
- if(my_empty_len>=user_len)
- {
- while(user_len>0)
- {
- /*copy srb data to wqbuffer*/
- pQbuffer=&pACB->wqbuffer[pACB->wqbuf_lastindex];
- memcpy(pQbuffer,ptmpuserbuffer,1);
- pACB->wqbuf_lastindex++;
- pACB->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;/*if last index number set it to 0 */
- ptmpuserbuffer++;
- user_len--;
- }
- /*post fist Qbuffer*/
- if(pACB->acb_flags & ACB_F_IOCTL_WQBUFFER_CLEARED)
- {
- pACB->acb_flags &=~ACB_F_IOCTL_WQBUFFER_CLEARED;
- arcmsr_post_Qbuffer(pACB);
+ case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
+ u_int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
+ u_int8_t * pQbuffer;
+ u_int8_t * ptmpuserbuffer=pcmdmessagefld->messagedatabuffer;
+
+ user_len=pcmdmessagefld->cmdmessage.Length;
+ /*check if data xfer length of this request will overflow my array qbuffer */
+ wqbuf_lastindex=acb->wqbuf_lastindex;
+ wqbuf_firstindex=acb->wqbuf_firstindex;
+ if(wqbuf_lastindex!=wqbuf_firstindex) {
+ arcmsr_post_Qbuffer(acb);
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR;
+ } else {
+ my_empty_len=(wqbuf_firstindex-wqbuf_lastindex-1)&(ARCMSR_MAX_QBUFFER-1);
+ if(my_empty_len>=user_len) {
+ while(user_len>0) {
+ /*copy srb data to wqbuffer*/
+ pQbuffer= &acb->wqbuffer[acb->wqbuf_lastindex];
+ memcpy(pQbuffer, ptmpuserbuffer, 1);
+ acb->wqbuf_lastindex++;
+ acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+ /*if last index number set it to 0 */
+ ptmpuserbuffer++;
+ user_len--;
+ }
+ /*post fist Qbuffer*/
+ if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
+ acb->acb_flags &=~ACB_F_MESSAGE_WQBUFFER_CLEARED;
+ arcmsr_post_Qbuffer(acb);
+ }
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ } else {
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR;
}
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- }
- else
- {
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_ERROR;
}
- splx(s);
- return ARC_IOCTL_SUCCESS;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_CLEAR_RQBUFFER:
- {
- ULONG s;
- PUCHAR pQbuffer=pACB->rqbuffer;
- s=splcam();
- if(pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW)
- {
- pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);/*signature, let IOP331 know data has been readed */
+ case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
+ u_int8_t * pQbuffer=acb->rqbuffer;
+
+ if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /*signature, let IOP331 know data has been readed */
}
- pACB->acb_flags |= ACB_F_IOCTL_RQBUFFER_CLEARED;
- pACB->rqbuf_firstindex=0;
- pACB->rqbuf_lastindex=0;
- memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- splx(s);
- return ARC_IOCTL_SUCCESS;
+ acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
+ acb->rqbuf_firstindex=0;
+ acb->rqbuf_lastindex=0;
+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_CLEAR_WQBUFFER:
+ case ARCMSR_MESSAGE_CLEAR_WQBUFFER:
{
- ULONG s;
- PUCHAR pQbuffer=pACB->wqbuffer;
+ u_int8_t * pQbuffer=acb->wqbuffer;
- s=splcam();
- if(pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW)
- {
- pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);/*signature, let IOP331 know data has been readed */
+ if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /*signature, let IOP331 know data has been readed */
}
- pACB->acb_flags |= ACB_F_IOCTL_WQBUFFER_CLEARED;
- pACB->wqbuf_firstindex=0;
- pACB->wqbuf_lastindex=0;
- memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- splx(s);
- return ARC_IOCTL_SUCCESS;
+ acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED|ACB_F_MESSAGE_WQBUFFER_READED);
+ acb->wqbuf_firstindex=0;
+ acb->wqbuf_lastindex=0;
+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_CLEAR_ALLQBUFFER:
- {
- ULONG s;
- PUCHAR pQbuffer;
+ case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
+ u_int8_t * pQbuffer;
- s=splcam();
- if(pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW)
- {
- pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);/*signature, let IOP331 know data has been readed */
+ if(acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /*signature, let IOP331 know data has been readed */
}
- pACB->acb_flags |= (ACB_F_IOCTL_WQBUFFER_CLEARED|ACB_F_IOCTL_RQBUFFER_CLEARED);
- pACB->rqbuf_firstindex=0;
- pACB->rqbuf_lastindex=0;
- pACB->wqbuf_firstindex=0;
- pACB->wqbuf_lastindex=0;
- pQbuffer=pACB->rqbuffer;
- memset(pQbuffer, 0, sizeof(struct _QBUFFER));
- pQbuffer=pACB->wqbuffer;
- memset(pQbuffer, 0, sizeof(struct _QBUFFER));
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- splx(s);
- return ARC_IOCTL_SUCCESS;
+ acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
+ |ACB_F_MESSAGE_RQBUFFER_CLEARED
+ |ACB_F_MESSAGE_WQBUFFER_READED);
+ acb->rqbuf_firstindex=0;
+ acb->rqbuf_lastindex=0;
+ acb->wqbuf_firstindex=0;
+ acb->wqbuf_lastindex=0;
+ pQbuffer=acb->rqbuffer;
+ memset(pQbuffer, 0, sizeof(struct QBUFFER));
+ pQbuffer=acb->wqbuffer;
+ memset(pQbuffer, 0, sizeof(struct QBUFFER));
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_RETURN_CODE_3F:
- {
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_3F;
- return ARC_IOCTL_SUCCESS;
+ case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_3F;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
- case ARCMSR_IOCTL_SAY_HELLO:
- {
- PCMD_IOCTL_FIELD pccbioctlfld=(PCMD_IOCTL_FIELD)arg;
- PCHAR hello_string="Hello! I am ARCMSR";
- PCHAR puserbuffer=(PUCHAR)pccbioctlfld->ioctldatabuffer;
+ case ARCMSR_MESSAGE_SAY_HELLO: {
+ u_int8_t * hello_string="Hello! I am ARCMSR";
+ u_int8_t * puserbuffer=(u_int8_t *)pcmdmessagefld->messagedatabuffer;
- if(memcpy(puserbuffer,hello_string,(SHORT)strlen(hello_string)))
- {
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_ERROR;
- return ENOIOCTL;
+ if(memcpy(puserbuffer, hello_string, (int16_t)strlen(hello_string))) {
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_ERROR;
+ ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+ return ENOIOCTL;
}
- pccbioctl->ReturnCode=ARCMSR_IOCTL_RETURNCODE_OK;
- return ARC_IOCTL_SUCCESS;
+ pcmdmessagefld->cmdmessage.ReturnCode=ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
+ }
+ break;
+ case ARCMSR_MESSAGE_SAY_GOODBYE: {
+ arcmsr_iop_parking(acb);
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
+ }
+ break;
+ case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
+ arcmsr_flush_adapter_cache(acb);
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
}
break;
}
- return EINVAL;
+ ARCMSR_LOCK_RELEASE(&acb->qbuffer_lock);
+ return retvalue;
}
/*
**************************************************************************
-**
**************************************************************************
*/
-PSRB arcmsr_get_freesrb(PACB pACB)
+struct CommandControlBlock * arcmsr_get_freesrb(struct AdapterControlBlock *acb)
{
- PSRB pSRB=NULL;
- ULONG s;
- LONG srb_startindex,srb_doneindex;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_get_freesrb: srb_startindex=%d srb_doneindex=%d\n",pACB->srb_startindex,pACB->srb_doneindex);
- #endif
-
- s=splcam();
- srb_doneindex=pACB->srb_doneindex;
- srb_startindex=pACB->srb_startindex;
- pSRB=pACB->psrbringQ[srb_startindex];
- srb_startindex++;
- srb_startindex %= ARCMSR_MAX_FREESRB_NUM;
- if(srb_doneindex!=srb_startindex)
- {
- pACB->srb_startindex=srb_startindex;
- }
- else
- {
- pSRB=NULL;
+ struct CommandControlBlock *srb=NULL;
+ u_int32_t workingsrb_startindex, workingsrb_doneindex;
+
+ ARCMSR_LOCK_ACQUIRE(&acb->workingQ_start_lock);
+ workingsrb_doneindex=acb->workingsrb_doneindex;
+ workingsrb_startindex=acb->workingsrb_startindex;
+ srb=acb->srbworkingQ[workingsrb_startindex];
+ workingsrb_startindex++;
+ workingsrb_startindex %= ARCMSR_MAX_FREESRB_NUM;
+ if(workingsrb_doneindex!=workingsrb_startindex) {
+ acb->workingsrb_startindex=workingsrb_startindex;
+ } else {
+ srb=NULL;
}
- splx(s);
- return(pSRB);
+ ARCMSR_LOCK_RELEASE(&acb->workingQ_start_lock);
+ return(srb);
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
+static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb * pccb)
+{
+ struct CMD_MESSAGE_FIELD * pcmdmessagefld;
+ int retvalue = 0, transfer_len = 0;
+ char *buffer;
+ uint32_t controlcode = (uint32_t ) pccb->csio.cdb_io.cdb_bytes[5] << 24 |
+ (uint32_t ) pccb->csio.cdb_io.cdb_bytes[6] << 16 |
+ (uint32_t ) pccb->csio.cdb_io.cdb_bytes[7] << 8 |
+ (uint32_t ) pccb->csio.cdb_io.cdb_bytes[8];
+ /* 4 bytes: Areca io control code */
+ if((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
+ buffer = pccb->csio.data_ptr;
+ transfer_len = pccb->csio.dxfer_len;
+ } else {
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ goto message_out;
+ }
+ if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ goto message_out;
+ }
+ pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer;
+ switch(controlcode) {
+ case ARCMSR_MESSAGE_READ_RQBUFFER: {
+ u_int8_t *pQbuffer;
+ u_int8_t *ptmpQbuffer=pcmdmessagefld->messagedatabuffer;
+ int32_t allxfer_len = 0;
+
+ while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
+ && (allxfer_len < 1031)) {
+ pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
+ memcpy(ptmpQbuffer, pQbuffer, 1);
+ acb->rqbuf_firstindex++;
+ acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
+ ptmpQbuffer++;
+ allxfer_len++;
+ }
+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ struct QBUFFER *prbuffer = (struct QBUFFER *) &acb->pmu->message_rbuffer;
+ u_int8_t *iop_data = (u_int8_t *)prbuffer->data;
+ int32_t iop_len;
+
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ iop_len =(u_int32_t)prbuffer->data_len;
+ while (iop_len > 0) {
+ pQbuffer= &acb->rqbuffer[acb->rqbuf_lastindex];
+ memcpy(pQbuffer, iop_data, 1);
+ acb->rqbuf_lastindex++;
+ acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+ iop_data++;
+ iop_len--;
+ }
+ CHIP_REG_WRITE32(inbound_doorbell,
+ ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ }
+ pcmdmessagefld->cmdmessage.Length = allxfer_len;
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ retvalue=ARCMSR_MESSAGE_SUCCESS;
+ }
+ break;
+ case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
+ int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
+ u_int8_t *pQbuffer;
+ u_int8_t *ptmpuserbuffer=pcmdmessagefld->messagedatabuffer;
+
+ user_len = pcmdmessagefld->cmdmessage.Length;
+ wqbuf_lastindex = acb->wqbuf_lastindex;
+ wqbuf_firstindex = acb->wqbuf_firstindex;
+ if (wqbuf_lastindex != wqbuf_firstindex) {
+ arcmsr_post_Qbuffer(acb);
+ /* has error report sensedata */
+ if(&pccb->csio.sense_data) {
+ ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
+ /* Valid,ErrorCode */
+ ((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05;
+ /* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
+ ((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A;
+ /* AdditionalSenseLength */
+ ((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20;
+ /* AdditionalSenseCode */
+ }
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ } else {
+ my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
+ &(ARCMSR_MAX_QBUFFER - 1);
+ if (my_empty_len >= user_len) {
+ while (user_len > 0) {
+ pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
+ memcpy(pQbuffer, ptmpuserbuffer, 1);
+ acb->wqbuf_lastindex++;
+ acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
+ ptmpuserbuffer++;
+ user_len--;
+ }
+ if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
+ acb->acb_flags &=
+ ~ACB_F_MESSAGE_WQBUFFER_CLEARED;
+ arcmsr_post_Qbuffer(acb);
+ }
+ } else {
+ /* has error report sensedata */
+ if(&pccb->csio.sense_data) {
+ ((u_int8_t *)&pccb->csio.sense_data)[0] = (0x1 << 7 | 0x70);
+ /* Valid,ErrorCode */
+ ((u_int8_t *)&pccb->csio.sense_data)[2] = 0x05;
+ /* FileMark,EndOfMedia,IncorrectLength,Reserved,SenseKey */
+ ((u_int8_t *)&pccb->csio.sense_data)[7] = 0x0A;
+ /* AdditionalSenseLength */
+ ((u_int8_t *)&pccb->csio.sense_data)[12] = 0x20;
+ /* AdditionalSenseCode */
+ }
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ }
+ }
+ }
+ break;
+ case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
+ u_int8_t *pQbuffer = acb->rqbuffer;
+
+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell
+ , ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ }
+ acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
+ acb->rqbuf_firstindex = 0;
+ acb->rqbuf_lastindex = 0;
+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
+ break;
+ case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
+ u_int8_t *pQbuffer = acb->wqbuffer;
+
+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell
+ , ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ }
+ acb->acb_flags |=
+ (ACB_F_MESSAGE_WQBUFFER_CLEARED |
+ ACB_F_MESSAGE_WQBUFFER_READED);
+ acb->wqbuf_firstindex = 0;
+ acb->wqbuf_lastindex = 0;
+ memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
+ pcmdmessagefld->cmdmessage.ReturnCode =
+ ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
+ break;
+ case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
+ u_int8_t *pQbuffer;
+
+ if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
+ acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
+ CHIP_REG_WRITE32(inbound_doorbell
+ , ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ }
+ acb->acb_flags |=
+ (ACB_F_MESSAGE_WQBUFFER_CLEARED
+ | ACB_F_MESSAGE_RQBUFFER_CLEARED
+ | ACB_F_MESSAGE_WQBUFFER_READED);
+ acb->rqbuf_firstindex = 0;
+ acb->rqbuf_lastindex = 0;
+ acb->wqbuf_firstindex = 0;
+ acb->wqbuf_lastindex = 0;
+ pQbuffer = acb->rqbuffer;
+ memset(pQbuffer, 0, sizeof (struct QBUFFER));
+ pQbuffer = acb->wqbuffer;
+ memset(pQbuffer, 0, sizeof (struct QBUFFER));
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
+ break;
+ case ARCMSR_MESSAGE_REQUEST_RETURNCODE_3F: {
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F;
+ }
+ break;
+ case ARCMSR_MESSAGE_SAY_HELLO: {
+ int8_t * hello_string = "Hello! I am ARCMSR";
+
+ memcpy(pcmdmessagefld->messagedatabuffer, hello_string
+ , (int16_t)strlen(hello_string));
+ pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
+ }
+ break;
+ case ARCMSR_MESSAGE_SAY_GOODBYE:
+ arcmsr_iop_parking(acb);
+ break;
+ case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
+ arcmsr_flush_adapter_cache(acb);
+ break;
+ default:
+ retvalue = ARCMSR_MESSAGE_FAIL;
+ }
+message_out:
+ return retvalue;
}
/*
*********************************************************************
-**
-**
-**
*********************************************************************
*/
-static VOID arcmsr_executesrb(VOID *arg,bus_dma_segment_t *dm_segs,LONG nseg,LONG error)
+static void arcmsr_executesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
- PSRB pSRB=(PSRB)arg;
- PACB pACB;
- union ccb *pccb;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_executesrb........................................ \n" );
- #endif
-
- pccb=pSRB->pccb;
- pACB=(PACB)pSRB->pACB;
- if(error != 0)
- {
- if(error != EFBIG)
- {
- printf("arcmsr_executesrb:%d Unexepected error %x returned from " "bus_dmamap_load\n",pACB->pci_unit,error);
+ struct CommandControlBlock *srb=(struct CommandControlBlock *)arg;
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *)srb->acb;
+ union ccb * pccb;
+ int target, lun;
+
+ pccb=srb->pccb;
+ target=pccb->ccb_h.target_id;
+ lun=pccb->ccb_h.target_lun;
+ if(error != 0) {
+ if(error != EFBIG) {
+ printf("arcmsr%d: unexpected error %x returned from 'bus_dmamap_load' \n"
+ , acb->pci_unit, error);
}
- if(pccb->ccb_h.status == CAM_REQ_INPROG)
- {
- xpt_freeze_devq(pccb->ccb_h.path,/*count*/1);
- pccb->ccb_h.status=CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
+ if((pccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
+ xpt_freeze_devq(pccb->ccb_h.path, /*count*/1);
+ pccb->ccb_h.status |= (CAM_REQ_TOO_BIG|CAM_DEV_QFRZN);
}
- xpt_done(pccb);
+ arcmsr_srb_complete(srb, 0);
return;
}
- arcmsr_build_srb(pSRB,dm_segs,nseg);
- if((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG)
- {
- if(nseg != 0)
- {
- bus_dmamap_unload(pACB->buffer_dmat,pSRB->dmamap);
+ if(nseg > ARCMSR_MAX_SG_ENTRIES) {
+ pccb->ccb_h.status |= CAM_REQ_TOO_BIG;
+ arcmsr_srb_complete(srb, 0);
+ return;
+ }
+ if(acb->acb_flags & ACB_F_BUS_RESET) {
+ printf("arcmsr%d: bus reset and return busy \n", acb->pci_unit);
+ pccb->ccb_h.status |= CAM_SCSI_BUS_RESET;
+ arcmsr_srb_complete(srb, 0);
+ return;
+ }
+ if(acb->devstate[target][lun]==ARECA_RAID_GONE) {
+ u_int8_t block_cmd;
+
+ block_cmd=pccb->csio.cdb_io.cdb_bytes[0] & 0x0f;
+ if(block_cmd==0x08 || block_cmd==0x0a) {
+ printf("arcmsr%d:block 'read/write' command"
+ "with gone raid volume Cmd=%2x, TargetId=%d, Lun=%d \n"
+ , acb->pci_unit, block_cmd, target, lun);
+ pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+ arcmsr_srb_complete(srb, 0);
+ return;
}
- xpt_done(pccb);
+ }
+ if((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
+ if(nseg != 0) {
+ bus_dmamap_unload(acb->dm_segs_dmat, srb->dm_segs_dmamap);
+ }
+ arcmsr_srb_complete(srb, 0);
return;
}
pccb->ccb_h.status |= CAM_SIM_QUEUED;
- if(pACB->srboutstandingcount < ARCMSR_MAX_OUTSTANDING_CMD)
- {
- /*
- ******************************************************************
- ** and we can make sure there were no pending srb in this duration
- ******************************************************************
- */
- arcmsr_post_srb(pACB,pSRB);
- }
- else
- {
- /*
- ******************************************************************
- ** Q of srbwaitexec will be post out when any outstanding command complete
- ******************************************************************
- */
- arcmsr_queue_wait2go_srb(pACB,pSRB);
+ if(acb->srboutstandingcount >= ARCMSR_MAX_OUTSTANDING_CMD) {
+ pccb->ccb_h.status |= CAM_SCSI_BUSY;
+ arcmsr_srb_complete(srb, 0);
+ return;
}
+ arcmsr_build_srb(srb, dm_segs, nseg);
+ arcmsr_post_srb(acb, srb);
return;
}
/*
*****************************************************************************************
-**
*****************************************************************************************
*/
-BOOLEAN arcmsr_seek_cmd2abort(union ccb * pabortccb)
+static u_int8_t arcmsr_seek_cmd2abort(union ccb * abortccb)
{
- PSRB pSRB,pfreesrb;
- PACB pACB=(PACB) pabortccb->ccb_h.arcmsr_ccbacb_ptr;
- ULONG s,intmask_org,mask;
- LONG i=0;
+ struct CommandControlBlock *srb;
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *) abortccb->ccb_h.arcmsr_ccbacb_ptr;
+ u_int32_t intmask_org, mask;
+ int i=0;
- #if ARCMSR_DEBUG0
- printf("arcmsr_seek_cmd2abort.................. \n");
- #endif
-
- s=splcam();
- /*
+ acb->num_aborts++;
+ /*
+ ***************************************************************************
** It is the upper layer do abort command this lock just prior to calling us.
** First determine if we currently own this command.
** Start by searching the device queue. If not found
- ** at all,and the system wanted us to just abort the
+ ** at all, and the system wanted us to just abort the
** command return success.
+ ***************************************************************************
*/
- if(pACB->srboutstandingcount!=0)
- {
- /* Q back all outstanding srb into wait exec psrb Q*/
- pfreesrb=pACB->pfreesrb;
- for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++)
- {
- pSRB=&pfreesrb[i];
- if(pSRB->startdone==ARCMSR_SRB_START)
- {
- if(pSRB->pccb==pabortccb)
- {
- /* disable all outbound interrupt */
- intmask_org=CHIP_REG_READ32(&pACB->pmu->outbound_intmask);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
- /* talk to iop 331 outstanding command aborted*/
- arcmsr_abort_allcmd(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_seek_cmd2abort: wait 'abort all outstanding command' timeout.................in \n");
- }
- /*clear all outbound posted Q*/
- for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++)
- {
- CHIP_REG_READ32(&pACB->pmu->outbound_queueport);
- }
- pfreesrb=pACB->pfreesrb;
- for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++)
- {
- pSRB=&pfreesrb[i];
- if(pSRB->startdone==ARCMSR_SRB_START)
- {
- pSRB->startdone=ARCMSR_SRB_ABORTED;
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
- }
- }
- /* enable all outbound interrupt */
- mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org & mask);
- splx(s);
- return(TRUE);
- }
- }
- }
- }
- /*
- ** seek this command at our command list
- ** if command found then remove,abort it and free this SRB
- */
- if(pACB->srbwait2gocount!=0)
- {
- for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++)
- {
- pSRB=pACB->psrbwait2go[i];
- if(pSRB!=NULL)
- {
- if(pSRB->pccb==pabortccb)
- {
- pACB->psrbwait2go[i]=NULL;
- pSRB->startdone=ARCMSR_SRB_ABORTED;
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
- atomic_subtract_int(&pACB->srbwait2gocount,1);
- splx(s);
- return(TRUE);
+ if(acb->srboutstandingcount!=0) {
+ for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
+ srb=acb->psrb_pool[i];
+ if(srb->startdone==ARCMSR_SRB_START) {
+ if(srb->pccb==abortccb) {
+ srb->startdone=ARCMSR_SRB_ABORTED;
+ printf("arcmsr%d:scsi id=%d lun=%d abort srb '%p'"
+ "outstanding command \n"
+ , acb->pci_unit, abortccb->ccb_h.target_id
+ , abortccb->ccb_h.target_lun, srb);
+ goto abort_outstanding_cmd;
}
}
}
}
- splx(s);
- return (FALSE);
+ return(FALSE);
+abort_outstanding_cmd:
+ /* do not talk to iop 331 abort command */
+ UDELAY(3000*1000);/*wait for 3 sec for all command done*/
+ /* disable all outbound interrupt */
+ intmask_org=CHIP_REG_READ32(outbound_intmask);
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
+ arcmsr_polling_srbdone(acb, srb);
+ /* enable all outbound interrupt */
+ mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE);
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org & mask);
+ return (TRUE);
}
/*
****************************************************************************
-**
****************************************************************************
*/
-VOID arcmsr_bus_reset(PACB pACB)
+static void arcmsr_bus_reset(struct AdapterControlBlock *acb)
{
- #if ARCMSR_DEBUG0
- printf("arcmsr_bus_reset.......................... \n");
- #endif
-
- arcmsr_iop_reset(pACB);
- return;
+ int retry=0;
+
+ acb->num_resets++;
+ acb->acb_flags |=ACB_F_BUS_RESET;
+ while(acb->srboutstandingcount!=0 && retry < 400) {
+ arcmsr_interrupt((void *)acb);
+ UDELAY(25000);
+ retry++;
+ }
+ arcmsr_iop_reset(acb);
+ acb->acb_flags &= ~ACB_F_BUS_RESET;
+ return;
}
/*
+**************************************************************************
+**************************************************************************
+*/
+static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
+ union ccb * pccb)
+{
+ pccb->ccb_h.status |= CAM_REQ_CMP;
+ switch (pccb->csio.cdb_io.cdb_bytes[0]) {
+ case INQUIRY: {
+ unsigned char inqdata[36];
+ char *buffer=pccb->csio.data_ptr;;
+
+ if (pccb->ccb_h.target_lun) {
+ pccb->ccb_h.status |= CAM_SEL_TIMEOUT;
+ xpt_done(pccb);
+ return;
+ }
+ inqdata[0] = T_PROCESSOR;
+ /* Periph Qualifier & Periph Dev Type */
+ inqdata[1] = 0;
+ /* rem media bit & Dev Type Modifier */
+ inqdata[2] = 0;
+ /* ISO, ECMA, & ANSI versions */
+ inqdata[4] = 31;
+ /* length of additional data */
+ strncpy(&inqdata[8], "Areca ", 8);
+ /* Vendor Identification */
+ strncpy(&inqdata[16], "RAID controller ", 16);
+ /* Product Identification */
+ strncpy(&inqdata[32], "R001", 4); /* Product Revision */
+ memcpy(buffer, inqdata, sizeof(inqdata));
+ xpt_done(pccb);
+ }
+ break;
+ case WRITE_BUFFER:
+ case READ_BUFFER: {
+ if (arcmsr_iop_message_xfer(acb, pccb)) {
+ pccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
+ pccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
+ }
+ xpt_done(pccb);
+ }
+ break;
+ default:
+ xpt_done(pccb);
+ }
+}
+/*
*********************************************************************
-**
-** CAM Status field values
-**typedef enum {
-** CAM_REQ_INPROG, CCB request is in progress
-** CAM_REQ_CMP, CCB request completed without error
-** CAM_REQ_ABORTED, CCB request aborted by the host
-** CAM_UA_ABORT, Unable to abort CCB request
-** CAM_REQ_CMP_ERR, CCB request completed with an error
-** CAM_BUSY, CAM subsytem is busy
-** CAM_REQ_INVALID, CCB request was invalid
-** CAM_PATH_INVALID, Supplied Path ID is invalid
-** CAM_DEV_NOT_THERE, SCSI Device Not Installed/there
-** CAM_UA_TERMIO, Unable to terminate I/O CCB request
-** CAM_SEL_TIMEOUT, Target Selection Timeout
-** CAM_CMD_TIMEOUT, Command timeout
-** CAM_SCSI_STATUS_ERROR, SCSI error, look at error code in CCB
-** CAM_MSG_REJECT_REC, Message Reject Received
-** CAM_SCSI_BUS_RESET, SCSI Bus Reset Sent/Received
-** CAM_UNCOR_PARITY, Uncorrectable parity error occurred
-** CAM_AUTOSENSE_FAIL=0x10, Autosense: request sense cmd fail
-** CAM_NO_HBA, No HBA Detected error
-** CAM_DATA_RUN_ERR, Data Overrun error
-** CAM_UNEXP_BUSFREE, Unexpected Bus Free
-** CAM_SEQUENCE_FAIL, Target Bus Phase Sequence Failure
-** CAM_CCB_LEN_ERR, CCB length supplied is inadequate
-** CAM_PROVIDE_FAIL, Unable to provide requested capability
-** CAM_BDR_SENT, A SCSI BDR msg was sent to target
-** CAM_REQ_TERMIO, CCB request terminated by the host
-** CAM_UNREC_HBA_ERROR, Unrecoverable Host Bus Adapter Error
-** CAM_REQ_TOO_BIG, The request was too large for this host
-** CAM_REQUEUE_REQ,
-** * This request should be requeued to preserve
-** * transaction ordering. This typically occurs
-** * when the SIM recognizes an error that should
-** * freeze the queue and must place additional
-** * requests for the target at the sim level
-** * back into the XPT queue.
-**
-** CAM_IDE=0x33, Initiator Detected Error
-** CAM_RESRC_UNAVAIL, Resource Unavailable
-** CAM_UNACKED_EVENT, Unacknowledged Event by Host
-** CAM_MESSAGE_RECV, Message Received in Host Target Mode
-** CAM_INVALID_CDB, Invalid CDB received in Host Target Mode
-** CAM_LUN_INVALID, Lun supplied is invalid
-** CAM_TID_INVALID, Target ID supplied is invalid
-** CAM_FUNC_NOTAVAIL, The requested function is not available
-** CAM_NO_NEXUS, Nexus is not established
-** CAM_IID_INVALID, The initiator ID is invalid
-** CAM_CDB_RECVD, The SCSI CDB has been received
-** CAM_LUN_ALRDY_ENA, The LUN is already eanbeld for target mode
-** CAM_SCSI_BUSY, SCSI Bus Busy
-**
-** CAM_DEV_QFRZN=0x40, The DEV queue is frozen w/this err
-**
-** Autosense data valid for target
-** CAM_AUTOSNS_VALID=0x80,
-** CAM_RELEASE_SIMQ=0x100, SIM ready to take more commands
-** CAM_SIM_QUEUED =0x200, SIM has this command in it's queue
-**
-** CAM_STATUS_MASK=0x3F, Mask bits for just the status #
-**
-** Target Specific Adjunct Status
-** CAM_SENT_SENSE=0x40000000 sent sense with status
-**} cam_status;
-**
-**union ccb {
-** struct ccb_hdr ccb_h; For convenience
-** struct ccb_scsiio csio;
-** struct ccb_getdev cgd;
-** struct ccb_getdevlist cgdl;
-** struct ccb_pathinq cpi;
-** struct ccb_relsim crs;
-** struct ccb_setasync csa;
-** struct ccb_setdev csd;
-** struct ccb_pathstats cpis;
-** struct ccb_getdevstats cgds;
-** struct ccb_dev_match cdm;
-** struct ccb_trans_settings cts;
-** struct ccb_calc_geometry ccg;
-** struct ccb_abort cab;
-** struct ccb_resetbus crb;
-** struct ccb_resetdev crd;
-** struct ccb_termio tio;
-** struct ccb_accept_tio atio;
-** struct ccb_scsiio ctio;
-** struct ccb_en_lun cel;
-** struct ccb_immed_notify cin;
-** struct ccb_notify_ack cna;
-** struct ccb_eng_inq cei;
-** struct ccb_eng_exec cee;
-** struct ccb_rescan crcn;
-** struct ccb_debug cdbg;
-** }
-**
-**struct ccb_hdr {
-** cam_pinfo pinfo; "" Info for priority scheduling
-** camq_entry xpt_links; "" For chaining in the XPT layer
-** camq_entry sim_links; "" For chaining in the SIM layer
-** camq_entry periph_links; "" For chaining in the type driver
-** u_int32_t retry_count;
-** void (*cbfcnp)(struct cam_periph *, union ccb *);"" Callback on completion function
-** xpt_opcode func_code; "" XPT function code
-** u_int32_t status; "" Status returned by CAM subsystem
-** struct cam_path *path; "" Compiled path for this ccb
-** path_id_t path_id; "" Path ID for the request
-** target_id_t target_id; "" Target device ID
-** lun_id_t target_lun; "" Target LUN number
-** u_int32_t flags;
-** ccb_ppriv_area periph_priv;
-** ccb_spriv_area sim_priv;
-** u_int32_t timeout; "" Timeout value
-** struct callout_handle timeout_ch; "" Callout handle used for timeouts
-**};
-**
-**typedef union {
-** u_int8_t *cdb_ptr; "" Pointer to the CDB bytes to send
-** u_int8_t cdb_bytes[IOCDBLEN]; "" Area for the CDB send
-**} cdb_t;
-**
-** SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO
-** function codes.
-**
-**struct ccb_scsiio {
-** struct ccb_hdr ccb_h;
-** union ccb *next_ccb; "" Ptr for next CCB for action
-** u_int8_t *req_map; "" Ptr to mapping info
-** u_int8_t *data_ptr; "" Ptr to the data buf/SG list
-** u_int32_t dxfer_len; "" Data transfer length
-** struct scsi_sense_data sense_data; "" Autosense storage
-** u_int8_t sense_len; "" Number of bytes to autosense
-** u_int8_t cdb_len; "" Number of bytes for the CDB
-** u_int16_t sglist_cnt; "" Number of SG list entries
-** u_int8_t scsi_status; "" Returned SCSI status
-** u_int8_t sense_resid; "" Autosense resid length: 2's comp
-** u_int32_t resid; "" Transfer residual length: 2's comp
-** cdb_t cdb_io; "" Union for CDB bytes/pointer
-** u_int8_t *msg_ptr; "" Pointer to the message buffer
-** u_int16_t msg_len; "" Number of bytes for the Message
-** u_int8_t tag_action; "" What to do for tag queueing
-**#define CAM_TAG_ACTION_NONE 0x00 "" The tag action should be either the define below (to send a non-tagged transaction) or one of the defined scsi tag messages from scsi_message.h.
-** u_int tag_id; "" tag id from initator (target mode)
-** u_int init_id; "" initiator id of who selected
-**}
*********************************************************************
*/
-static VOID arcmsr_action(struct cam_sim * psim,union ccb * pccb)
+static void arcmsr_action(struct cam_sim * psim, union ccb * pccb)
{
- PACB pACB;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_action ..................................\n" );
- #endif
+ struct AdapterControlBlock * acb;
- pACB=(PACB) cam_sim_softc(psim);
- if(pACB==NULL)
- {
- pccb->ccb_h.status=CAM_REQ_INVALID;
+ acb=(struct AdapterControlBlock *) cam_sim_softc(psim);
+ if(acb==NULL) {
+ pccb->ccb_h.status |= CAM_REQ_INVALID;
xpt_done(pccb);
return;
}
- switch (pccb->ccb_h.func_code)
- {
- case XPT_SCSI_IO:
- {
- PSRB pSRB;
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_SCSI_IO......................\n" );
- #endif
-
- if((pSRB=arcmsr_get_freesrb(pACB)) == NULL)
- {
- pccb->ccb_h.status=CAM_RESRC_UNAVAIL;
+ switch (pccb->ccb_h.func_code) {
+ case XPT_SCSI_IO: {
+ struct CommandControlBlock *srb;
+ int target=pccb->ccb_h.target_id;
+
+ if(target == 16) {
+ /* virtual device for iop message transfer */
+ arcmsr_handle_virtual_command(acb, pccb);
+ return;
+ }
+ if((srb=arcmsr_get_freesrb(acb)) == NULL) {
+ pccb->ccb_h.status |= CAM_RESRC_UNAVAIL;
xpt_done(pccb);
return;
}
- pccb->ccb_h.arcmsr_ccbsrb_ptr=pSRB;
- pccb->ccb_h.arcmsr_ccbacb_ptr=pACB;
- pSRB->pccb=pccb;
- if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
- {
- if((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0)
- {
- if((pccb->ccb_h.flags & CAM_DATA_PHYS) == 0)
- {
- LONG error,s;
+ pccb->ccb_h.arcmsr_ccbsrb_ptr=srb;
+ pccb->ccb_h.arcmsr_ccbacb_ptr=acb;
+ srb->pccb=pccb;
+ if((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
+ if(!(pccb->ccb_h.flags & CAM_SCATTER_VALID)) {
+ /* Single buffer */
+ if(!(pccb->ccb_h.flags & CAM_DATA_PHYS)) {
+ /* Buffer is virtual */
+ u_int32_t error, s;
s=splsoftvm();
- error = bus_dmamap_load(pACB->buffer_dmat,pSRB->dmamap,pccb->csio.data_ptr,pccb->csio.dxfer_len,arcmsr_executesrb,pSRB,/*flags*/0);
- if(error == EINPROGRESS)
- {
- xpt_freeze_simq(pACB->psim,1);
+ error = bus_dmamap_load(acb->dm_segs_dmat
+ , srb->dm_segs_dmamap
+ , pccb->csio.data_ptr
+ , pccb->csio.dxfer_len
+ , arcmsr_executesrb, srb, /*flags*/0);
+ if(error == EINPROGRESS) {
+ xpt_freeze_simq(acb->psim, 1);
pccb->ccb_h.status |= CAM_RELEASE_SIMQ;
}
splx(s);
- }
- else
- {
+ } else {
+ /* Buffer is physical */
panic("arcmsr: CAM_DATA_PHYS not supported");
}
- }
- else
- {
+ } else {
+ /* Scatter/gather list */
struct bus_dma_segment *segs;
- if((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0 || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0)
- {
- pccb->ccb_h.status=CAM_PROVIDE_FAIL;
+ if((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0
+ || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) {
+ pccb->ccb_h.status |= CAM_PROVIDE_FAIL;
xpt_done(pccb);
- free(pSRB,M_DEVBUF);
+ free(srb, M_DEVBUF);
return;
}
segs=(struct bus_dma_segment *)pccb->csio.data_ptr;
- arcmsr_executesrb(pSRB,segs,pccb->csio.sglist_cnt,0);
+ arcmsr_executesrb(srb, segs, pccb->csio.sglist_cnt, 0);
}
- }
- else
- {
- arcmsr_executesrb(pSRB,NULL,0,0);
+ } else {
+ arcmsr_executesrb(srb, NULL, 0, 0);
}
break;
}
- case XPT_TARGET_IO:
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_TARGET_IO\n" );
- #endif
- /*
- ** target mode not yet support vendor specific commands.
- */
- pccb->ccb_h.status=CAM_REQ_CMP;
+ case XPT_TARGET_IO: {
+ /* target mode not yet support vendor specific commands. */
+ pccb->ccb_h.status |= CAM_REQ_CMP;
xpt_done(pccb);
break;
}
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi=&pccb->cpi;
+ case XPT_PATH_INQ: {
+ struct ccb_pathinq *cpi= &pccb->cpi;
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_PATH_INQ\n" );
- #endif
cpi->version_num=1;
cpi->hba_inquiry=PI_SDTR_ABLE | PI_TAG_ABLE;
cpi->target_sprt=0;
cpi->hba_misc=0;
cpi->hba_eng_cnt=0;
- cpi->max_target=ARCMSR_MAX_TARGETID;
- cpi->max_lun=ARCMSR_MAX_TARGETLUN; /* 7 or 0 */
- cpi->initiator_id=ARCMSR_SCSI_INITIATOR_ID;
+ cpi->max_target=ARCMSR_MAX_TARGETID; /* 0-16 */
+ cpi->max_lun=ARCMSR_MAX_TARGETLUN; /* 0-7 */
+ cpi->initiator_id=ARCMSR_SCSI_INITIATOR_ID; /* 255 */
cpi->bus_id=cam_sim_bus(psim);
- strncpy(cpi->sim_vid,"FreeBSD",SIM_IDLEN);
- strncpy(cpi->hba_vid,"ARCMSR",HBA_IDLEN);
- strncpy(cpi->dev_name,cam_sim_name(psim),DEV_IDLEN);
+ strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
+ strncpy(cpi->hba_vid, "ARCMSR", HBA_IDLEN);
+ strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
cpi->unit_number=cam_sim_unit(psim);
- cpi->ccb_h.status=CAM_REQ_CMP;
cpi->transport = XPORT_SPI;
cpi->transport_version = 2;
cpi->protocol = PROTO_SCSI;
cpi->protocol_version = SCSI_REV_2;
+ cpi->ccb_h.status |= CAM_REQ_CMP;
xpt_done(pccb);
break;
}
- case XPT_ABORT:
- {
+ case XPT_ABORT: {
union ccb *pabort_ccb;
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_ABORT\n" );
- #endif
pabort_ccb=pccb->cab.abort_ccb;
- switch (pabort_ccb->ccb_h.func_code)
- {
+ switch (pabort_ccb->ccb_h.func_code) {
case XPT_ACCEPT_TARGET_IO:
case XPT_IMMED_NOTIFY:
case XPT_CONT_TARGET_IO:
- if(arcmsr_seek_cmd2abort(pabort_ccb)==TRUE)
- {
- pabort_ccb->ccb_h.status=CAM_REQ_ABORTED;
+ if(arcmsr_seek_cmd2abort(pabort_ccb)==TRUE) {
+ pabort_ccb->ccb_h.status |= CAM_REQ_ABORTED;
xpt_done(pabort_ccb);
- pccb->ccb_h.status=CAM_REQ_CMP;
- }
- else
- {
+ pccb->ccb_h.status |= CAM_REQ_CMP;
+ } else {
xpt_print_path(pabort_ccb->ccb_h.path);
printf("Not found\n");
- pccb->ccb_h.status=CAM_PATH_INVALID;
+ pccb->ccb_h.status |= CAM_PATH_INVALID;
}
break;
case XPT_SCSI_IO:
- pccb->ccb_h.status=CAM_UA_ABORT;
+ pccb->ccb_h.status |= CAM_UA_ABORT;
break;
default:
- pccb->ccb_h.status=CAM_REQ_INVALID;
+ pccb->ccb_h.status |= CAM_REQ_INVALID;
break;
}
xpt_done(pccb);
break;
}
case XPT_RESET_BUS:
- case XPT_RESET_DEV:
- {
- LONG i;
+ case XPT_RESET_DEV: {
+ u_int32_t i;
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_RESET_BUS\n" );
- #endif
- arcmsr_bus_reset(pACB);
- for (i=0; i < 500; i++)
- {
+ arcmsr_bus_reset(acb);
+ for (i=0; i < 500; i++) {
DELAY(1000);
}
- pccb->ccb_h.status=CAM_REQ_CMP;
+ pccb->ccb_h.status |= CAM_REQ_CMP;
xpt_done(pccb);
break;
}
- case XPT_TERM_IO:
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_TERM_IO\n" );
- #endif
- pccb->ccb_h.status=CAM_REQ_INVALID;
+ case XPT_TERM_IO: {
+ pccb->ccb_h.status |= CAM_REQ_INVALID;
xpt_done(pccb);
break;
}
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &pccb->cts;
- ULONG s;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
+ case XPT_GET_TRAN_SETTINGS: {
+ struct ccb_trans_settings *cts;
+ struct ccb_trans_settings_scsi *scsi;
+ struct ccb_trans_settings_spi *spi;
+
+ if(pccb->ccb_h.target_id == 16) {
+ pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
+ xpt_done(pccb);
+ break;
+ }
+
+ cts= &pccb->cts;
+ scsi = &cts->proto_specific.scsi;
+ spi = &cts->xport_specific.spi;
cts->protocol = PROTO_SCSI;
cts->protocol_version = SCSI_REV_2;
cts->transport = XPORT_SPI;
cts->transport_version = 2;
-
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_GET_TRAN_SETTINGS\n" );
- #endif
-
- s=splcam();
spi->flags = CTS_SPI_FLAGS_DISC_ENB;
spi->sync_period=3;
spi->sync_offset=32;
@@ -1991,52 +1599,53 @@ static VOID arcmsr_action(struct cam_sim * psim,union ccb * pccb)
| CTS_SPI_VALID_SYNC_OFFSET
| CTS_SPI_VALID_BUS_WIDTH;
scsi->valid = CTS_SCSI_VALID_TQ;
- splx(s);
- pccb->ccb_h.status=CAM_REQ_CMP;
+
+ pccb->ccb_h.status |= CAM_REQ_CMP;
xpt_done(pccb);
break;
}
- case XPT_SET_TRAN_SETTINGS:
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_SET_TRAN_SETTINGS\n" );
- #endif
- pccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(pccb);
+ case XPT_SET_TRAN_SETTINGS: {
+ pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
+ xpt_done(pccb);
break;
}
- case XPT_CALC_GEOMETRY:
- {
+ case XPT_CALC_GEOMETRY: {
struct ccb_calc_geometry *ccg;
- ULONG size_mb;
- ULONG secs_per_cylinder;
+ u_int32_t size_mb;
+ u_int32_t secs_per_cylinder;
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: XPT_CALC_GEOMETRY\n" );
- #endif
- ccg=&pccb->ccg;
+ if(pccb->ccb_h.target_id == 16) {
+ pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
+ xpt_done(pccb);
+ break;
+ }
+ ccg= &pccb->ccg;
+ if (ccg->block_size == 0) {
+ pccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(pccb);
+ break;
+ }
+ if(((1024L * 1024L)/ccg->block_size) < 0) {
+ pccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(pccb);
+ break;
+ }
size_mb=ccg->volume_size/((1024L * 1024L)/ccg->block_size);
- if(size_mb > 1024 )
- {
+ if(size_mb > 1024 ) {
ccg->heads=255;
ccg->secs_per_track=63;
- }
- else
- {
+ } 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;
- pccb->ccb_h.status=CAM_REQ_CMP;
+ pccb->ccb_h.status |= CAM_REQ_CMP;
xpt_done(pccb);
break;
}
default:
- #if ARCMSR_DEBUG0
- printf("arcmsr_action: invalid XPT function CAM_REQ_INVALID\n" );
- #endif
- pccb->ccb_h.status=CAM_REQ_INVALID;
+ pccb->ccb_h.status |= CAM_REQ_INVALID;
xpt_done(pccb);
break;
}
@@ -2044,115 +1653,233 @@ static VOID arcmsr_action(struct cam_sim * psim,union ccb * pccb)
}
/*
**********************************************************************
-**
-** start background rebuild
-**
**********************************************************************
*/
-VOID arcmsr_start_adapter_bgrb(PACB pACB)
+static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
{
- #if ARCMSR_DEBUG0
- printf("arcmsr_start_adapter_bgrb.................................. \n");
- #endif
- pACB->acb_flags |= ACB_F_MSG_START_BGRB;
- pACB->acb_flags &= ~ACB_F_MSG_STOP_BGRB;
- CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0,ARCMSR_INBOUND_MESG0_START_BGRB);
+ acb->acb_flags |= ACB_F_MSG_START_BGRB;
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
+ }
return;
}
/*
**********************************************************************
-**
-** start background rebuild
-**
**********************************************************************
*/
-VOID arcmsr_iop_init(PACB pACB)
+static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
{
- ULONG intmask_org,mask,outbound_doorbell,firmware_state=0;
-
- #if ARCMSR_DEBUG0
- printf("arcmsr_iop_init.................................. \n");
- #endif
- do
- {
- firmware_state=CHIP_REG_READ32(&pACB->pmu->outbound_msgaddr1);
- }while((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)==0);
- /* disable all outbound interrupt */
- intmask_org=CHIP_REG_READ32(&pACB->pmu->outbound_intmask);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
- /*start background rebuild*/
- arcmsr_start_adapter_bgrb(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_HwInitialize: wait 'start adapter background rebuild' timeout................. \n");
+ struct CommandControlBlock *srb;
+ uint32_t flag_srb, outbound_intstatus, poll_srb_done=0, poll_count=0;
+ int id, lun;
+
+polling_srb_retry:
+ poll_count++;
+ outbound_intstatus=CHIP_REG_READ32(outbound_intstatus) & acb->outbound_int_enable;
+ CHIP_REG_WRITE32(outbound_intstatus, outbound_intstatus);/*clear interrupt*/
+ while(1) {
+ if((flag_srb=CHIP_REG_READ32(outbound_queueport))==0xFFFFFFFF) {
+ if(poll_srb_done) {
+ break;/*chip FIFO no ccb for completion already*/
+ } else {
+ UDELAY(25000);
+ if(poll_count > 100) {
+ break;
+ }
+ goto polling_srb_retry;
+ }
+ }
+ /* check ifcommand done with no error*/
+ srb=(struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb << 5));
+ /*frame must be 32 bytes aligned*/
+ if((srb->acb!=acb) || (srb->startdone!=ARCMSR_SRB_START)) {
+ if((srb->startdone==ARCMSR_SRB_ABORTED) && (srb==poll_srb)) {
+ printf("arcmsr%d: scsi id=%d lun=%d srb='%p'"
+ "poll command abort successfully \n"
+ , acb->pci_unit
+ , srb->pccb->ccb_h.target_id
+ , srb->pccb->ccb_h.target_lun, srb);
+ srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+ arcmsr_srb_complete(srb, 1);
+ poll_srb_done=1;
+ continue;
+ }
+ printf("arcmsr%d: polling get an illegal srb command done srb='%p'"
+ "srboutstandingcount=%d \n"
+ , acb->pci_unit
+ , srb, acb->srboutstandingcount);
+ continue;
+ }
+ id=srb->pccb->ccb_h.target_id;
+ lun=srb->pccb->ccb_h.target_lun;
+ if((flag_srb & ARCMSR_SRBREPLY_FLAG_ERROR)==0) {
+ if(acb->devstate[id][lun]==ARECA_RAID_GONE) {
+ acb->devstate[id][lun]=ARECA_RAID_GOOD;
+ }
+ srb->pccb->ccb_h.status |= CAM_REQ_CMP;
+ arcmsr_srb_complete(srb, 1);
+ } else {
+ switch(srb->arcmsr_cdb.DeviceStatus) {
+ case ARCMSR_DEV_SELECT_TIMEOUT: {
+ acb->devstate[id][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_SEL_TIMEOUT;
+ arcmsr_srb_complete(srb, 1);
+ }
+ break;
+ case ARCMSR_DEV_ABORTED:
+ case ARCMSR_DEV_INIT_FAIL: {
+ acb->devstate[id][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_DEV_NOT_THERE;
+ arcmsr_srb_complete(srb, 1);
+ }
+ break;
+ case SCSISTAT_CHECK_CONDITION: {
+ acb->devstate[id][lun]=ARECA_RAID_GOOD;
+ arcmsr_report_sense_info(srb);
+ arcmsr_srb_complete(srb, 1);
+ }
+ break;
+ default:
+ printf("arcmsr%d: scsi id=%d lun=%d"
+ "polling and getting command error done"
+ ", but got unknow DeviceStatus=0x%x \n"
+ , acb->pci_unit, id, lun, srb->arcmsr_cdb.DeviceStatus);
+ acb->devstate[id][lun]=ARECA_RAID_GONE;
+ srb->pccb->ccb_h.status |= CAM_UNCOR_PARITY;
+ /*unknow error or crc error just for retry*/
+ arcmsr_srb_complete(srb, 1);
+ break;
+ }
+ }
+ } /*drain reply FIFO*/
+ return;
+}
+/*
+**********************************************************************
+** get firmware miscellaneous data
+**********************************************************************
+*/
+static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
+{
+ char *acb_firm_model=acb->firm_model;
+ char *acb_firm_version=acb->firm_version;
+ size_t iop_firm_model=offsetof(struct MessageUnit,message_rwbuffer[15]); /*firm_model,15,60-67*/
+ size_t iop_firm_version=offsetof(struct MessageUnit,message_rwbuffer[17]); /*firm_version,17,68-83*/
+ int i;
+
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n"
+ , acb->pci_unit);
+ }
+ i=0;
+ while(i<8) {
+ *acb_firm_model=bus_space_read_1(acb->btag, acb->bhandle, iop_firm_model+i);
+ /* 8 bytes firm_model, 15, 60-67*/
+ acb_firm_model++;
+ i++;
+ }
+ i=0;
+ while(i<16) {
+ *acb_firm_version=bus_space_read_1(acb->btag, acb->bhandle, iop_firm_version+i);
+ /* 16 bytes firm_version, 17, 68-83*/
+ acb_firm_version++;
+ i++;
}
+ printf("ARECA RAID ADAPTER%d: %s \n", acb->pci_unit, ARCMSR_DRIVER_VERSION);
+ printf("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", acb->pci_unit, acb->firm_version);
+ acb->firm_request_len=CHIP_REG_READ32(message_rwbuffer[1]); /*firm_request_len, 1, 04-07*/
+ acb->firm_numbers_queue=CHIP_REG_READ32(message_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
+ acb->firm_sdram_size=CHIP_REG_READ32(message_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/
+ acb->firm_ide_channels=CHIP_REG_READ32(message_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/
+ return;
+}
+/*
+**********************************************************************
+** start background rebulid
+**********************************************************************
+*/
+static void arcmsr_iop_init(struct AdapterControlBlock *acb)
+{
+ u_int32_t intmask_org, mask, outbound_doorbell, firmware_state=0;
+
+ do {
+ firmware_state=CHIP_REG_READ32(outbound_msgaddr1);
+ } while((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)==0);
+ intmask_org=CHIP_REG_READ32(outbound_intmask)|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE;
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org);
+ intmask_org=CHIP_REG_READ32(outbound_intmask)|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE;
+ arcmsr_get_firmware_spec(acb);
+ arcmsr_start_adapter_bgrb(acb);
/* clear Qbuffer if door bell ringed */
- outbound_doorbell=CHIP_REG_READ32(&pACB->pmu->outbound_doorbell);
- if(outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
- {
- CHIP_REG_WRITE32(&pACB->pmu->outbound_doorbell,outbound_doorbell);/*clear interrupt */
- CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell,ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
- }
- /* enable outbound Post Queue,outbound message0,outbell doorbell Interrupt */
- mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE|ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,intmask_org & mask);
- pACB->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
- pACB->acb_flags |=ACB_F_IOP_INITED;
+ outbound_doorbell=CHIP_REG_READ32(outbound_doorbell);
+ CHIP_REG_WRITE32(outbound_doorbell, outbound_doorbell);/*clear interrupt */
+ CHIP_REG_WRITE32(inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK);
+ /* enable outbound Post Queue, outbound message0, outbell doorbell Interrupt */
+ mask=~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE|ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE);
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org & mask);
+ acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff;
+ acb->acb_flags |=ACB_F_IOP_INITED;
return;
}
/*
**********************************************************************
-**
-** map freesrb
-**
**********************************************************************
*/
static void arcmsr_map_freesrb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
- PACB pACB=arg;
- PSRB psrb_tmp,pfreesrb;
- ULONG cdb_phyaddr;
- LONG i;
-
- pfreesrb=(PSRB)pACB->uncacheptr;
- cdb_phyaddr=segs->ds_addr; /* We suppose bus_addr_t high part always 0 here*/
- if(((CPT2INT)pACB->uncacheptr & 0x1F)!=0)
- {
- pfreesrb=pfreesrb+(0x20-((CPT2INT)pfreesrb & 0x1F));
- cdb_phyaddr=cdb_phyaddr+(0x20-((CPT2INT)cdb_phyaddr & 0x1F));
+ struct AdapterControlBlock *acb=arg;
+ struct CommandControlBlock *srb_tmp;
+ u_int8_t * dma_memptr;
+ u_int32_t i, srb_phyaddr_hi32;
+ unsigned long srb_phyaddr=(unsigned long)segs->ds_addr;
+
+ dma_memptr=acb->uncacheptr;
+ srb_phyaddr=segs->ds_addr; /* We suppose bus_addr_t high part always 0 here*/
+ if(((unsigned long)dma_memptr & 0x1F)!=0) {
+ dma_memptr=dma_memptr+(0x20-((unsigned long)dma_memptr & 0x1F));
+ srb_phyaddr=srb_phyaddr+(0x20-((unsigned long)srb_phyaddr & 0x1F));
+ }
+ srb_tmp=(struct CommandControlBlock *)dma_memptr;
+ for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
+ /*srb address must 32 (0x20) boundary*/
+ if(((unsigned long)srb_tmp & 0x1F)==0) {
+ if(bus_dmamap_create(acb->dm_segs_dmat, /*flags*/0, &srb_tmp->dm_segs_dmamap)!=0) {
+ acb->acb_flags |= ACB_F_MAPFREESRB_FAILD;
+ printf("arcmsr%d: srb dmamap bus_dmamap_create error\n", acb->pci_unit);
+ return;
+ }
+ srb_tmp->cdb_shifted_phyaddr=srb_phyaddr >> 5;
+ srb_tmp->acb=acb;
+ acb->srbworkingQ[i]=acb->psrb_pool[i]=srb_tmp;
+ srb_phyaddr=srb_phyaddr+sizeof(struct CommandControlBlock);
+ } else {
+ acb->acb_flags |= ACB_F_MAPFREESRB_FAILD;
+ printf("arcmsr%d: dma_memptr=%p i=%d"
+ "this srb cross 32 bytes boundary ignored srb_tmp=%p \n"
+ , acb->pci_unit, dma_memptr, i, srb_tmp);
+ return;
+ }
+ srb_tmp++;
}
+ acb->vir2phy_offset=(unsigned long)srb_tmp-(unsigned long)srb_phyaddr;
/*
********************************************************************
** here we need to tell iop 331 our freesrb.HighPart
** if freesrb.HighPart is not zero
********************************************************************
*/
- for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++)
- {
- psrb_tmp=&pfreesrb[i];
- if(((CPT2INT)psrb_tmp & 0x1F)==0) /*srb address must 32 (0x20) boundary*/
- {
- if(bus_dmamap_create(pACB->buffer_dmat, /*flags*/0, &psrb_tmp->dmamap)!=0)
- {
- pACB->acb_flags |= ACB_F_MAPFREESRB_FAILD;
- printf(" arcmsr_map_freesrb: (pSRB->dmamap) bus_dmamap_create ..............error\n");
- return;
- }
- psrb_tmp->cdb_shifted_phyaddr=cdb_phyaddr >> 5;
- psrb_tmp->pACB=pACB;
- pACB->psrbringQ[i]=psrb_tmp;
- cdb_phyaddr=cdb_phyaddr+sizeof(struct _SRB);
- }
- else
- {
- pACB->acb_flags |= ACB_F_MAPFREESRB_FAILD;
- printf(" arcmsr_map_freesrb:pfreesrb=%p i=%d this srb cross 32 bytes boundary ignored ......psrb_tmp=%p \n",pfreesrb,i,psrb_tmp);
- return;
+ srb_phyaddr_hi32=(uint32_t) ((srb_phyaddr>>16)>>16);
+ if(srb_phyaddr_hi32!=0) {
+ CHIP_REG_WRITE32(message_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
+ CHIP_REG_WRITE32(message_rwbuffer[1], srb_phyaddr_hi32);
+ CHIP_REG_WRITE32(inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
+ if(arcmsr_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
}
}
- pACB->pfreesrb=pfreesrb;
- pACB->vir2phy_offset=(CPT2INT)psrb_tmp-(cdb_phyaddr-sizeof(struct _SRB));
- return;
+ return;
}
/*
************************************************************************
@@ -2160,255 +1887,240 @@ static void arcmsr_map_freesrb(void *arg, bus_dma_segment_t *segs, int nseg, int
**
************************************************************************
*/
-VOID arcmsr_free_resource(PACB pACB)
+static void arcmsr_free_resource(struct AdapterControlBlock *acb)
{
/* remove the control device */
- if (pACB->ioctl_dev != NULL)
- {
- destroy_dev(pACB->ioctl_dev);
+ if(acb->ioctl_dev != NULL) {
+ destroy_dev(acb->ioctl_dev);
}
- bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap);
- bus_dmamap_destroy(pACB->srb_dmat, pACB->srb_dmamap);
- bus_dma_tag_destroy(pACB->srb_dmat);
- bus_dma_tag_destroy(pACB->buffer_dmat);
- bus_dma_tag_destroy(pACB->parent_dmat);
+ bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap);
+ bus_dmamap_destroy(acb->srb_dmat, acb->srb_dmamap);
+ bus_dma_tag_destroy(acb->srb_dmat);
+ bus_dma_tag_destroy(acb->dm_segs_dmat);
+ bus_dma_tag_destroy(acb->parent_dmat);
return;
}
/*
************************************************************************
-** PCI config header registers for all devices
-**
-** #define PCIR_COMMAND 0x04
-** #define PCIM_CMD_PORTEN 0x0001
-** #define PCIM_CMD_MEMEN 0x0002
-** #define PCIM_CMD_BUSMASTEREN 0x0004
-** #define PCIM_CMD_MWRICEN 0x0010
-** #define PCIM_CMD_PERRESPEN 0x0040
-**
-** Function : arcmsr_initialize
-** Purpose : initialize the internal structures for a given SCSI host
-** Inputs : host - pointer to this host adapter's structure
-** Preconditions : when this function is called,the chip_type
-** field of the pACB structure MUST have been set.
-**
-** 10h Base Address register #0
-** 14h Base Address register #1
-** 18h Base Address register #2
-** 1Ch Base Address register #3
-** 20h Base Address register #4
-** 24h Base Address register #5
************************************************************************
*/
-static LONG arcmsr_initialize(device_t dev)
+static u_int32_t arcmsr_initialize(device_t dev)
{
- PACB pACB=device_get_softc(dev);
- LONG rid=PCI_BASE_ADDR0;
+ struct AdapterControlBlock *acb=device_get_softc(dev);
+ u_int32_t intmask_org, rid=PCIR_BAR(0);
vm_offset_t mem_base;
- USHORT pci_command;
+ u_int16_t pci_command;
+ int i, j;
- #if ARCMSR_DEBUG0
- printf("arcmsr_initialize..............................\n");
- #endif
#if __FreeBSD_version >= 502010
- if (bus_dma_tag_create( /*parent*/NULL,
- /*alignemnt*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
- /*nsegments*/BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0,
- /*lockfunc*/NULL,
- /*lockarg*/NULL,
- &pACB->parent_dmat) != 0)
+ if(bus_dma_tag_create( /*parent*/ NULL,
+ /*alignemnt*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*nsegments*/ BUS_SPACE_UNRESTRICTED,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->parent_dmat) != 0)
#else
- if (bus_dma_tag_create( /*parent*/NULL,
- /*alignemnt*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
- /*nsegments*/BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0,
- &pACB->parent_dmat) != 0)
+ if(bus_dma_tag_create( /*parent*/ NULL,
+ /*alignemnt*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*nsegments*/ BUS_SPACE_UNRESTRICTED,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ &acb->parent_dmat) != 0)
#endif
{
- printf("arcmsr_initialize: bus_dma_tag_create .......................failure!\n");
+ printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
return ENOMEM;
}
- /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
+ /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
#if __FreeBSD_version >= 502010
- if(bus_dma_tag_create( /*parent_dmat*/pACB->parent_dmat,
- /*alignment*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/MAXBSIZE,
- /*nsegments*/ARCMSR_MAX_SG_ENTRIES,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/BUS_DMA_ALLOCNOW,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/&Giant,
- &pACB->buffer_dmat) != 0)
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ MAXBSIZE,
+ /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ busdma_lock_mutex,
+ /*lockarg*/ &Giant,
+ &acb->dm_segs_dmat) != 0)
#else
- if(bus_dma_tag_create( /*parent_dmat*/pACB->parent_dmat,
- /*alignment*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/MAXBSIZE,
- /*nsegments*/ARCMSR_MAX_SG_ENTRIES,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/BUS_DMA_ALLOCNOW,
- &pACB->buffer_dmat) != 0)
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ MAXBSIZE,
+ /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ &acb->dm_segs_dmat) != 0)
#endif
{
- bus_dma_tag_destroy(pACB->parent_dmat);
- printf("arcmsr_initialize: bus_dma_tag_create ............................failure!\n");
+ bus_dma_tag_destroy(acb->parent_dmat);
+ printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
return ENOMEM;
- }
- /* DMA tag for our srb structures.... Allocate the pfreesrb memory */
+ }
+ /* DMA tag for our srb structures.... Allocate the freesrb memory */
#if __FreeBSD_version >= 502010
- if (bus_dma_tag_create( /*parent_dmat*/pACB->parent_dmat,
- /*alignment*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/((sizeof(struct _SRB) * ARCMSR_MAX_FREESRB_NUM)+0x20),
- /*nsegments*/1,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0,
- /*lockfunc*/NULL,
- /*lockarg*/NULL,
- &pACB->srb_dmat) != 0)
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ ARCMSR_SRBS_POOL_SIZE,
+ /*nsegments*/ 1,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->srb_dmat) != 0)
#else
- if (bus_dma_tag_create( /*parent_dmat*/pACB->parent_dmat,
- /*alignment*/1,
- /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL,
- /*filterarg*/NULL,
- /*maxsize*/((sizeof(struct _SRB) * ARCMSR_MAX_FREESRB_NUM)+0x20),
- /*nsegments*/1,
- /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/0,
- &pACB->srb_dmat) != 0)
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ ARCMSR_SRBS_POOL_SIZE,
+ /*nsegments*/ 1,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ &acb->srb_dmat) != 0)
#endif
{
- bus_dma_tag_destroy(pACB->buffer_dmat);
- bus_dma_tag_destroy(pACB->parent_dmat);
- printf("arcmsr_initialize: pACB->srb_dmat bus_dma_tag_create .....................failure!\n");
+ bus_dma_tag_destroy(acb->dm_segs_dmat);
+ bus_dma_tag_destroy(acb->parent_dmat);
+ printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
return ENXIO;
- }
+ }
/* Allocation for our srbs */
- if (bus_dmamem_alloc(pACB->srb_dmat, (void **)&pACB->uncacheptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT, &pACB->srb_dmamap) != 0)
- {
- bus_dma_tag_destroy(pACB->srb_dmat);
- bus_dma_tag_destroy(pACB->buffer_dmat);
- bus_dma_tag_destroy(pACB->parent_dmat);
- printf("arcmsr_initialize: pACB->srb_dmat bus_dma_tag_create ...............failure!\n");
+ if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr
+ , BUS_DMA_WAITOK | BUS_DMA_COHERENT, &acb->srb_dmamap) != 0) {
+ bus_dma_tag_destroy(acb->srb_dmat);
+ bus_dma_tag_destroy(acb->dm_segs_dmat);
+ bus_dma_tag_destroy(acb->parent_dmat);
+ printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", acb->pci_unit);
return ENXIO;
}
/* And permanently map them */
- if(bus_dmamap_load(pACB->srb_dmat, pACB->srb_dmamap,pACB->uncacheptr,(sizeof(struct _SRB) * ARCMSR_MAX_FREESRB_NUM)+0x20,arcmsr_map_freesrb, pACB, /*flags*/0))
- {
- bus_dma_tag_destroy(pACB->srb_dmat);
- bus_dma_tag_destroy(pACB->buffer_dmat);
- bus_dma_tag_destroy(pACB->parent_dmat);
- printf("arcmsr_initialize: bus_dmamap_load................... failure!\n");
+ if(bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr
+ , ARCMSR_SRBS_POOL_SIZE, arcmsr_map_freesrb, acb, /*flags*/0)) {
+ bus_dma_tag_destroy(acb->srb_dmat);
+ bus_dma_tag_destroy(acb->dm_segs_dmat);
+ bus_dma_tag_destroy(acb->parent_dmat);
+ printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", acb->pci_unit);
return ENXIO;
}
- pci_command=pci_read_config(dev,PCIR_COMMAND,2);
+ pci_command=pci_read_config(dev, PCIR_COMMAND, 2);
pci_command |= PCIM_CMD_BUSMASTEREN;
pci_command |= PCIM_CMD_PERRESPEN;
pci_command |= PCIM_CMD_MWRICEN;
/* Enable Busmaster/Mem */
pci_command |= PCIM_CMD_MEMEN;
- pci_write_config(dev,PCIR_COMMAND,pci_command,2);
- pACB->sys_res_arcmsr=bus_alloc_resource(dev,SYS_RES_MEMORY,&rid,0,~0,0x1000,RF_ACTIVE);
- if(pACB->sys_res_arcmsr == NULL)
- {
- arcmsr_free_resource(pACB);
- printf("arcmsr_initialize: bus_alloc_resource .....................failure!\n");
+ pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
+ acb->sys_res_arcmsr=bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0ul, ~0ul, 0x1000, RF_ACTIVE);
+ if(acb->sys_res_arcmsr == NULL) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
- if(rman_get_start(pACB->sys_res_arcmsr) <= 0)
- {
- arcmsr_free_resource(pACB);
- printf("arcmsr_initialize: rman_get_start ...........................failure!\n");
- return ENXIO;
+ if(rman_get_start(acb->sys_res_arcmsr) <= 0) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
+ return ENXIO;
}
- mem_base=(vm_offset_t) rman_get_virtual(pACB->sys_res_arcmsr);
- if(mem_base==0)
- {
- arcmsr_free_resource(pACB);
- printf("arcmsr_initialize: rman_get_virtual ..........................failure!\n");
+ mem_base=(vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr);
+ if(mem_base==0) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
- if(pACB->acb_flags & ACB_F_MAPFREESRB_FAILD)
- {
- arcmsr_free_resource(pACB);
- printf("arcmsr_initialize: arman_get_virtual ..........................failure!\n");
+ if(acb->acb_flags & ACB_F_MAPFREESRB_FAILD) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: map free srb failure!\n", acb->pci_unit);
return ENXIO;
}
- pACB->btag=rman_get_bustag(pACB->sys_res_arcmsr);
- pACB->bhandle=rman_get_bushandle(pACB->sys_res_arcmsr);
- pACB->pmu=(PMU)mem_base;
- pACB->acb_flags |= (ACB_F_IOCTL_WQBUFFER_CLEARED|ACB_F_IOCTL_RQBUFFER_CLEARED);
- pACB->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
- arcmsr_iop_init(pACB);
- return(0);
+ acb->btag=rman_get_bustag(acb->sys_res_arcmsr);
+ acb->bhandle=rman_get_bushandle(acb->sys_res_arcmsr);
+ acb->pmu=(struct MessageUnit *)mem_base;
+ acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED
+ |ACB_F_MESSAGE_RQBUFFER_CLEARED
+ |ACB_F_MESSAGE_WQBUFFER_READED);
+ acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
+ /*
+ ********************************************************************
+ ** init raid volume state
+ ********************************************************************
+ */
+ for(i=0;i<ARCMSR_MAX_TARGETID;i++) {
+ for(j=0;j<ARCMSR_MAX_TARGETLUN;j++) {
+ acb->devstate[i][j]=ARECA_RAID_GOOD;
+ }
+ }
+ /* disable iop all outbound interrupt */
+ intmask_org=CHIP_REG_READ32(outbound_intmask);
+ CHIP_REG_WRITE32(outbound_intmask, intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE);
+ arcmsr_iop_init(acb);
+ return(0);
}
/*
************************************************************************
-**
-** attach and init a host adapter
-**
************************************************************************
*/
-static LONG arcmsr_attach(device_t dev)
+static u_int32_t arcmsr_attach(device_t dev)
{
- PACB pACB=device_get_softc(dev);
- LONG unit=device_get_unit(dev);
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
+ u_int32_t unit=device_get_unit(dev);
struct ccb_setasync csa;
struct cam_devq *devq; /* Device Queue to use for this SIM */
struct resource *irqres;
int rid;
- #if ARCMSR_DEBUG0
- printf("arcmsr_attach .............................\n" );
- #endif
-
- if(arcmsr_initialize(dev))
- {
- printf("arcmsr_attach: arcmsr_initialize failure!\n");
+ if(acb == NULL) {
+ printf("arcmsr%d: cannot allocate softc\n", unit);
+ return (ENOMEM);
+ }
+ bzero(acb, sizeof(struct AdapterControlBlock));
+ if(arcmsr_initialize(dev)) {
+ printf("arcmsr%d: initialize failure!\n", unit);
return ENXIO;
}
- /* After setting up the adapter,map our interrupt */
+ /* After setting up the adapter, map our interrupt */
rid=0;
- irqres=bus_alloc_resource(dev,SYS_RES_IRQ,&rid,0,~0,1,RF_SHAREABLE | RF_ACTIVE);
- if(irqres == NULL || bus_setup_intr(dev,irqres,INTR_TYPE_CAM,arcmsr_interrupt,pACB,&pACB->ih))
- {
- arcmsr_free_resource(pACB);
- printf("arcmsr%d: unable to register interrupt handler!\n",unit);
+ irqres=bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE);
+ if(irqres == NULL ||
+ bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE
+ , arcmsr_interrupt, acb, &acb->ih)) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: unable to register interrupt handler!\n", unit);
return ENXIO;
}
- pACB->irqres=irqres;
- pACB->pci_dev=dev;
- pACB->pci_unit=unit;
+ acb->irqres=irqres;
+ acb->pci_dev=dev;
+ acb->pci_unit=unit;
/*
* Now let the CAM generic SCSI layer find the SCSI devices on
* the bus * start queue to reset to the idle loop. *
@@ -2416,229 +2128,175 @@ static LONG arcmsr_attach(device_t dev)
* max_sim_transactions
*/
devq=cam_simq_alloc(ARCMSR_MAX_START_JOB);
- if(devq == NULL)
- {
- arcmsr_free_resource(pACB);
- bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irqres);
- printf("arcmsr_attach: cam_simq_alloc failure!\n");
+ if(devq == NULL) {
+ arcmsr_free_resource(acb);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
+ printf("arcmsr%d: cam_simq_alloc failure!\n", unit);
return ENXIO;
}
- pACB->psim=cam_sim_alloc(arcmsr_action,arcmsr_poll,"arcmsr",pACB,pACB->pci_unit,1,ARCMSR_MAX_OUTSTANDING_CMD,devq);
- if(pACB->psim == NULL)
- {
- arcmsr_free_resource(pACB);
- bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irqres);
+ acb->psim=cam_sim_alloc(arcmsr_action, arcmsr_poll
+ , "arcmsr", acb, unit, 1, ARCMSR_MAX_OUTSTANDING_CMD, devq);
+ if(acb->psim == NULL) {
+ arcmsr_free_resource(acb);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
cam_simq_free(devq);
- printf("arcmsr_attach: cam_sim_alloc ..................failure!\n");
+ printf("arcmsr%d: cam_sim_alloc failure!\n", unit);
return ENXIO;
}
- if(xpt_bus_register(pACB->psim,0) != CAM_SUCCESS)
- {
- arcmsr_free_resource(pACB);
- bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irqres);
- cam_sim_free(pACB->psim,/*free_devq*/TRUE);
- printf("arcmsr_attach: xpt_bus_register .......................failure!\n");
+ if(xpt_bus_register(acb->psim, 0) != CAM_SUCCESS) {
+ arcmsr_free_resource(acb);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
+ cam_sim_free(acb->psim, /*free_devq*/TRUE);
+ printf("arcmsr%d: xpt_bus_register failure!\n", unit);
return ENXIO;
}
- if(xpt_create_path(&pACB->ppath,/* periph */ NULL,cam_sim_path(pACB->psim),CAM_TARGET_WILDCARD,CAM_LUN_WILDCARD) != CAM_REQ_CMP)
- {
- arcmsr_free_resource(pACB);
- bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irqres);
- xpt_bus_deregister(cam_sim_path(pACB->psim));
- cam_sim_free(pACB->psim,/* free_simq */ TRUE);
- printf("arcmsr_attach: xpt_create_path .....................failure!\n");
+ if(xpt_create_path(&acb->ppath, /* periph */ NULL
+ , cam_sim_path(acb->psim)
+ , CAM_TARGET_WILDCARD
+ , CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+ arcmsr_free_resource(acb);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
+ xpt_bus_deregister(cam_sim_path(acb->psim));
+ cam_sim_free(acb->psim, /* free_simq */ TRUE);
+ printf("arcmsr%d: xpt_create_path failure!\n", unit);
return ENXIO;
}
- /*
+ ARCMSR_LOCK_INIT(&acb->workingQ_done_lock, "arcmsr done working Q lock");
+ ARCMSR_LOCK_INIT(&acb->workingQ_start_lock, "arcmsr start working Q lock");
+ ARCMSR_LOCK_INIT(&acb->qbuffer_lock, "arcmsr Q buffer lock");
+ /*
****************************************************
*/
- xpt_setup_ccb(&csa.ccb_h,pACB->ppath,/*priority*/5);
+ xpt_setup_ccb(&csa.ccb_h, acb->ppath, /*priority*/5);
csa.ccb_h.func_code=XPT_SASYNC_CB;
csa.event_enable=AC_FOUND_DEVICE|AC_LOST_DEVICE;
csa.callback=arcmsr_async;
- csa.callback_arg=pACB->psim;
+ csa.callback_arg=acb->psim;
xpt_action((union ccb *)&csa);
- /* Create the control device. */
- pACB->ioctl_dev=make_dev(&arcmsr_cdevsw, unit, UID_ROOT, GID_WHEEL /* GID_OPERATOR */, S_IRUSR | S_IWUSR, "arcmsr%d", unit);
+ /* Create the control device. */
+ acb->ioctl_dev=make_dev(&arcmsr_cdevsw
+ , unit
+ , UID_ROOT
+ , GID_WHEEL /* GID_OPERATOR */
+ , S_IRUSR | S_IWUSR
+ , "arcmsr%d", unit);
#if __FreeBSD_version < 503000
- pACB->ioctl_dev->si_drv1=pACB;
+ acb->ioctl_dev->si_drv1=acb;
#endif
#if __FreeBSD_version > 500005
- (void)make_dev_alias(pACB->ioctl_dev, "arc%d", unit);
-#endif
-
-#if 0
- #if __FreeBSD_version > 500005
- if(kthread_create(arcmsr_do_thread_works, pACB, &pACB->kthread_proc,0,"arcmsr%d: kthread",pACB->pci_unit))
- {
- device_printf(pACB->pci_dev,"cannot create kernel thread for this host adapetr\n");
- xpt_bus_deregister(cam_sim_path(pACB->psim));
- cam_sim_free(pACB->psim,/* free_simq */ TRUE);
- panic("arcmsr plunge kernel thread fail");
- }
- #else
- if(kthread_create(arcmsr_do_thread_works, pACB, &pACB->kthread_proc,"arcmsr%d: kthread", pACB->pci_unit))
- {
- device_printf(pACB->pci_dev,"cannot create kernel thread for this host adapetr\n");
- xpt_bus_deregister(cam_sim_path(pACB->psim));
- cam_sim_free(pACB->psim,/* free_simq */ TRUE);
- panic("arcmsr plunge kernel thread fail");
- }
- #endif
+ (void)make_dev_alias(acb->ioctl_dev, "arc%d", unit);
#endif
- return 0;
+ return 0;
}
/*
************************************************************************
-**
-**
-**
************************************************************************
*/
-static LONG arcmsr_probe(device_t dev)
+static u_int32_t arcmsr_probe(device_t dev)
{
- ULONG id;
- #if ARCMSR_DEBUG0
- printf("arcmsr_probe................. \n");
- #endif
- switch(id=pci_get_devid(dev))
- {
+ u_int32_t id;
+ static char buf[256];
+ char *type;
+ int raid6 = 1;
+
+ if (pci_get_vendor(dev) != PCI_VENDOR_ID_ARECA) {
+ return (ENXIO);
+ }
+ switch(id=pci_get_devid(dev)) {
case PCIDevVenIDARC1110:
- device_set_desc(dev,"ARECA ARC1110 PCI-X 4 PORTS SATA RAID CONTROLLER \n" ARCMSR_DRIVER_VERSION );
- return 0;
- case PCIDevVenIDARC1120:
- device_set_desc(dev,"ARECA ARC1120 PCI-X 8 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1130:
- device_set_desc(dev,"ARECA ARC1130 PCI-X 12 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1160:
- device_set_desc(dev,"ARECA ARC1160 PCI-X 16 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1210:
- device_set_desc(dev,"ARECA ARC1210 PCI-EXPRESS 4 PORTS SATA RAID CONTROLLER \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1220:
- device_set_desc(dev,"ARECA ARC1220 PCI-EXPRESS 8 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1230:
- device_set_desc(dev,"ARECA ARC1230 PCI-EXPRESS 12 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- case PCIDevVenIDARC1260:
- device_set_desc(dev,"ARECA ARC1260 PCI-EXPRESS 16 PORTS SATA RAID CONTROLLER (RAID6-ENGINE Inside) \n" ARCMSR_DRIVER_VERSION);
- return 0;
- }
- return ENXIO;
+ case PCIDevVenIDARC1210:
+ raid6 = 0;
+ /*FALLTHRU*/
+ case PCIDevVenIDARC1120:
+ case PCIDevVenIDARC1130:
+ case PCIDevVenIDARC1160:
+ case PCIDevVenIDARC1170:
+ case PCIDevVenIDARC1220:
+ case PCIDevVenIDARC1230:
+ case PCIDevVenIDARC1260:
+ case PCIDevVenIDARC1270:
+ case PCIDevVenIDARC1280:
+ type = "SATA";
+ break;
+ case PCIDevVenIDARC1380:
+ case PCIDevVenIDARC1381:
+ case PCIDevVenIDARC1680:
+ case PCIDevVenIDARC1681:
+ type = "SAS";
+ break;
+ default:
+ type = "X-TYPE";
+ break;
+ }
+ sprintf(buf, "Areca %s Host Adapter RAID Controller %s\n", type, raid6 ? "(RAID6 capable)" : "");
+ device_set_desc_copy(dev, buf);
+ return 0;
}
/*
************************************************************************
-**
-**
-**
************************************************************************
*/
-static VOID arcmsr_shutdown(device_t dev)
+static void arcmsr_shutdown(device_t dev)
{
- LONG i,abort_cmd_cnt=0;
- ULONG s,intmask_org;
- PSRB pSRB;
- PACB pACB=device_get_softc(dev);
+ u_int32_t i, poll_count=0;
+ u_int32_t intmask_org;
+ struct CommandControlBlock *srb;
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
- #if ARCMSR_DEBUG0
- printf("arcmsr_shutdown................. \n");
- #endif
- s=splcam();
- /* disable all outbound interrupt */
- intmask_org=CHIP_REG_READ32(&pACB->pmu->outbound_intmask);
- CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask,(intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE));
/* stop adapter background rebuild */
- arcmsr_stop_adapter_bgrb(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_pcidev_disattach: wait 'stop adapter rebuild' timeout.... \n");
- }
- arcmsr_flush_adapter_cache(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_pcidev_disattach: wait 'flush adapter cache' timeout.... \n");
- }
+ arcmsr_stop_adapter_bgrb(acb);
+ arcmsr_flush_adapter_cache(acb);
+ /* disable all outbound interrupt */
+ intmask_org=CHIP_REG_READ32(outbound_intmask);
+ CHIP_REG_WRITE32(outbound_intmask, (intmask_org|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE));
/* abort all outstanding command */
- pACB->acb_flags |= ACB_F_SCSISTOPADAPTER;
- pACB->acb_flags &= ~ACB_F_IOP_INITED;
- if(pACB->srboutstandingcount!=0)
- {
- PSRB pfreesrb;
- #if ARCMSR_DEBUG0
- printf("arcmsr_pcidev_disattach: .....pACB->srboutstandingcount!=0 \n");
- #endif
- /* Q back all outstanding srb into wait exec psrb Q*/
- pfreesrb=pACB->pfreesrb;
- for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++)
- {
- pSRB=&pfreesrb[i];
- if(pSRB->startdone==ARCMSR_SRB_START)
- {
- pSRB->srb_flags|=SRB_FLAG_MASTER_ABORTED;
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- abort_cmd_cnt++;
- }
+ acb->acb_flags |= ACB_F_SCSISTOPADAPTER;
+ acb->acb_flags &= ~ACB_F_IOP_INITED;
+ if(acb->srboutstandingcount!=0) {
+ while((acb->srboutstandingcount!=0) && (poll_count < 256)) {
+ arcmsr_interrupt((void *)acb);
+ UDELAY(25000);
+ poll_count++;
}
- if(abort_cmd_cnt!=0)
- {
- #if ARCMSR_DEBUG0
- printf("arcmsr_pcidev_disattach: .....abort_cmd_cnt!=0 \n");
- #endif
- arcmsr_abort_allcmd(pACB);
- if(arcmsr_wait_msgint_ready(pACB)!=TRUE)
- {
- printf("arcmsr_pcidev_disattach: wait 'abort all outstanding command' timeout.................in \n");
+ if(acb->srboutstandingcount!=0) {
+ arcmsr_abort_allcmd(acb);
+ /*clear all outbound posted Q*/
+ for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++) {
+ CHIP_REG_READ32(outbound_queueport);
}
- }
- atomic_set_int(&pACB->srboutstandingcount,0);
- }
- if(pACB->srbwait2gocount!=0)
- { /*remove first wait2go srb and abort it*/
- for(i=0;i<ARCMSR_MAX_OUTSTANDING_CMD;i++)
- {
- pSRB=pACB->psrbwait2go[i];
- if(pSRB!=NULL)
- {
- pACB->psrbwait2go[i]=NULL;
- atomic_subtract_int(&pACB->srbwait2gocount,1);
- pSRB->pccb->ccb_h.status=CAM_REQ_ABORTED;
- arcmsr_srb_complete(pSRB);
+ for(i=0;i<ARCMSR_MAX_FREESRB_NUM;i++) {
+ srb=acb->psrb_pool[i];
+ if(srb->startdone==ARCMSR_SRB_START) {
+ srb->startdone=ARCMSR_SRB_ABORTED;
+ srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+ arcmsr_srb_complete(srb, 1);
+ }
}
}
}
- splx(s);
-#if 0
- pACB->acb_flags |= ACB_F_STOP_THREAD;
- wakeup(pACB->kthread_proc);/* signal to kernel thread do_dpcQ: "stop thread" */
-#endif
- return;
+ atomic_set_int(&acb->srboutstandingcount, 0);
+ acb->workingsrb_doneindex=0;
+ acb->workingsrb_startindex=0;
+ return;
}
/*
************************************************************************
-**
-**
-**
************************************************************************
*/
-static LONG arcmsr_detach(device_t dev)
+static u_int32_t arcmsr_detach(device_t dev)
{
- PACB pACB=device_get_softc(dev);
+ struct AdapterControlBlock *acb=(struct AdapterControlBlock *)device_get_softc(dev);
arcmsr_shutdown(dev);
- arcmsr_free_resource(pACB);
- bus_release_resource(dev, SYS_RES_MEMORY, PCI_BASE_ADDR0, pACB->sys_res_arcmsr);
- bus_teardown_intr(dev, pACB->irqres, pACB->ih);
- bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irqres);
- xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL);
- xpt_free_path(pACB->ppath);
- xpt_bus_deregister(cam_sim_path(pACB->psim));
- cam_sim_free(pACB->psim, TRUE);
+ arcmsr_free_resource(acb);
+ bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr);
+ bus_teardown_intr(dev, acb->irqres, acb->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, acb->irqres);
+ xpt_async(AC_LOST_DEVICE, acb->ppath, NULL);
+ xpt_free_path(acb->ppath);
+ xpt_bus_deregister(cam_sim_path(acb->psim));
+ cam_sim_free(acb->psim, TRUE);
return (0);
}
-
OpenPOWER on IntegriCloud