When the timeout for an HCB expires that request should be aborted, just like with an
XPT_ABORT request. The only difference is that the returned status of aborted request
should be CAM_CMD_TIMEOUT instead of CAM_REQ_ABORTED (that is why implementation of the
abort better be done as a function). But there is one more possible problem: what if the
abort request itself will get stuck? In this case the SCSI bus should be reset, just like
with an XPT_RESET_BUS request (and the idea about implementing it as a function called
from both places applies here too). Also we should reset the whole SCSI bus if a device
reset request got stuck. So after all the timeout function would look like:
static void
xxx_timeout(void *arg)
{
struct xxx_hcb *hcb = (struct xxx_hcb *)arg;
struct xxx_softc *softc;
struct ccb_hdr *ccb_h;
softc = hcb->softc;
ccb_h = &hcb->ccb->ccb_h;
if(hcb->flags & HCB_BEING_ABORTED
|| ccb_h->func_code == XPT_RESET_DEV) {
xxx_reset_bus(softc);
} else {
xxx_abort_ccb(hcb->ccb, CAM_CMD_TIMEOUT);
}
}
When we abort a request all the other disconnected requests to the same target/LUN get
aborted too. So there appears a question, should we return them with status
CAM_REQ_ABORTED or CAM_CMD_TIMEOUT? The current drivers use CAM_CMD_TIMEOUT. This seems
logical because if one request got timed out then probably something really bad is
happening to the device, so if they would not be disturbed they would time out by
themselves.