Author: mav Date: Sat Jun 2 08:29:07 2012 New Revision: 236437 URL: http://svn.freebsd.org/changeset/base/236437
Log: Rewrite enabling NCQ for SATA devices in a way more alike to SCSI TCQ. This allows to control it with `camcontrol negotiate adaX -T (en|dis)able` on the fly, same as for SCSI devices. Sponsored by: iXsystems, Inc. Modified: head/sbin/camcontrol/camcontrol.c head/sys/cam/ata/ata_xpt.c head/sys/cam/cam_ccb.h head/sys/cam/cam_xpt.c Modified: head/sbin/camcontrol/camcontrol.c ============================================================================== --- head/sbin/camcontrol/camcontrol.c Sat Jun 2 05:46:04 2012 (r236436) +++ head/sbin/camcontrol/camcontrol.c Sat Jun 2 08:29:07 2012 (r236437) @@ -1025,11 +1025,11 @@ camxferrate(struct cam_device *device) if (sas->valid & CTS_SAS_VALID_SPEED) speed = sas->bitrate; } else if (ccb->cts.transport == XPORT_ATA) { - struct ccb_trans_settings_ata *ata = + struct ccb_trans_settings_pata *pata = &ccb->cts.xport_specific.ata; - if (ata->valid & CTS_ATA_VALID_MODE) - speed = ata_mode2speed(ata->mode); + if (pata->valid & CTS_ATA_VALID_MODE) + speed = ata_mode2speed(pata->mode); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &ccb->cts.xport_specific.sata; @@ -1072,16 +1072,16 @@ camxferrate(struct cam_device *device) fprintf(stdout, ")"); } } else if (ccb->cts.transport == XPORT_ATA) { - struct ccb_trans_settings_ata *ata = + struct ccb_trans_settings_pata *pata = &ccb->cts.xport_specific.ata; printf(" ("); - if (ata->valid & CTS_ATA_VALID_MODE) - printf("%s, ", ata_mode2string(ata->mode)); - if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) - printf("ATAPI %dbytes, ", ata->atapi); - if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf("PIO %dbytes", ata->bytecount); + if (pata->valid & CTS_ATA_VALID_MODE) + printf("%s, ", ata_mode2string(pata->mode)); + if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) + printf("ATAPI %dbytes, ", pata->atapi); + if (pata->valid & CTS_ATA_VALID_BYTECOUNT) + printf("PIO %dbytes", pata->bytecount); printf(")"); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = @@ -2891,21 +2891,45 @@ cts_print(struct cam_device *device, str "enabled" : "disabled"); } } + if (cts->transport == XPORT_FC) { + struct ccb_trans_settings_fc *fc = + &cts->xport_specific.fc; + + if (fc->valid & CTS_FC_VALID_WWNN) + fprintf(stdout, "%sWWNN: 0x%llx", pathstr, + (long long) fc->wwnn); + if (fc->valid & CTS_FC_VALID_WWPN) + fprintf(stdout, "%sWWPN: 0x%llx", pathstr, + (long long) fc->wwpn); + if (fc->valid & CTS_FC_VALID_PORT) + fprintf(stdout, "%sPortID: 0x%x", pathstr, fc->port); + if (fc->valid & CTS_FC_VALID_SPEED) + fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", + pathstr, fc->bitrate / 1000, fc->bitrate % 1000); + } + if (cts->transport == XPORT_SAS) { + struct ccb_trans_settings_sas *sas = + &cts->xport_specific.sas; + + if (sas->valid & CTS_SAS_VALID_SPEED) + fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", + pathstr, sas->bitrate / 1000, sas->bitrate % 1000); + } if (cts->transport == XPORT_ATA) { - struct ccb_trans_settings_ata *ata = + struct ccb_trans_settings_pata *pata = &cts->xport_specific.ata; - if ((ata->valid & CTS_ATA_VALID_MODE) != 0) { + if ((pata->valid & CTS_ATA_VALID_MODE) != 0) { fprintf(stdout, "%sATA mode: %s\n", pathstr, - ata_mode2string(ata->mode)); + ata_mode2string(pata->mode)); } - if ((ata->valid & CTS_ATA_VALID_ATAPI) != 0) { + if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) { fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, - ata->atapi); + pata->atapi); } - if ((ata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { + if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { fprintf(stdout, "%sPIO transaction length: %d\n", - pathstr, ata->bytecount); + pathstr, pata->bytecount); } } if (cts->transport == XPORT_SATA) { @@ -2941,12 +2965,22 @@ cts_print(struct cam_device *device, str sata->caps); } } + if (cts->protocol == PROTO_ATA) { + struct ccb_trans_settings_ata *ata= + &cts->proto_specific.ata; + + if (ata->valid & CTS_ATA_VALID_TQ) { + fprintf(stdout, "%stagged queueing: %s\n", pathstr, + (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ? + "enabled" : "disabled"); + } + } if (cts->protocol == PROTO_SCSI) { struct ccb_trans_settings_scsi *scsi= &cts->proto_specific.scsi; if (scsi->valid & CTS_SCSI_VALID_TQ) { - fprintf(stdout, "%stagged queueing is %s\n", pathstr, + fprintf(stdout, "%stagged queueing: %s\n", pathstr, (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? "enabled" : "disabled"); } @@ -3384,16 +3418,19 @@ ratecontrol(struct cam_device *device, i if (change_settings) { int didsettings = 0; struct ccb_trans_settings_spi *spi = NULL; - struct ccb_trans_settings_ata *ata = NULL; + struct ccb_trans_settings_pata *pata = NULL; struct ccb_trans_settings_sata *sata = NULL; + struct ccb_trans_settings_ata *ata = NULL; struct ccb_trans_settings_scsi *scsi = NULL; if (ccb->cts.transport == XPORT_SPI) spi = &ccb->cts.xport_specific.spi; if (ccb->cts.transport == XPORT_ATA) - ata = &ccb->cts.xport_specific.ata; + pata = &ccb->cts.xport_specific.ata; if (ccb->cts.transport == XPORT_SATA) sata = &ccb->cts.xport_specific.sata; + if (ccb->cts.protocol == PROTO_ATA) + ata = &ccb->cts.proto_specific.ata; if (ccb->cts.protocol == PROTO_SCSI) scsi = &ccb->cts.proto_specific.scsi; ccb->cts.xport_specific.valid = 0; @@ -3406,19 +3443,28 @@ ratecontrol(struct cam_device *device, i spi->flags |= CTS_SPI_FLAGS_DISC_ENB; didsettings++; } - if (scsi && tag_enable != -1) { + if (tag_enable != -1) { if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { warnx("HBA does not support tagged queueing, " "so you cannot modify tag settings"); retval = 1; goto ratecontrol_bailout; } - scsi->valid |= CTS_SCSI_VALID_TQ; - if (tag_enable == 0) - scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; - else - scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - didsettings++; + if (ata) { + ata->valid |= CTS_SCSI_VALID_TQ; + if (tag_enable == 0) + ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; + else + ata->flags |= CTS_ATA_FLAGS_TAG_ENB; + didsettings++; + } else if (scsi) { + scsi->valid |= CTS_SCSI_VALID_TQ; + if (tag_enable == 0) + scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; + else + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + didsettings++; + } } if (spi && offset != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { @@ -3465,6 +3511,12 @@ ratecontrol(struct cam_device *device, i retval = 1; goto ratecontrol_bailout; } + if (!user_settings) { + warnx("You can modify only user rate " + "settings for SATA"); + retval = 1; + goto ratecontrol_bailout; + } sata->revision = ata_speed2revision(syncrate * 100); if (sata->revision < 0) { warnx("Invalid rate %f", syncrate); @@ -3474,16 +3526,22 @@ ratecontrol(struct cam_device *device, i sata->valid |= CTS_SATA_VALID_REVISION; didsettings++; } - if ((ata || sata) && mode != -1) { + if ((pata || sata) && mode != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { warnx("HBA is not capable of changing " "transfer rates"); retval = 1; goto ratecontrol_bailout; } - if (ata) { - ata->mode = mode; - ata->valid |= CTS_ATA_VALID_MODE; + if (!user_settings) { + warnx("You can modify only user mode " + "settings for ATA/SATA"); + retval = 1; + goto ratecontrol_bailout; + } + if (pata) { + pata->mode = mode; + pata->valid |= CTS_ATA_VALID_MODE; } else { sata->mode = mode; sata->valid |= CTS_SATA_VALID_MODE; @@ -3530,11 +3588,6 @@ ratecontrol(struct cam_device *device, i if (didsettings == 0) { goto ratecontrol_bailout; } - if (!user_settings && (ata || sata)) { - warnx("You can modify only user settings for ATA/SATA"); - retval = 1; - goto ratecontrol_bailout; - } ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_SET_TRAN_SETTINGS CCB"); @@ -3566,13 +3619,10 @@ ratecontrol(struct cam_device *device, i fprintf(stderr, "Test Unit Ready failed\n"); goto ratecontrol_bailout; } - /* - * If the user wants things quiet, there's no sense in - * getting the transfer settings, if we're not going - * to print them. - */ - if (quiet != 0) - goto ratecontrol_bailout; + } + if ((change_settings || send_tur) && !quiet && + (ccb->cts.transport == XPORT_ATA || + ccb->cts.transport == XPORT_SATA || send_tur)) { fprintf(stdout, "New parameters:\n"); retval = get_print_cts(device, user_settings, 0, NULL); } Modified: head/sys/cam/ata/ata_xpt.c ============================================================================== --- head/sys/cam/ata/ata_xpt.c Sat Jun 2 05:46:04 2012 (r236436) +++ head/sys/cam/ata/ata_xpt.c Sat Jun 2 08:29:07 2012 (r236437) @@ -165,7 +165,7 @@ static cam_status proberegister(struct c void *arg); static void probeschedule(struct cam_periph *probe_periph); static void probestart(struct cam_periph *periph, union ccb *start_ccb); -//static void proberequestdefaultnegotiation(struct cam_periph *periph); +static void proberequestdefaultnegotiation(struct cam_periph *periph); //static int proberequestbackoff(struct cam_periph *periph, // struct cam_ed *device); static void probedone(struct cam_periph *periph, union ccb *done_ccb); @@ -180,6 +180,7 @@ static struct cam_ed * ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id); static void ata_device_transport(struct cam_path *path); +static void ata_get_transfer_settings(struct ccb_trans_settings *cts); static void ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, int async_update); @@ -662,7 +663,7 @@ negotiate: } xpt_action(start_ccb); } -#if 0 + static void proberequestdefaultnegotiation(struct cam_periph *periph) { @@ -672,14 +673,15 @@ proberequestdefaultnegotiation(struct ca cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); - if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) return; - } + cts.xport_specific.valid = 0; cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); } +#if 0 /* * Backoff Negotiation Code- only pertinent for SPI devices. */ @@ -1044,10 +1046,10 @@ noerror: cts.xport_specific.sata.tags = path->device->maxtags; cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS; xpt_action((union ccb *)&cts); - /* Reconfigure queues for tagged queueing. */ - xpt_start_tags(path); } } + if (changed) + proberequestdefaultnegotiation(periph); ata_device_transport(path); PROBE_SET_ACTION(softc, PROBE_SETMODE); xpt_release_ccb(done_ccb); @@ -1829,10 +1831,7 @@ ata_action(union ccb *start_ccb) break; case XPT_GET_TRAN_SETTINGS: { - struct cam_sim *sim; - - sim = start_ccb->ccb_h.path->bus->sim; - (*(sim->sim_action))(sim, start_ccb); + ata_get_transfer_settings(&start_ccb->cts); break; } case XPT_SCSI_IO: @@ -1871,14 +1870,48 @@ ata_action(union ccb *start_ccb) } static void +ata_get_transfer_settings(struct ccb_trans_settings *cts) +{ + struct ccb_trans_settings_ata *ata; + struct ccb_trans_settings_scsi *scsi; + struct cam_ed *device; + struct cam_sim *sim; + + device = cts->ccb_h.path->device; + sim = cts->ccb_h.path->bus->sim; + (*(sim->sim_action))(sim, (union ccb *)cts); + + if (cts->protocol == PROTO_ATA) { + ata = &cts->proto_specific.ata; + if ((ata->valid & CTS_ATA_VALID_TQ) == 0) { + ata->valid |= CTS_ATA_VALID_TQ; + if (cts->type == CTS_TYPE_USER_SETTINGS || + (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || + (device->inq_flags & SID_CmdQue) != 0) + ata->flags |= CTS_ATA_FLAGS_TAG_ENB; + } + } + if (cts->protocol == PROTO_SCSI) { + scsi = &cts->proto_specific.scsi; + if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) { + scsi->valid |= CTS_SCSI_VALID_TQ; + if (cts->type == CTS_TYPE_USER_SETTINGS || + (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || + (device->inq_flags & SID_CmdQue) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + } + } +} + +static void ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device, int async_update) { struct ccb_pathinq cpi; - struct ccb_trans_settings cur_cts; + struct ccb_trans_settings_ata *ata; struct ccb_trans_settings_scsi *scsi; - struct ccb_trans_settings_scsi *cur_scsi; struct cam_sim *sim; + struct ata_params *ident_data; struct scsi_inquiry_data *inq_data; if (device == NULL) { @@ -1938,95 +1971,63 @@ ata_set_transfer_settings(struct ccb_tra } sim = cts->ccb_h.path->bus->sim; - - /* - * Nothing more of interest to do unless - * this is a device connected via the - * SCSI protocol. - */ - if (cts->protocol != PROTO_SCSI) { - if (async_update == FALSE) - (*(sim->sim_action))(sim, (union ccb *)cts); - return; - } - + ident_data = &device->ident_data; inq_data = &device->inq_data; - scsi = &cts->proto_specific.scsi; + if (cts->protocol == PROTO_ATA) + ata = &cts->proto_specific.ata; + else + ata = NULL; + if (cts->protocol == PROTO_SCSI) + scsi = &cts->proto_specific.scsi; + else + scsi = NULL; xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); - /* SCSI specific sanity checking */ + /* Sanity checking */ if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0 - || (INQ_DATA_TQ_ENABLED(inq_data)) == 0 + || (ata && (ident_data->satacapabilities & ATA_SUPPORT_NCQ) == 0) + || (scsi && (INQ_DATA_TQ_ENABLED(inq_data)) == 0) || (device->queue_flags & SCP_QUEUE_DQUE) != 0 || (device->mintags == 0)) { /* * Can't tag on hardware that doesn't support tags, * doesn't have it enabled, or has broken tag support. */ - scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; - } - - if (async_update == FALSE) { - /* - * Perform sanity checking against what the - * controller and device can do. - */ - xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE); - cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; - cur_cts.type = cts->type; - xpt_action((union ccb *)&cur_cts); - if ((cur_cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { - return; - } - cur_scsi = &cur_cts.proto_specific.scsi; - if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) { - scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; - scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB; - } - if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0) + if (ata) + ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; + if (scsi) scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; } - if (cts->type == CTS_TYPE_CURRENT_SETTINGS - && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) { - int device_tagenb; - - /* - * If we are transitioning from tags to no-tags or - * vice-versa, we need to carefully freeze and restart - * the queue so that we don't overlap tagged and non-tagged - * commands. We also temporarily stop tags if there is - * a change in transfer negotiation settings to allow - * "tag-less" negotiation. - */ - if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 - || (device->inq_flags & SID_CmdQue) != 0) - device_tagenb = TRUE; - else - device_tagenb = FALSE; + /* Start/stop tags use. */ + if (cts->type == CTS_TYPE_CURRENT_SETTINGS && + ((ata && (ata->valid & CTS_ATA_VALID_TQ) != 0) || + (scsi && (scsi->valid & CTS_SCSI_VALID_TQ) != 0))) { + int nowt, newt = 0; + + nowt = ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || + (device->inq_flags & SID_CmdQue) != 0); + if (ata) + newt = (ata->flags & CTS_ATA_FLAGS_TAG_ENB) != 0; + if (scsi) + newt = (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0; - if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0 - && device_tagenb == FALSE) - || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0 - && device_tagenb == TRUE)) { - - if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) { - /* - * Delay change to use tags until after a - * few commands have gone to this device so - * the controller has time to perform transfer - * negotiations without tagged messages getting - * in the way. - */ - device->tag_delay_count = CAM_TAG_DELAY_COUNT; - device->flags |= CAM_DEV_TAG_AFTER_COUNT; - } else { - xpt_stop_tags(cts->ccb_h.path); - } - } + if (newt && !nowt) { + /* + * Delay change to use tags until after a + * few commands have gone to this device so + * the controller has time to perform transfer + * negotiations without tagged messages getting + * in the way. + */ + device->tag_delay_count = CAM_TAG_DELAY_COUNT; + device->flags |= CAM_DEV_TAG_AFTER_COUNT; + } else if (nowt && !newt) + xpt_stop_tags(cts->ccb_h.path); } + if (async_update == FALSE) (*(sim->sim_action))(sim, (union ccb *)cts); } @@ -2116,11 +2117,11 @@ ata_announce_periph(struct cam_periph *p /* Report connection speed */ speed = cpi.base_transfer_speed; if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) { - struct ccb_trans_settings_ata *ata = + struct ccb_trans_settings_pata *pata = &cts.xport_specific.ata; - if (ata->valid & CTS_ATA_VALID_MODE) - speed = ata_mode2speed(ata->mode); + if (pata->valid & CTS_ATA_VALID_MODE) + speed = ata_mode2speed(pata->mode); } if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = @@ -2139,16 +2140,16 @@ ata_announce_periph(struct cam_periph *p periph->unit_number, speed); /* Report additional information about connection */ if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) { - struct ccb_trans_settings_ata *ata = + struct ccb_trans_settings_pata *pata = &cts.xport_specific.ata; printf(" ("); - if (ata->valid & CTS_ATA_VALID_MODE) - printf("%s, ", ata_mode2string(ata->mode)); - if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0) - printf("ATAPI %dbytes, ", ata->atapi); - if (ata->valid & CTS_ATA_VALID_BYTECOUNT) - printf("PIO %dbytes", ata->bytecount); + if (pata->valid & CTS_ATA_VALID_MODE) + printf("%s, ", ata_mode2string(pata->mode)); + if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) + printf("ATAPI %dbytes, ", pata->atapi); + if (pata->valid & CTS_ATA_VALID_BYTECOUNT) + printf("PIO %dbytes", pata->bytecount); printf(")"); } if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) { Modified: head/sys/cam/cam_ccb.h ============================================================================== --- head/sys/cam/cam_ccb.h Sat Jun 2 05:46:04 2012 (r236436) +++ head/sys/cam/cam_ccb.h Sat Jun 2 08:29:07 2012 (r236437) @@ -844,6 +844,14 @@ struct ccb_trans_settings_scsi #define CTS_SCSI_FLAGS_TAG_ENB 0x01 }; +struct ccb_trans_settings_ata +{ + u_int valid; /* Which fields to honor */ +#define CTS_ATA_VALID_TQ 0x01 + u_int flags; +#define CTS_ATA_FLAGS_TAG_ENB 0x01 +}; + struct ccb_trans_settings_spi { u_int valid; /* Which fields to honor */ @@ -878,7 +886,7 @@ struct ccb_trans_settings_sas { u_int32_t bitrate; /* Mbps */ }; -struct ccb_trans_settings_ata { +struct ccb_trans_settings_pata { u_int valid; /* Which fields to honor */ #define CTS_ATA_VALID_MODE 0x01 #define CTS_ATA_VALID_BYTECOUNT 0x02 @@ -924,6 +932,7 @@ struct ccb_trans_settings { u_int transport_version; union { u_int valid; /* Which fields to honor */ + struct ccb_trans_settings_ata ata; struct ccb_trans_settings_scsi scsi; } proto_specific; union { @@ -931,7 +940,7 @@ struct ccb_trans_settings { struct ccb_trans_settings_spi spi; struct ccb_trans_settings_fc fc; struct ccb_trans_settings_sas sas; - struct ccb_trans_settings_ata ata; + struct ccb_trans_settings_pata ata; struct ccb_trans_settings_sata sata; } xport_specific; }; Modified: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Sat Jun 2 05:46:04 2012 (r236436) +++ head/sys/cam/cam_xpt.c Sat Jun 2 08:29:07 2012 (r236437) @@ -5064,10 +5064,16 @@ camisr_runqueue(void *V_queue) ccb_h->path->bus->sim->devq->send_openings++; runq = TRUE; - if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0 - && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ) - || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0 + if (((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0 && (dev->ccbq.dev_active == 0))) { + dev->flags &= ~CAM_DEV_REL_ON_QUEUE_EMPTY; + xpt_release_devq(ccb_h->path, /*count*/1, + /*run_queue*/FALSE); + } + + if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0 + && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)) { + dev->flags &= ~CAM_DEV_REL_ON_COMPLETE; xpt_release_devq(ccb_h->path, /*count*/1, /*run_queue*/FALSE); } _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"