PERFORCE change 50770 for review
Scott Long
scottl at FreeBSD.org
Fri Apr 9 23:32:42 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=50770
Change 50770 by scottl at scottl-junior-camlock on 2004/04/09 23:31:42
Don peril-sensitive eyewear and convert probestart() to use
workitems instead of calling xpt_action() directly. The workitem
is pre-allocated in proberegister(). Also add a helper method for
safely queueing work items, and change the locking slightly to not
drop the workitem mutex once the item is safely off the list.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#3 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/cam_probe.c#3 (text+ko) ====
@@ -81,6 +81,17 @@
PERIPHDRIVER_DECLARE(probe, probe_driver);
typedef enum {
+ WORK_EXECUTE_CCB = 0x1,
+} cam_workflags;
+
+struct cam_workitem {
+ TAILQ_ENTRY(cam_workitem) work_links;
+ cam_workflags command;
+ void *data;
+ void (*cbfcnp)(void *);
+};
+
+typedef enum {
PROBE_TUR,
PROBE_INQUIRY,
PROBE_FULL_INQUIRY,
@@ -102,19 +113,9 @@
probe_flags flags;
MD5_CTX context;
u_int8_t digest[16];
+ struct cam_workitem *work;
} probe_softc;
-typedef enum {
- WORK_EXECUTE_CCB = 0x1,
-} cam_workflags;
-
-struct cam_workitem {
- TAILQ_ENTRY(cam_workitem) work_links;
- cam_workflags command;
- void *data;
- void (*cbfcnp)(void *);
-};
-
static struct proc *probe_proc;
static struct mtx probe_workmtx;
static int probe_workflags;
@@ -123,6 +124,15 @@
#define PROBE_FLAG_EXIT 0x1
static void
+probe_queue_work(struct cam_workitem *work)
+{
+ mtx_lock(&probe_workmtx);
+ TAILQ_INSERT_TAIL(&probe_worklist, work, work_links);
+ mtx_unlock(&probe_workmtx);
+ wakeup(&probe_worklist);
+}
+
+static void
probe_work(void *dummy)
{
struct cam_workitem *work;
@@ -135,6 +145,7 @@
continue;
}
TAILQ_REMOVE(&probe_worklist, work, work_links);
+ mtx_unlock(&probe_workmtx);
switch (work->command) {
case WORK_EXECUTE_CCB:
@@ -143,6 +154,11 @@
default:
panic("Unknown CAM work item %d\n", work->command);
}
+
+ if (work->cbfcnp != NULL)
+ work->cbfcnp(work->data);
+
+ mtx_lock(&probe_workmtx);
}
mtx_unlock(&probe_workmtx);
@@ -164,6 +180,7 @@
{
union ccb *request_ccb; /* CCB representing the probe request */
probe_softc *softc;
+ struct cam_workitem *work;
request_ccb = (union ccb *)arg;
if (periph == NULL) {
@@ -184,6 +201,16 @@
"Unable to allocate softc\n");
return(CAM_REQ_CMP_ERR);
}
+
+ work = malloc(sizeof(struct cam_workitem), M_TEMP, M_NOWAIT | M_ZERO);
+ if (work == NULL) {
+ printf("proberegister: Unable to probe new device. "
+ "Unable to allocate softc\n");
+ free(softc, M_TEMP);
+ return (CAM_REQ_CMP_ERR);
+ }
+
+ softc->work = work;
TAILQ_INIT(&softc->request_ccbs);
TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
periph_links.tqe);
@@ -388,7 +415,11 @@
return;
}
}
- xpt_action(start_ccb);
+
+ softc->work->command = WORK_EXECUTE_CCB;
+ softc->work->data = start_ccb;
+ softc->work->cbfcnp = NULL;
+ probe_queue_work(softc->work);
}
static void
@@ -702,6 +733,7 @@
static void
probecleanup(struct cam_periph *periph)
{
+ free(((probe_softc *)(periph->softc))->work, M_TEMP);
free(periph->softc, M_TEMP);
}
More information about the p4-projects
mailing list