Author: mav
Date: Sat Jun  9 06:43:26 2012
New Revision: 236778
URL: http://svn.freebsd.org/changeset/base/236778

Log:
  MFC r235897:
   - Add low-level support for SATA Enclosure Management Bridge (SEMB)
  devices -- SATA equivalents of the SCSI SES/SAF-TE devices.
   - Add some utility functions for SCSI SAF-TE devices access.
  
  Sponsored by:   iXsystems, Inc.

Modified:
  stable/9/sbin/camcontrol/camcontrol.c
  stable/9/sys/cam/ata/ata_all.c
  stable/9/sys/cam/ata/ata_all.h
  stable/9/sys/cam/ata/ata_da.c
  stable/9/sys/cam/ata/ata_xpt.c
  stable/9/sys/cam/cam_ccb.h
  stable/9/sys/cam/cam_xpt.c
  stable/9/sys/cam/scsi/scsi_all.c
  stable/9/sys/cam/scsi/scsi_all.h
  stable/9/sys/sys/ata.h
Directory Properties:
  stable/9/sbin/camcontrol/   (props changed)
  stable/9/sys/   (props changed)

Modified: stable/9/sbin/camcontrol/camcontrol.c
==============================================================================
--- stable/9/sbin/camcontrol/camcontrol.c       Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sbin/camcontrol/camcontrol.c       Sat Jun  9 06:43:26 2012        
(r236778)
@@ -456,7 +456,7 @@ getdevtree(void)
                        case DEV_MATCH_DEVICE: {
                                struct device_match_result *dev_result;
                                char vendor[16], product[48], revision[16];
-                               char tmpstr[256];
+                               char fw[5], tmpstr[256];
 
                                dev_result =
                                     &ccb.cdm.matches[i].result.device_result;
@@ -495,6 +495,25 @@ getdevtree(void)
                                           sizeof(revision));
                                    sprintf(tmpstr, "<%s %s>", product,
                                        revision);
+                               } else if (dev_result->protocol == PROTO_SEMB) {
+                                       struct sep_identify_data *sid;
+
+                                       sid = (struct sep_identify_data *)
+                                           &dev_result->ident_data;
+                                       cam_strvis(vendor, sid->vendor_id,
+                                           sizeof(sid->vendor_id),
+                                           sizeof(vendor));
+                                       cam_strvis(product, sid->product_id,
+                                           sizeof(sid->product_id),
+                                           sizeof(product));
+                                       cam_strvis(revision, sid->product_rev,
+                                           sizeof(sid->product_rev),
+                                           sizeof(revision));
+                                       cam_strvis(fw, sid->firmware_rev,
+                                           sizeof(sid->firmware_rev),
+                                           sizeof(fw));
+                                       sprintf(tmpstr, "<%s %s %s %s>",
+                                           vendor, product, revision, fw);
                                } else {
                                    sprintf(tmpstr, "<>");
                                }

Modified: stable/9/sys/cam/ata/ata_all.c
==============================================================================
--- stable/9/sys/cam/ata/ata_all.c      Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/ata/ata_all.c      Sat Jun  9 06:43:26 2012        
(r236778)
@@ -108,6 +108,16 @@ ata_op_string(struct ata_cmd *cmd)
        case 0x51: return ("CONFIGURE_STREAM");
        case 0x60: return ("READ_FPDMA_QUEUED");
        case 0x61: return ("WRITE_FPDMA_QUEUED");
+       case 0x67:
+               if (cmd->features == 0xec)
+                       return ("SEP_ATTN IDENTIFY");
+               switch (cmd->lba_low) {
+               case 0x00: return ("SEP_ATTN READ BUFFER");
+               case 0x02: return ("SEP_ATTN RECEIVE DIAGNOSTIC RESULTS");
+               case 0x80: return ("SEP_ATTN WRITE BUFFER");
+               case 0x82: return ("SEP_ATTN SEND DIAGNOSTIC");
+               }
+               return ("SEP_ATTN");
        case 0x70: return ("SEEK");
        case 0x87: return ("CFA_TRANSLATE_SECTOR");
        case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
@@ -286,6 +296,21 @@ ata_print_ident(struct ata_params *ident
        printf(" device\n");
 }
 
+void
+semb_print_ident(struct sep_identify_data *ident_data)
+{
+       char vendor[9], product[17], revision[5], fw[5], in[7], ins[5];
+
+       cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
+       cam_strvis(product, ident_data->product_id, 16, sizeof(product));
+       cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
+       cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
+       cam_strvis(in, ident_data->interface_id, 6, sizeof(in));
+       cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins));
+       printf("<%s %s %s %s> SEMB %s %s device\n",
+           vendor, product, revision, fw, in, ins);
+}
+
 uint32_t
 ata_logical_sector_size(struct ata_params *ident_data)
 {
@@ -695,3 +720,86 @@ ata_static_identify_match(caddr_t identb
        }
         return (-1);
 }
+
+void
+semb_receive_diagnostic_results(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+    uint8_t tag_action, int pcv, uint8_t page_code,
+    uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+       length = min(length, 1020);
+       length = (length + 3) & ~3;
+       cam_fill_ataio(ataio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/CAM_DIR_IN,
+                     tag_action,
+                     data_ptr,
+                     length,
+                     timeout);
+       ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+           pcv ? page_code : 0, 0x02, length / 4);
+}
+
+void
+semb_send_diagnostic(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+    uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+       length = min(length, 1020);
+       length = (length + 3) & ~3;
+       cam_fill_ataio(ataio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+                     tag_action,
+                     data_ptr,
+                     length,
+                     timeout);
+       ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+           length > 0 ? data_ptr[0] : 0, 0x82, length / 4);
+}
+
+void
+semb_read_buffer(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+    uint8_t tag_action, uint8_t page_code,
+    uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+       length = min(length, 1020);
+       length = (length + 3) & ~3;
+       cam_fill_ataio(ataio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/CAM_DIR_IN,
+                     tag_action,
+                     data_ptr,
+                     length,
+                     timeout);
+       ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+           page_code, 0x00, length / 4);
+}
+
+void
+semb_write_buffer(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+    uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+       length = min(length, 1020);
+       length = (length + 3) & ~3;
+       cam_fill_ataio(ataio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+                     tag_action,
+                     data_ptr,
+                     length,
+                     timeout);
+       ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+           length > 0 ? data_ptr[0] : 0, 0x80, length / 4);
+}
+

Modified: stable/9/sys/cam/ata/ata_all.h
==============================================================================
--- stable/9/sys/cam/ata/ata_all.h      Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/ata/ata_all.h      Sat Jun  9 06:43:26 2012        
(r236778)
@@ -83,6 +83,20 @@ struct ata_res {
        u_int8_t        sector_count_exp;
 };
 
+struct sep_identify_data {
+       uint8_t         length;         /* Enclosure descriptor length */
+       uint8_t         subenc_id;      /* Sub-enclosure identifier */
+       uint8_t         logical_id[8];  /* Enclosure logical identifier (WWN) */
+       uint8_t         vendor_id[8];   /* Vendor identification string */
+       uint8_t         product_id[16]; /* Product identification string */
+       uint8_t         product_rev[4]; /* Product revision string */
+       uint8_t         channel_id;     /* Channel identifier */
+       uint8_t         firmware_rev[4];/* Firmware revision */
+       uint8_t         interface_id[6];/* Interface spec ("S-E-S "/"SAF-TE")*/
+       uint8_t         interface_rev[4];/* Interface spec revision */
+       uint8_t         vend_spec[11];  /* Vendor specific information */
+};
+
 int    ata_version(int ver);
 
 char * ata_op_string(struct ata_cmd *cmd);
@@ -126,4 +140,26 @@ int        ata_speed2revision(u_int speed);
 int    ata_identify_match(caddr_t identbuffer, caddr_t table_entry);
 int    ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry);
 
+void   semb_print_ident(struct sep_identify_data *ident_data);
+
+void semb_receive_diagnostic_results(struct ccb_ataio *ataio,
+       u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+       uint8_t tag_action, int pcv, uint8_t page_code,
+       uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_send_diagnostic(struct ccb_ataio *ataio,
+       u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+       uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+       uint32_t timeout);
+
+void semb_read_buffer(struct ccb_ataio *ataio,
+       u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+       uint8_t tag_action, uint8_t page_code,
+       uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_write_buffer(struct ccb_ataio *ataio,
+       u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+       uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+       uint32_t timeout);
+
 #endif

Modified: stable/9/sys/cam/ata/ata_da.c
==============================================================================
--- stable/9/sys/cam/ata/ata_da.c       Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/ata/ata_da.c       Sat Jun  9 06:43:26 2012        
(r236778)
@@ -776,6 +776,20 @@ adaasync(void *callback_arg, u_int32_t c
                                "due to status 0x%x\n", status);
                break;
        }
+       case AC_ADVINFO_CHANGED:
+       {
+               uintptr_t buftype;
+
+               buftype = (uintptr_t)arg;
+               if (buftype == CDAI_TYPE_PHYS_PATH) {
+                       struct ada_softc *softc;
+
+                       softc = periph->softc;
+                       disk_attr_changed(softc->disk, "GEOM::physpath",
+                                         M_NOWAIT);
+               }
+               break;
+       }
        case AC_SENT_BDR:
        case AC_BUS_RESET:
        {
@@ -1088,8 +1102,8 @@ adaregister(struct cam_periph *periph, v
         * them and the only alternative would be to
         * not attach the device on failure.
         */
-       xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
-                          adaasync, periph, periph->path);
+       xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
+           AC_ADVINFO_CHANGED, adaasync, periph, periph->path);
 
        /*
         * Schedule a periodic event to occasionally send an

Modified: stable/9/sys/cam/ata/ata_xpt.c
==============================================================================
--- stable/9/sys/cam/ata/ata_xpt.c      Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/ata/ata_xpt.c      Sat Jun  9 06:43:26 2012        
(r236778)
@@ -93,6 +93,8 @@ typedef enum {
        PROBE_FULL_INQUIRY,
        PROBE_PM_PID,
        PROBE_PM_PRV,
+       PROBE_IDENTIFY_SES,
+       PROBE_IDENTIFY_SAFTE,
        PROBE_INVALID
 } probe_action;
 
@@ -110,6 +112,8 @@ static char *probe_action_text[] = {
        "PROBE_FULL_INQUIRY",
        "PROBE_PM_PID",
        "PROBE_PM_PRV",
+       "PROBE_IDENTIFY_SES",
+       "PROBE_IDENTIFY_SAFTE",
        "PROBE_INVALID"
 };
 
@@ -266,7 +270,8 @@ probeschedule(struct cam_periph *periph)
        ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 
        if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) ||
-           periph->path->device->protocol == PROTO_SATAPM)
+           periph->path->device->protocol == PROTO_SATAPM ||
+           periph->path->device->protocol == PROTO_SEMB)
                PROBE_SET_ACTION(softc, PROBE_RESET);
        else
                PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
@@ -300,7 +305,8 @@ probestart(struct cam_periph *periph, un
        if (softc->restart) {
                softc->restart = 0;
                if ((path->device->flags & CAM_DEV_UNCONFIGURED) ||
-                   path->device->protocol == PROTO_SATAPM)
+                   path->device->protocol == PROTO_SATAPM ||
+                   path->device->protocol == PROTO_SEMB)
                        softc->action = PROBE_RESET;
                else
                        softc->action = PROBE_IDENTIFY;
@@ -622,6 +628,30 @@ negotiate:
                      10 * 1000);
                ata_pm_read_cmd(ataio, 1, 15);
                break;
+       case PROBE_IDENTIFY_SES:
+               cam_fill_ataio(ataio,
+                     1,
+                     probedone,
+                     /*flags*/CAM_DIR_IN,
+                     0,
+                     /*data_ptr*/(u_int8_t *)&softc->ident_data,
+                     /*dxfer_len*/sizeof(softc->ident_data),
+                     30 * 1000);
+               ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x02,
+                   sizeof(softc->ident_data) / 4);
+               break;
+       case PROBE_IDENTIFY_SAFTE:
+               cam_fill_ataio(ataio,
+                     1,
+                     probedone,
+                     /*flags*/CAM_DIR_IN,
+                     0,
+                     /*data_ptr*/(u_int8_t *)&softc->ident_data,
+                     /*dxfer_len*/sizeof(softc->ident_data),
+                     30 * 1000);
+               ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x00,
+                   sizeof(softc->ident_data) / 4);
+               break;
        case PROBE_INVALID:
                CAM_DEBUG(path, CAM_DEBUG_INFO,
                    ("probestart: invalid action state\n"));
@@ -758,12 +788,16 @@ probedone(struct cam_periph *periph, uni
 {
        struct ccb_trans_settings cts;
        struct ata_params *ident_buf;
+       struct scsi_inquiry_data *inq_buf;
        probe_softc *softc;
        struct cam_path *path;
        cam_status status;
        u_int32_t  priority;
        u_int caps;
-       int found = 1;
+       int changed = 1, found = 1;
+       static const uint8_t fake_device_id_hdr[8] =
+           {0, SVPD_DEVICE_ID, 0, 12,
+            SVPD_ID_CODESET_BINARY, SVPD_ID_TYPE_NAA, 0, 8};
 
        CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
 
@@ -771,6 +805,7 @@ probedone(struct cam_periph *periph, uni
        path = done_ccb->ccb_h.path;
        priority = done_ccb->ccb_h.pinfo.priority;
        ident_buf = &path->device->ident_data;
+       inq_buf = &path->device->inq_data;
 
        if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
                if (softc->restart) {
@@ -819,6 +854,18 @@ probedone(struct cam_periph *periph, uni
                } else if (softc->action == PROBE_SETDMAAA &&
                    status == CAM_ATA_STATUS_ERROR) {
                        goto noerror;
+
+               /*
+                * SES and SAF-TE SEPs have different IDENTIFY commands,
+                * but SATA specification doesn't tell how to identify them.
+                * Until better way found, just try another if first fail.
+                */
+               } else if (softc->action == PROBE_IDENTIFY_SES &&
+                   status == CAM_ATA_STATUS_ERROR) {
+                       PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE);
+                       xpt_release_ccb(done_ccb);
+                       xpt_schedule(periph, priority);
+                       return;
                }
 
                /*
@@ -862,6 +909,10 @@ noerror:
                        xpt_action((union ccb *)&cts);
                        path->device->protocol = PROTO_SATAPM;
                        PROBE_SET_ACTION(softc, PROBE_PM_PID);
+               } else if (sign == 0xc33c &&
+                   done_ccb->ccb_h.target_id != 15) {
+                       path->device->protocol = PROTO_SEMB;
+                       PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SES);
                } else if (sign == 0xeb14 &&
                    done_ccb->ccb_h.target_id != 15) {
                        path->device->protocol = PROTO_SCSI;
@@ -881,7 +932,6 @@ noerror:
        {
                struct ccb_pathinq cpi;
                int16_t *ptr;
-               int changed = 1;
 
                ident_buf = &softc->ident_data;
                for (ptr = (int16_t *)ident_buf;
@@ -936,6 +986,11 @@ noerror:
                                path->device->serial_num = NULL;
                                path->device->serial_num_len = 0;
                        }
+                       if (path->device->device_id != NULL) {
+                               free(path->device->device_id, M_CAMXPT);
+                               path->device->device_id = NULL;
+                               path->device->device_id_len = 0;
+                       }
                        path->device->serial_num =
                                (u_int8_t *)malloc((sizeof(ident_buf->serial) + 
1),
                                           M_CAMXPT, M_NOWAIT);
@@ -948,6 +1003,18 @@ noerror:
                                path->device->serial_num_len =
                                    strlen(path->device->serial_num);
                        }
+                       if (ident_buf->enabled.extension &
+                           ATA_SUPPORT_64BITWWN) {
+                               path->device->device_id =
+                                   malloc(16, M_CAMXPT, M_NOWAIT);
+                               if (path->device->device_id != NULL) {
+                                       path->device->device_id_len = 16;
+                                       bcopy(&fake_device_id_hdr,
+                                           path->device->device_id, 8);
+                                       bcopy(ident_buf->wwn,
+                                           path->device->device_id + 8, 8);
+                               }
+                       }
 
                        path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
                }
@@ -1092,11 +1159,9 @@ notsata:
        case PROBE_INQUIRY:
        case PROBE_FULL_INQUIRY:
        {
-               struct scsi_inquiry_data *inq_buf;
                u_int8_t periph_qual, len;
 
                path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
-               inq_buf = &path->device->inq_data;
 
                periph_qual = SID_QUAL(inq_buf);
 
@@ -1200,6 +1265,48 @@ notsata:
                        xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb);
                }
                break;
+       case PROBE_IDENTIFY_SES:
+       case PROBE_IDENTIFY_SAFTE:
+               if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
+                       /* Check that it is the same device. */
+                       if (bcmp(&softc->ident_data, ident_buf, 53)) {
+                               /* Device changed. */
+                               xpt_async(AC_LOST_DEVICE, path, NULL);
+                       } else {
+                               bcopy(&softc->ident_data, ident_buf, 
sizeof(struct ata_params));
+                               changed = 0;
+                       }
+               }
+               if (changed) {
+                       bcopy(&softc->ident_data, ident_buf, sizeof(struct 
ata_params));
+                       /* Clean up from previous instance of this device */
+                       if (path->device->device_id != NULL) {
+                               free(path->device->device_id, M_CAMXPT);
+                               path->device->device_id = NULL;
+                               path->device->device_id_len = 0;
+                       }
+                       path->device->device_id =
+                           malloc(16, M_CAMXPT, M_NOWAIT);
+                       if (path->device->device_id != NULL) {
+                               path->device->device_id_len = 16;
+                               bcopy(&fake_device_id_hdr,
+                                   path->device->device_id, 8);
+                               bcopy(((uint8_t*)ident_buf) + 2,
+                                   path->device->device_id + 8, 8);
+                       }
+
+                       path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
+               }
+
+               if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
+                       path->device->flags &= ~CAM_DEV_UNCONFIGURED;
+                       xpt_acquire_device(path->device);
+                       done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
+                       xpt_action(done_ccb);
+                       xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
+                           done_ccb);
+               }
+               break;
        case PROBE_INVALID:
                CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
                    ("probedone: invalid action state\n"));
@@ -1624,10 +1731,20 @@ ata_dev_advinfo(union ccb *start_ccb)
        device = start_ccb->ccb_h.path->device;
        cdai = &start_ccb->cdai;
        switch(cdai->buftype) {
-       case CDAI_TYPE_SERIAL_NUM:
+       case CDAI_TYPE_SCSI_DEVID:
                if (cdai->flags & CDAI_FLAG_STORE)
+                       return;
+               cdai->provsiz = device->device_id_len;
+               if (device->device_id_len == 0)
                        break;
-               start_ccb->ccb_h.status = CAM_REQ_CMP;
+               amt = device->device_id_len;
+               if (cdai->provsiz > cdai->bufsiz)
+                       amt = cdai->bufsiz;
+               memcpy(cdai->buf, device->device_id, amt);
+               break;
+       case CDAI_TYPE_SERIAL_NUM:
+               if (cdai->flags & CDAI_FLAG_STORE)
+                       return;
                cdai->provsiz = device->serial_num_len;
                if (device->serial_num_len == 0)
                        break;
@@ -1636,8 +1753,45 @@ ata_dev_advinfo(union ccb *start_ccb)
                        amt = cdai->bufsiz;
                memcpy(cdai->buf, device->serial_num, amt);
                break;
-       default:
+       case CDAI_TYPE_PHYS_PATH:
+               if (cdai->flags & CDAI_FLAG_STORE) {
+                       if (device->physpath != NULL)
+                               free(device->physpath, M_CAMXPT);
+                       device->physpath_len = cdai->bufsiz;
+                       /* Clear existing buffer if zero length */
+                       if (cdai->bufsiz == 0)
+                               break;
+                       device->physpath = malloc(cdai->bufsiz, M_CAMXPT, 
M_NOWAIT);
+                       if (device->physpath == NULL) {
+                               start_ccb->ccb_h.status = CAM_REQ_ABORTED;
+                               return;
+                       }
+                       memcpy(device->physpath, cdai->buf, cdai->bufsiz);
+               } else {
+                       cdai->provsiz = device->physpath_len;
+                       if (device->physpath_len == 0)
+                               break;
+                       amt = device->physpath_len;
+                       if (cdai->provsiz > cdai->bufsiz)
+                               amt = cdai->bufsiz;
+                       memcpy(cdai->buf, device->physpath, amt);
+               }
                break;
+       default:
+               return;
+       }
+       start_ccb->ccb_h.status = CAM_REQ_CMP;
+
+       if (cdai->flags & CDAI_FLAG_STORE) {
+               int owned;
+
+               owned = mtx_owned(start_ccb->ccb_h.path->bus->sim->mtx);
+               if (owned == 0)
+                       mtx_lock(start_ccb->ccb_h.path->bus->sim->mtx);
+               xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path,
+                         (void *)(uintptr_t)cdai->buftype);
+               if (owned == 0)
+                       mtx_unlock(start_ccb->ccb_h.path->bus->sim->mtx);
        }
 }
 

Modified: stable/9/sys/cam/cam_ccb.h
==============================================================================
--- stable/9/sys/cam/cam_ccb.h  Sat Jun  9 03:34:34 2012        (r236777)
+++ stable/9/sys/cam/cam_ccb.h  Sat Jun  9 06:43:26 2012        (r236778)
@@ -242,6 +242,7 @@ typedef enum {
        PROTO_ATA,      /* AT Attachment */
        PROTO_ATAPI,    /* AT Attachment Packetized Interface */
        PROTO_SATAPM,   /* SATA Port Multiplier */
+       PROTO_SEMB,     /* SATA Enclosure Management Bridge */
 } cam_proto;
 
 typedef enum {

Modified: stable/9/sys/cam/cam_xpt.c
==============================================================================
--- stable/9/sys/cam/cam_xpt.c  Sat Jun  9 03:34:34 2012        (r236777)
+++ stable/9/sys/cam/cam_xpt.c  Sat Jun  9 06:43:26 2012        (r236778)
@@ -1080,6 +1080,9 @@ xpt_announce_periph(struct cam_periph *p
        else if (path->device->protocol == PROTO_ATA ||
            path->device->protocol == PROTO_SATAPM)
                ata_print_ident(&path->device->ident_data);
+       else if (path->device->protocol == PROTO_SEMB)
+               semb_print_ident(
+                   (struct sep_identify_data *)&path->device->ident_data);
        else
                printf("Unknown protocol device\n");
        if (bootverbose && path->device->serial_num_len > 0) {
@@ -4848,7 +4851,8 @@ xpt_finishconfig_task(void *context, int
         * attached.  For any devices like that, announce the
         * passthrough driver so the user will see something.
         */
-       xpt_for_all_devices(xptpassannouncefunc, NULL);
+       if (!bootverbose)
+               xpt_for_all_devices(xptpassannouncefunc, NULL);
 
        /* Release our hook so that the boot can continue. */
        config_intrhook_disestablish(xsoftc.xpt_config_hook);

Modified: stable/9/sys/cam/scsi/scsi_all.c
==============================================================================
--- stable/9/sys/cam/scsi/scsi_all.c    Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/scsi/scsi_all.c    Sat Jun  9 06:43:26 2012        
(r236778)
@@ -5740,6 +5740,66 @@ scsi_send_diagnostic(struct ccb_scsiio *
                      timeout);
 }
 
+void
+scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+                       void (*cbfcnp)(struct cam_periph *, union ccb*),
+                       uint8_t tag_action, int mode,
+                       uint8_t buffer_id, u_int32_t offset,
+                       uint8_t *data_ptr, uint32_t allocation_length,
+                       uint8_t sense_len, uint32_t timeout)
+{
+       struct scsi_read_buffer *scsi_cmd;
+
+       scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes;
+       memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+       scsi_cmd->opcode = READ_BUFFER;
+       scsi_cmd->byte2 = mode;
+       scsi_cmd->buffer_id = buffer_id;
+       scsi_ulto3b(offset, scsi_cmd->offset);
+       scsi_ulto3b(allocation_length, scsi_cmd->length);
+
+       cam_fill_csio(csio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/CAM_DIR_IN,
+                     tag_action,
+                     data_ptr,
+                     allocation_length,
+                     sense_len,
+                     sizeof(*scsi_cmd),
+                     timeout);
+}
+
+void
+scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+                       void (*cbfcnp)(struct cam_periph *, union ccb *),
+                       uint8_t tag_action, int mode,
+                       uint8_t buffer_id, u_int32_t offset,
+                       uint8_t *data_ptr, uint32_t param_list_length,
+                       uint8_t sense_len, uint32_t timeout)
+{
+       struct scsi_write_buffer *scsi_cmd;
+
+       scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes;
+       memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+       scsi_cmd->opcode = WRITE_BUFFER;
+       scsi_cmd->byte2 = mode;
+       scsi_cmd->buffer_id = buffer_id;
+       scsi_ulto3b(offset, scsi_cmd->offset);
+       scsi_ulto3b(param_list_length, scsi_cmd->length);
+
+       cam_fill_csio(csio,
+                     retries,
+                     cbfcnp,
+                     /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE,
+                     tag_action,
+                     data_ptr,
+                     param_list_length,
+                     sense_len,
+                     sizeof(*scsi_cmd),
+                     timeout);
+}
+
 void 
 scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
                void (*cbfcnp)(struct cam_periph *, union ccb *),

Modified: stable/9/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/9/sys/cam/scsi/scsi_all.h    Sat Jun  9 03:34:34 2012        
(r236777)
+++ stable/9/sys/cam/scsi/scsi_all.h    Sat Jun  9 06:43:26 2012        
(r236778)
@@ -1267,6 +1267,8 @@ struct scsi_vpd_id_descriptor
 #define        SCSI_PROTO_RDMA         0x04
 #define SCSI_PROTO_iSCSI       0x05
 #define        SCSI_PROTO_SAS          0x06
+#define        SCSI_PROTO_ADT          0x07
+#define        SCSI_PROTO_ATA          0x08
 #define        SVPD_ID_PROTO_SHIFT     4
 #define        SVPD_ID_CODESET_BINARY  0x01
 #define        SVPD_ID_CODESET_ASCII   0x02
@@ -1400,6 +1402,13 @@ struct scsi_service_action_in
        uint8_t control;
 };
 
+struct scsi_diag_page {
+       uint8_t page_code;
+       uint8_t page_specific_flags;
+       uint8_t length[2];
+       uint8_t params[0];
+};
+
 struct scsi_read_capacity
 {
        u_int8_t opcode;
@@ -2342,6 +2351,20 @@ void scsi_send_diagnostic(struct ccb_scs
                          uint16_t param_list_length, uint8_t sense_len,
                          uint32_t timeout);
 
+void scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+                       void (*cbfcnp)(struct cam_periph *, union ccb*),
+                       uint8_t tag_action, int mode,
+                       uint8_t buffer_id, u_int32_t offset,
+                       uint8_t *data_ptr, uint32_t allocation_length,
+                       uint8_t sense_len, uint32_t timeout);
+
+void scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+                       void (*cbfcnp)(struct cam_periph *, union ccb *),
+                       uint8_t tag_action, int mode,
+                       uint8_t buffer_id, u_int32_t offset,
+                       uint8_t *data_ptr, uint32_t param_list_length,
+                       uint8_t sense_len, uint32_t timeout);
+
 void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
                     void (*cbfcnp)(struct cam_periph *, union ccb *),
                     u_int8_t tag_action, int readop, u_int8_t byte2, 

Modified: stable/9/sys/sys/ata.h
==============================================================================
--- stable/9/sys/sys/ata.h      Sat Jun  9 03:34:34 2012        (r236777)
+++ stable/9/sys/sys/ata.h      Sat Jun  9 06:43:26 2012        (r236778)
@@ -318,6 +318,7 @@ struct ata_params {
 #define ATA_READ_VERIFY48               0x42
 #define ATA_READ_FPDMA_QUEUED           0x60    /* read DMA NCQ */
 #define ATA_WRITE_FPDMA_QUEUED          0x61    /* write DMA NCQ */
+#define ATA_SEP_ATTN                    0x67    /* SEP request */
 #define ATA_SEEK                        0x70    /* seek */
 #define ATA_PACKET_CMD                  0xa0    /* packet command */
 #define ATA_ATAPI_IDENTIFY              0xa1    /* get ATAPI params*/
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to