cam: Permit non-pollable sims.

Some CAM sim drivers do not support polling (notably iscsi(4)).
Rather than using a no-op poll routine that always times out requests,
permit a SIM to set a NULL poll callback.  cam_periph_runccb() will
fail polled requests non-pollable sims immediately as if they had
timed out.

Reviewed by:	scottl, mav (earlier version)
Reviewed by:	imp
MFC after:	2 weeks
Sponsored by:	Chelsio
Differential Revision:	https://reviews.freebsd.org/D28453
This commit is contained in:
John Baldwin 2021-02-11 13:49:43 -08:00
parent 6d2a10d96f
commit 447b3557a9
3 changed files with 15 additions and 1 deletions

View file

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_ccb.h>
#include <cam/cam_queue.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_xpt_internal.h>
#include <cam/cam_periph.h>
#include <cam/cam_debug.h>
#include <cam/cam_sim.h>
@ -1247,7 +1248,10 @@ cam_periph_runccb(union ccb *ccb,
* in the do loop below.
*/
if (must_poll) {
timeout = xpt_poll_setup(ccb);
if (cam_sim_pollable(ccb->ccb_h.path->bus->sim))
timeout = xpt_poll_setup(ccb);
else
timeout = 0;
}
if (timeout == 0) {

View file

@ -142,5 +142,11 @@ cam_sim_bus(const struct cam_sim *sim)
return (sim->bus_id);
}
static __inline bool
cam_sim_pollable(const struct cam_sim *sim)
{
return (sim->sim_poll != NULL);
}
#endif /* _KERNEL */
#endif /* _CAM_CAM_SIM_H */

View file

@ -3181,6 +3181,7 @@ xpt_sim_poll(struct cam_sim *sim)
{
struct mtx *mtx;
KASSERT(cam_sim_pollable(sim), ("%s: non-pollable sim", __func__));
mtx = sim->mtx;
if (mtx)
mtx_lock(mtx);
@ -3203,6 +3204,8 @@ xpt_poll_setup(union ccb *start_ccb)
devq = sim->devq;
dev = start_ccb->ccb_h.path->device;
KASSERT(cam_sim_pollable(sim), ("%s: non-pollable sim", __func__));
/*
* Steal an opening so that no other queued requests
* can get it before us while we simulate interrupts.
@ -3226,6 +3229,7 @@ void
xpt_pollwait(union ccb *start_ccb, uint32_t timeout)
{
KASSERT(cam_sim_pollable(sim), ("%s: non-pollable sim", __func__));
while (--timeout > 0) {
xpt_sim_poll(start_ccb->ccb_h.path->bus->sim);
if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)