mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Add functionality and fix bugs so the driver will work with soon-to-be
released management apps.
1. Implement poll(). This will check for queued aif's so that a
subsequent ioctl call to retrieve the next aif will not block.
2. Don't catch signals when sleeping on a fib sent from userland. This
causes a race and panic due to the pthread context switcher waking
up the tsleep at inopportune times.
3. Fix some whitespace nits.
MFC after: 3 days
This commit is contained in:
parent
2164257702
commit
b3457b5173
7 changed files with 217 additions and 41 deletions
|
|
@ -42,6 +42,8 @@
|
|||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/selinfo.h>
|
||||
|
||||
#include <dev/aac/aac_compat.h>
|
||||
|
||||
|
|
@ -109,6 +111,27 @@ static int aac_dequeue_fib(struct aac_softc *sc, int queue,
|
|||
static int aac_enqueue_response(struct aac_softc *sc, int queue,
|
||||
struct aac_fib *fib);
|
||||
|
||||
/* Falcon/PPC interface */
|
||||
static int aac_fa_get_fwstatus(struct aac_softc *sc);
|
||||
static void aac_fa_qnotify(struct aac_softc *sc, int qbit);
|
||||
static int aac_fa_get_istatus(struct aac_softc *sc);
|
||||
static void aac_fa_clear_istatus(struct aac_softc *sc, int mask);
|
||||
static void aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
|
||||
u_int32_t arg0, u_int32_t arg1,
|
||||
u_int32_t arg2, u_int32_t arg3);
|
||||
static int aac_fa_get_mailboxstatus(struct aac_softc *sc);
|
||||
static void aac_fa_set_interrupts(struct aac_softc *sc, int enable);
|
||||
|
||||
struct aac_interface aac_fa_interface = {
|
||||
aac_fa_get_fwstatus,
|
||||
aac_fa_qnotify,
|
||||
aac_fa_get_istatus,
|
||||
aac_fa_clear_istatus,
|
||||
aac_fa_set_mailbox,
|
||||
aac_fa_get_mailboxstatus,
|
||||
aac_fa_set_interrupts
|
||||
};
|
||||
|
||||
/* StrongARM interface */
|
||||
static int aac_sa_get_fwstatus(struct aac_softc *sc);
|
||||
static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
|
||||
|
|
@ -160,6 +183,7 @@ static char *aac_describe_code(struct aac_code_lookup *table,
|
|||
static d_open_t aac_open;
|
||||
static d_close_t aac_close;
|
||||
static d_ioctl_t aac_ioctl;
|
||||
static d_poll_t aac_poll;
|
||||
static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
|
||||
static void aac_handle_aif(struct aac_softc *sc,
|
||||
struct aac_fib *fib);
|
||||
|
|
@ -176,7 +200,7 @@ static struct cdevsw aac_cdevsw = {
|
|||
noread, /* read */
|
||||
nowrite, /* write */
|
||||
aac_ioctl, /* ioctl */
|
||||
nopoll, /* poll */
|
||||
aac_poll, /* poll */
|
||||
nommap, /* mmap */
|
||||
nostrategy, /* strategy */
|
||||
"aac", /* name */
|
||||
|
|
@ -251,7 +275,12 @@ aac_attach(struct aac_softc *sc)
|
|||
* Register to probe our containers later.
|
||||
*/
|
||||
TAILQ_INIT(&sc->aac_container_tqh);
|
||||
AAC_LOCK_INIT(&sc->aac_container_lock);
|
||||
AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
|
||||
|
||||
/*
|
||||
* Lock for the AIF queue
|
||||
*/
|
||||
AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
|
||||
|
||||
sc->aac_ich.ich_func = aac_startup;
|
||||
sc->aac_ich.ich_arg = sc;
|
||||
|
|
@ -585,14 +614,10 @@ aac_intr(void *arg)
|
|||
|
||||
reason = AAC_GET_ISTATUS(sc);
|
||||
|
||||
/* controller wants to talk to the log? Defer it to the AIF thread */
|
||||
/* controller wants to talk to the log */
|
||||
if (reason & AAC_DB_PRINTF) {
|
||||
AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
|
||||
if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
|
||||
sc->aifflags |= AAC_AIFFLAGS_PENDING;
|
||||
wakeup(sc->aifthread);
|
||||
} else
|
||||
aac_print_printf(sc);
|
||||
aac_print_printf(sc);
|
||||
}
|
||||
|
||||
/* controller has a message for us? */
|
||||
|
|
@ -754,8 +779,6 @@ aac_host_command(struct aac_softc *sc)
|
|||
fib);
|
||||
}
|
||||
}
|
||||
aac_print_printf(sc);
|
||||
|
||||
}
|
||||
sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
|
||||
wakeup(sc->aac_dev);
|
||||
|
|
@ -1063,6 +1086,15 @@ aac_dump_complete(struct aac_softc *sc)
|
|||
|
||||
/*
|
||||
* Submit a command to the controller, return when it completes.
|
||||
* XXX This is very dangerous! If the card has gone out to lunch, we could
|
||||
* be stuck here forever. At the same time, signals are not caught
|
||||
* because there is a risk that a signal could wakeup the tsleep before
|
||||
* the card has a chance to complete the command. The passed in timeout
|
||||
* is ignored for the same reason. Since there is no way to cancel a
|
||||
* command in progress, we should probably create a 'dead' queue where
|
||||
* commands go that have been interrupted/timed-out/etc, that keeps them
|
||||
* out of the free pool. That way, if the card is just slow, it won't
|
||||
* spam the memory of a command that has been recycled.
|
||||
*/
|
||||
static int
|
||||
aac_wait_command(struct aac_command *cm, int timeout)
|
||||
|
|
@ -1077,9 +1109,7 @@ aac_wait_command(struct aac_command *cm, int timeout)
|
|||
aac_startio(cm->cm_sc);
|
||||
s = splbio();
|
||||
while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
|
||||
error = tsleep(cm, PRIBIO | PCATCH, "aacwait", 0);
|
||||
if ((error == ERESTART) || (error == EINTR))
|
||||
break;
|
||||
error = tsleep(cm, PRIBIO, "aacwait", 0);
|
||||
}
|
||||
splx(s);
|
||||
return(error);
|
||||
|
|
@ -1856,6 +1886,17 @@ aac_rx_get_fwstatus(struct aac_softc *sc)
|
|||
return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
|
||||
}
|
||||
|
||||
static int
|
||||
aac_fa_get_fwstatus(struct aac_softc *sc)
|
||||
{
|
||||
int val;
|
||||
|
||||
debug_called(3);
|
||||
|
||||
val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
|
||||
return (val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the controller of a change in a given queue
|
||||
*/
|
||||
|
|
@ -1876,6 +1917,15 @@ aac_rx_qnotify(struct aac_softc *sc, int qbit)
|
|||
AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
|
||||
}
|
||||
|
||||
static void
|
||||
aac_fa_qnotify(struct aac_softc *sc, int qbit)
|
||||
{
|
||||
debug_called(3);
|
||||
|
||||
AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
|
||||
AAC_FA_HACK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the interrupt reason bits
|
||||
*/
|
||||
|
|
@ -1895,6 +1945,17 @@ aac_rx_get_istatus(struct aac_softc *sc)
|
|||
return(AAC_GETREG4(sc, AAC_RX_ODBR));
|
||||
}
|
||||
|
||||
static int
|
||||
aac_fa_get_istatus(struct aac_softc *sc)
|
||||
{
|
||||
int val;
|
||||
|
||||
debug_called(3);
|
||||
|
||||
val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
|
||||
return (val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear some interrupt reason bits
|
||||
*/
|
||||
|
|
@ -1914,6 +1975,15 @@ aac_rx_clear_istatus(struct aac_softc *sc, int mask)
|
|||
AAC_SETREG4(sc, AAC_RX_ODBR, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
aac_fa_clear_istatus(struct aac_softc *sc, int mask)
|
||||
{
|
||||
debug_called(3);
|
||||
|
||||
AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
|
||||
AAC_FA_HACK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate the mailbox and set the command word
|
||||
*/
|
||||
|
|
@ -1943,6 +2013,24 @@ aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
|
|||
AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
|
||||
}
|
||||
|
||||
static void
|
||||
aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
|
||||
u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
|
||||
{
|
||||
debug_called(4);
|
||||
|
||||
AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
|
||||
AAC_FA_HACK(sc);
|
||||
AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
|
||||
AAC_FA_HACK(sc);
|
||||
AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
|
||||
AAC_FA_HACK(sc);
|
||||
AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
|
||||
AAC_FA_HACK(sc);
|
||||
AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
|
||||
AAC_FA_HACK(sc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the immediate command status word
|
||||
*/
|
||||
|
|
@ -1962,6 +2050,17 @@ aac_rx_get_mailboxstatus(struct aac_softc *sc)
|
|||
return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
|
||||
}
|
||||
|
||||
static int
|
||||
aac_fa_get_mailboxstatus(struct aac_softc *sc)
|
||||
{
|
||||
int val;
|
||||
|
||||
debug_called(4);
|
||||
|
||||
val = AAC_GETREG4(sc, AAC_FA_MAILBOX);
|
||||
return (val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set/clear interrupt masks
|
||||
*/
|
||||
|
|
@ -1989,6 +2088,20 @@ aac_rx_set_interrupts(struct aac_softc *sc, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
aac_fa_set_interrupts(struct aac_softc *sc, int enable)
|
||||
{
|
||||
debug(2, "%sable interrupts", enable ? "en" : "dis");
|
||||
|
||||
if (enable) {
|
||||
AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
|
||||
AAC_FA_HACK(sc);
|
||||
} else {
|
||||
AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
|
||||
AAC_FA_HACK(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugging and Diagnostics
|
||||
*/
|
||||
|
|
@ -2133,7 +2246,7 @@ aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
|
|||
break;
|
||||
case FSACTL_OPEN_GET_ADAPTER_FIB:
|
||||
arg = *(caddr_t*)arg;
|
||||
case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
|
||||
case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
|
||||
debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
|
||||
/*
|
||||
* Pass the caller out an AdapterFibContext.
|
||||
|
|
@ -2183,13 +2296,37 @@ aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
|
|||
error = 0;
|
||||
break;
|
||||
default:
|
||||
device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd);
|
||||
debug(1, "unsupported cmd 0x%lx\n", cmd);
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
static int
|
||||
aac_poll(dev_t dev, int poll_events, struct thread *td)
|
||||
{
|
||||
struct aac_softc *sc;
|
||||
int revents;
|
||||
|
||||
sc = dev->si_drv1;
|
||||
revents = 0;
|
||||
|
||||
AAC_LOCK_AQUIRE(&sc->aac_aifq_lock);
|
||||
if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
|
||||
if (sc->aac_aifq_tail != sc->aac_aifq_head)
|
||||
revents |= poll_events & (POLLIN | POLLRDNORM);
|
||||
}
|
||||
AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
|
||||
|
||||
if (revents == 0) {
|
||||
if (poll_events & (POLLIN | POLLRDNORM))
|
||||
selrecord(td, &sc->rcv_select);
|
||||
}
|
||||
|
||||
return (revents);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a FIB supplied from userspace
|
||||
*/
|
||||
|
|
@ -2231,8 +2368,10 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
|
|||
/*
|
||||
* Pass the FIB to the controller, wait for it to complete.
|
||||
*/
|
||||
if ((error = aac_wait_command(cm, 30)) != 0) /* XXX user timeout? */
|
||||
if ((error = aac_wait_command(cm, 30)) != 0) { /* XXX user timeout? */
|
||||
printf("aac_wait_command return %d\n", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the FIB and data back out to the caller.
|
||||
|
|
@ -2264,7 +2403,7 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
|||
struct aac_mntinfo mi;
|
||||
struct aac_mntinforesponse mir;
|
||||
u_int16_t rsize;
|
||||
int next, s, found;
|
||||
int next, found;
|
||||
int added = 0, i = 0;
|
||||
|
||||
debug_called(2);
|
||||
|
|
@ -2385,15 +2524,19 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
|
|||
}
|
||||
|
||||
/* Copy the AIF data to the AIF queue for ioctl retrieval */
|
||||
s = splbio();
|
||||
AAC_LOCK_AQUIRE(&sc->aac_aifq_lock);
|
||||
next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
|
||||
if (next != sc->aac_aifq_tail) {
|
||||
bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
|
||||
sc->aac_aifq_head = next;
|
||||
if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
|
||||
wakeup(sc->aac_aifq);
|
||||
sc->aac_aifq_head = next;
|
||||
|
||||
/* On the off chance that someone is sleeping for an aif... */
|
||||
if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
|
||||
wakeup(sc->aac_aifq);
|
||||
/* Wakeup any poll()ers */
|
||||
selwakeup(&sc->rcv_select);
|
||||
}
|
||||
splx(s);
|
||||
AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -2530,11 +2673,11 @@ aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
|
|||
static int
|
||||
aac_return_aif(struct aac_softc *sc, caddr_t uptr)
|
||||
{
|
||||
int error, s;
|
||||
int error;
|
||||
|
||||
debug_called(2);
|
||||
|
||||
s = splbio();
|
||||
AAC_LOCK_AQUIRE(&sc->aac_aifq_lock);
|
||||
if (sc->aac_aifq_tail == sc->aac_aifq_head) {
|
||||
error = EAGAIN;
|
||||
} else {
|
||||
|
|
@ -2546,7 +2689,7 @@ aac_return_aif(struct aac_softc *sc, caddr_t uptr)
|
|||
sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
|
||||
AAC_AIFQ_LENGTH;
|
||||
}
|
||||
splx(s);
|
||||
AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
|
||||
return(error);
|
||||
}
|
||||
|
||||
|
|
@ -2592,7 +2735,7 @@ aac_query_disk(struct aac_softc *sc, caddr_t uptr)
|
|||
query_disk.Locked =
|
||||
(disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
|
||||
query_disk.Deleted = 0;
|
||||
query_disk.Bus = 0;
|
||||
query_disk.Bus = device_get_unit(sc->aac_dev);
|
||||
query_disk.Target = disk->unit;
|
||||
query_disk.Lun = 0;
|
||||
query_disk.UnMapped = 0;
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
|
|||
fib->Header.StructType);
|
||||
device_printf(sc->aac_dev, " Flags 0x%x\n", fib->Header.Flags);
|
||||
device_printf(sc->aac_dev, " Size %d\n", fib->Header.Size);
|
||||
device_printf(sc->aac_dev, " SenderSize %d\n",xi
|
||||
device_printf(sc->aac_dev, " SenderSize %d\n",
|
||||
fib->Header.SenderSize);
|
||||
device_printf(sc->aac_dev, " SenderAddress 0x%x\n",
|
||||
fib->Header.SenderFibAddress);
|
||||
|
|
@ -225,7 +225,7 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
|
|||
case ContainerCommand:
|
||||
{
|
||||
struct aac_blockread *br;
|
||||
struct aac_blockwrite *br;
|
||||
struct aac_blockwrite *bw;
|
||||
struct aac_sg_table *sg;
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -252,9 +252,9 @@ aac_disk_dump(dev_t dev)
|
|||
for (i = 0; i < dumppages; ++i) {
|
||||
vm_offset_t a = addr + (i * PAGE_SIZE);
|
||||
if (is_physical_memory(a)) {
|
||||
va = pmap_kenter_temporary(trunc_page(a), i);
|
||||
va = pmap_kenter_temporary(trunc_page(a), i);
|
||||
} else {
|
||||
va = pmap_kenter_temporary(trunc_page(0), i);
|
||||
va = pmap_kenter_temporary(trunc_page(0), i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -279,6 +279,10 @@ aac_pci_attach(device_t dev)
|
|||
debug(2, "set hardware up for StrongARM");
|
||||
sc->aac_if = aac_sa_interface;
|
||||
break;
|
||||
case AAC_HWIF_FALCON:
|
||||
debug(2, "set hardware up for Falcon/PPC");
|
||||
sc->aac_if = aac_fa_interface;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ static struct aac_code_lookup aac_cpu_variant[] = {
|
|||
{"i960HX", CPUI960_HX},
|
||||
{"i960RX", CPUI960_RX},
|
||||
{"StrongARM SA110", CPUARM_SA110},
|
||||
{"PowerPC 603e", CPUPPC_603e},
|
||||
{"MPC824x", CPUMPC_824x},
|
||||
{"Unknown StrongARM", CPUARM_xxx},
|
||||
{"Unknown PowerPC", CPUPPC_xxx},
|
||||
{NULL, 0},
|
||||
|
|
@ -111,6 +111,7 @@ static struct aac_code_lookup aac_container_types[] = {
|
|||
{"RAID 00", CT_RAID00},
|
||||
{"Volume of Mirrors", CT_VOLUME_OF_MIRRORS},
|
||||
{"Pseudo RAID 3", CT_PSEUDO_RAID3},
|
||||
{"RAID 50", CT_RAID50},
|
||||
{NULL, 0},
|
||||
{"unknown", 0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ typedef enum {
|
|||
CT_RAID00, /* stripe of stripe */
|
||||
CT_VOLUME_OF_MIRRORS, /* volume of mirror */
|
||||
CT_PSEUDO_RAID3, /* really raid4 */
|
||||
CT_RAID50, /* stripe of raid5 */
|
||||
} AAC_FSAVolType;
|
||||
|
||||
/*
|
||||
|
|
@ -421,7 +422,7 @@ typedef enum {
|
|||
CPUI960_RX,
|
||||
CPUARM_SA110,
|
||||
CPUARM_xxx,
|
||||
CPUPPC_603e,
|
||||
CPUMPC_824x,
|
||||
CPUPPC_xxx,
|
||||
CPUSUBTYPE__last
|
||||
} AAC_CpuSubType;
|
||||
|
|
@ -1059,6 +1060,24 @@ struct aac_close_command {
|
|||
u_int32_t ContainerId;
|
||||
};
|
||||
|
||||
/*
|
||||
* Register set for adapters based on the Falcon bridge and PPC core
|
||||
*/
|
||||
|
||||
#define AAC_FA_DOORBELL0_CLEAR 0x00
|
||||
#define AAC_FA_DOORBELL1_CLEAR 0x02
|
||||
#define AAC_FA_DOORBELL0 0x04
|
||||
#define AAC_FA_DOORBELL1 0x06
|
||||
#define AAC_FA_MASK0_CLEAR 0x08
|
||||
#define AAC_FA_MASK1_CLEAR 0x0a
|
||||
#define AAC_FA_MASK0 0x0c
|
||||
#define AAC_FA_MASK1 0x0e
|
||||
#define AAC_FA_MAILBOX 0x10
|
||||
#define AAC_FA_FWSTATUS 0x2c /* Mailbox 7 */
|
||||
#define AAC_FA_INTSRC 0x900
|
||||
|
||||
#define AAC_FA_HACK(sc) (void)AAC_GETREG4(sc, AAC_FA_INTSRC)
|
||||
|
||||
/*
|
||||
* Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
|
||||
* on the SA110 'StrongArm'.
|
||||
|
|
@ -1072,6 +1091,7 @@ struct aac_close_command {
|
|||
|
||||
#define AAC_SA_DOORBELL1_CLEAR 0x9a /* doorbell 1 (host->adapter) */
|
||||
#define AAC_SA_DOORBELL1_SET 0x9e
|
||||
#define AAC_SA_DOORBELL1 0x9e
|
||||
#define AAC_SA_MASK1_CLEAR 0xa2
|
||||
#define AAC_SA_MASK1_SET 0xa6
|
||||
|
||||
|
|
@ -1114,6 +1134,7 @@ struct aac_close_command {
|
|||
* (ODBR and IDBR respectively for the i960Rx adapters)
|
||||
*/
|
||||
#define AAC_DB_PRINTF (1<<5) /* adapter requests host printf */
|
||||
#define AAC_PRINTF_DONE (1<<5) /* Host completed printf processing */
|
||||
|
||||
/*
|
||||
* Mask containing the interrupt bits we care about. We don't anticipate (or
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ struct aac_interface
|
|||
int (*aif_get_fwstatus)(struct aac_softc *sc);
|
||||
void (*aif_qnotify)(struct aac_softc *sc, int qbit);
|
||||
int (*aif_get_istatus)(struct aac_softc *sc);
|
||||
void (*aif_set_istatus)(struct aac_softc *sc, int mask);
|
||||
void (*aif_clr_istatus)(struct aac_softc *sc, int mask);
|
||||
void (*aif_set_mailbox)(struct aac_softc *sc, u_int32_t command,
|
||||
u_int32_t arg0, u_int32_t arg1,
|
||||
u_int32_t arg2, u_int32_t arg3);
|
||||
|
|
@ -217,11 +217,12 @@ struct aac_interface
|
|||
};
|
||||
extern struct aac_interface aac_rx_interface;
|
||||
extern struct aac_interface aac_sa_interface;
|
||||
extern struct aac_interface aac_fa_interface;
|
||||
|
||||
#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc)))
|
||||
#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit)))
|
||||
#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc)))
|
||||
#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_set_istatus((sc), \
|
||||
#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_clr_istatus((sc), \
|
||||
(mask)))
|
||||
#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
|
||||
((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), \
|
||||
|
|
@ -253,16 +254,18 @@ TAILQ_HEAD(aac_container_tq, aac_container);
|
|||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
typedef struct mtx aac_lock_t;
|
||||
#define AAC_LOCK_INIT(l) mtx_init(l, "AAC Container Mutex", MTX_DEF)
|
||||
#define AAC_LOCK_INIT(l, s) mtx_init(l, s, MTX_DEF)
|
||||
#define AAC_LOCK_AQUIRE(l) mtx_lock(l)
|
||||
#define AAC_LOCK_RELEASE(l) mtx_unlock(l)
|
||||
#else
|
||||
typedef struct simplelock aac_lock_t;
|
||||
#define AAC_LOCK_INIT(l) simple_lock_init(l)
|
||||
#define AAC_LOCK_INIT(l, s) simple_lock_init(l)
|
||||
#define AAC_LOCK_AQUIRE(l) simple_lock(l)
|
||||
#define AAC_LOCK_RELEASE(l) simple_unlock(l)
|
||||
#endif
|
||||
|
||||
#include <sys/selinfo.h>
|
||||
|
||||
/*
|
||||
* Per-controller structure.
|
||||
*/
|
||||
|
|
@ -294,6 +297,7 @@ struct aac_softc
|
|||
int aac_hwif;
|
||||
#define AAC_HWIF_I960RX 0
|
||||
#define AAC_HWIF_STRONGARM 1
|
||||
#define AAC_HWIF_FALCON 2
|
||||
#define AAC_HWIF_UNKNOWN -1
|
||||
bus_dma_tag_t aac_common_dmat; /* common structure
|
||||
* DMA tag */
|
||||
|
|
@ -337,9 +341,11 @@ struct aac_softc
|
|||
|
||||
/* management interface */
|
||||
dev_t aac_dev_t;
|
||||
aac_lock_t aac_aifq_lock;
|
||||
struct aac_aif_command aac_aifq[AAC_AIFQ_LENGTH];
|
||||
int aac_aifq_head;
|
||||
int aac_aifq_tail;
|
||||
struct selinfo rcv_select;
|
||||
struct proc *aifthread;
|
||||
int aifflags;
|
||||
#define AAC_AIFFLAGS_RUNNING (1 << 0)
|
||||
|
|
@ -542,8 +548,8 @@ aac_dequeue_bio(struct aac_softc *sc)
|
|||
|
||||
s = splbio();
|
||||
if ((bp = bioq_first(&sc->aac_bioq)) != NULL) {
|
||||
bioq_remove(&sc->aac_bioq, bp);
|
||||
AACQ_REMOVE(sc, AACQ_BIO);
|
||||
bioq_remove(&sc->aac_bioq, bp);
|
||||
AACQ_REMOVE(sc, AACQ_BIO);
|
||||
}
|
||||
splx(s);
|
||||
return(bp);
|
||||
|
|
@ -552,10 +558,11 @@ aac_dequeue_bio(struct aac_softc *sc)
|
|||
static __inline void
|
||||
aac_print_printf(struct aac_softc *sc)
|
||||
{
|
||||
if (sc->aac_common->ac_printf[0]) {
|
||||
/*
|
||||
* XXX We have the ability to read the length of the printf string
|
||||
* from out of the mailboxes.
|
||||
*/
|
||||
device_printf(sc->aac_dev, "**Monitor** %.*s", AAC_PRINTF_BUFSIZE,
|
||||
sc->aac_common->ac_printf);
|
||||
sc->aac_common->ac_printf[0] = 0;
|
||||
AAC_QNOTIFY(sc, AAC_DB_PRINTF);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue