summaryrefslogtreecommitdiffstats
path: root/sys/dev/mrsas
diff options
context:
space:
mode:
authorkadesai <kadesai@FreeBSD.org>2014-10-08 09:35:52 +0000
committerkadesai <kadesai@FreeBSD.org>2014-10-08 09:35:52 +0000
commit8e571179129796b94b6cf841974da008a0e3d8e6 (patch)
tree49ef4c8e71a97f8b96623f93034c87bb9650c00d /sys/dev/mrsas
parented192388a8f36ea491570a1c88d3f8fde14f9771 (diff)
downloadFreeBSD-src-8e571179129796b94b6cf841974da008a0e3d8e6.zip
FreeBSD-src-8e571179129796b94b6cf841974da008a0e3d8e6.tar.gz
d_poll() callback function is the entry point for poll system call for the application.
It is meant to notify the applications which will be waiting for some controller events to be occured. Reviewed by: ambrisko MFC after: 2 weeks Sponsored by: AVAGO Technologies
Diffstat (limited to 'sys/dev/mrsas')
-rw-r--r--sys/dev/mrsas/mrsas.c45
-rw-r--r--sys/dev/mrsas/mrsas.h3
2 files changed, 43 insertions, 5 deletions
diff --git a/sys/dev/mrsas/mrsas.c b/sys/dev/mrsas/mrsas.c
index 8e93dcf..c491404 100644
--- a/sys/dev/mrsas/mrsas.c
+++ b/sys/dev/mrsas/mrsas.c
@@ -65,6 +65,7 @@ static d_close_t mrsas_close;
static d_read_t mrsas_read;
static d_write_t mrsas_write;
static d_ioctl_t mrsas_ioctl;
+static d_poll_t mrsas_poll;
static struct mrsas_mgmt_info mrsas_mgmt_info;
static struct mrsas_ident *mrsas_find_ident(device_t);
@@ -184,6 +185,7 @@ static struct cdevsw mrsas_cdevsw = {
.d_read = mrsas_read,
.d_write = mrsas_write,
.d_ioctl = mrsas_ioctl,
+ .d_poll = mrsas_poll,
.d_name = "mrsas",
};
@@ -1265,6 +1267,36 @@ do_ioctl:
}
/**
+ * mrsas_poll: poll entry point for mrsas driver fd
+ *
+ * This function is the entry point for poll from the OS. It waits for
+ * some AEN events to be triggered from the controller and notifies back.
+ */
+static int
+mrsas_poll(struct cdev *dev, int poll_events, struct thread *td)
+{
+ struct mrsas_softc *sc;
+ int revents = 0;
+
+ sc = dev->si_drv1;
+
+ if (poll_events & (POLLIN | POLLRDNORM)) {
+ if (sc->mrsas_aen_triggered) {
+ revents |= poll_events & (POLLIN | POLLRDNORM);
+ }
+ }
+
+ if (revents == 0) {
+ if (poll_events & (POLLIN | POLLRDNORM)) {
+ sc->mrsas_poll_waiting = 1;
+ selrecord(td, &sc->mrsas_select);
+ }
+ }
+
+ return revents;
+}
+
+/**
* mrsas_setup_irq: Set up interrupt.
* input: Adapter instance soft state
*
@@ -3274,13 +3306,12 @@ mrsas_complete_mptmfi_passthru(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd
mtx_unlock(&sc->raidmap_lock);
break;
}
-#if 0 //currently not supporting event handling, so commenting out
if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
- mrsas_poll_wait_aen = 0;
+ sc->mrsas_aen_triggered = 0;
}
-#endif
- /* See if got an event notification */
+
+ /* See if got an event notification */
if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_WAIT)
mrsas_complete_aen(sc, cmd);
else
@@ -3967,7 +3998,11 @@ void mrsas_complete_aen(struct mrsas_softc *sc, struct mrsas_mfi_cmd *cmd)
* Don't signal app if it is just an aborted previously registered aen
*/
if ((!cmd->abort_aen) && (sc->remove_in_progress == 0)) {
- /* TO DO (?) */
+ sc->mrsas_aen_triggered = 1;
+ if (sc->mrsas_poll_waiting) {
+ sc->mrsas_poll_waiting = 0;
+ selwakeup(&sc->mrsas_select);
+ }
}
else
cmd->abort_aen = 0;
diff --git a/sys/dev/mrsas/mrsas.h b/sys/dev/mrsas/mrsas.h
index f9f236b..19f119b 100644
--- a/sys/dev/mrsas/mrsas.h
+++ b/sys/dev/mrsas/mrsas.h
@@ -2491,6 +2491,9 @@ struct mrsas_softc {
struct mtx mfi_cmd_pool_lock; // lock for cmd pool linked list
struct mtx raidmap_lock; // lock for raid map access/update
struct mtx aen_lock; // aen lock
+ struct selinfo mrsas_select; // poll select interface for application
+ uint32_t mrsas_aen_triggered;
+ uint32_t mrsas_poll_waiting;
uint32_t max_fw_cmds; // Max commands from FW
uint32_t max_num_sge; // Max number of SGEs
struct resource *mrsas_irq[MAX_MSIX_COUNT]; // interrupt interface window
OpenPOWER on IntegriCloud