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"

Reply via email to