From owner-svn-src-all@FreeBSD.ORG Thu May 24 11:07:39 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C9751106564A; Thu, 24 May 2012 11:07:39 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B16D68FC08; Thu, 24 May 2012 11:07:39 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4OB7dZf034292; Thu, 24 May 2012 11:07:39 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4OB7d41034281; Thu, 24 May 2012 11:07:39 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201205241107.q4OB7d41034281@svn.freebsd.org> From: Alexander Motin Date: Thu, 24 May 2012 11:07:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r235897 - in head: sbin/camcontrol sys/cam sys/cam/ata sys/cam/scsi sys/sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 May 2012 11:07:39 -0000 Author: mav Date: Thu May 24 11:07:39 2012 New Revision: 235897 URL: http://svn.freebsd.org/changeset/base/235897 Log: MFprojects/zfsd: - 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: head/sbin/camcontrol/camcontrol.c head/sys/cam/ata/ata_all.c head/sys/cam/ata/ata_all.h head/sys/cam/ata/ata_da.c head/sys/cam/ata/ata_xpt.c head/sys/cam/cam_ccb.h head/sys/cam/cam_xpt.c head/sys/cam/scsi/scsi_all.c head/sys/cam/scsi/scsi_all.h head/sys/sys/ata.h Modified: head/sbin/camcontrol/camcontrol.c ============================================================================== --- head/sbin/camcontrol/camcontrol.c Thu May 24 11:03:03 2012 (r235896) +++ head/sbin/camcontrol/camcontrol.c Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/ata/ata_all.c ============================================================================== --- head/sys/cam/ata/ata_all.c Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/ata/ata_all.c Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/ata/ata_all.h ============================================================================== --- head/sys/cam/ata/ata_all.h Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/ata/ata_all.h Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/ata/ata_da.c ============================================================================== --- head/sys/cam/ata/ata_da.c Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/ata/ata_da.c Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/ata/ata_xpt.c ============================================================================== --- head/sys/cam/ata/ata_xpt.c Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/ata/ata_xpt.c Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/cam_ccb.h ============================================================================== --- head/sys/cam/cam_ccb.h Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/cam_ccb.h Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/cam_xpt.c Thu May 24 11:07:39 2012 (r235897) @@ -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) { @@ -4859,7 +4862,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: head/sys/cam/scsi/scsi_all.c ============================================================================== --- head/sys/cam/scsi/scsi_all.c Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/scsi/scsi_all.c Thu May 24 11:07:39 2012 (r235897) @@ -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: head/sys/cam/scsi/scsi_all.h ============================================================================== --- head/sys/cam/scsi/scsi_all.h Thu May 24 11:03:03 2012 (r235896) +++ head/sys/cam/scsi/scsi_all.h Thu May 24 11:07:39 2012 (r235897) @@ -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; @@ -2352,6 +2361,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: head/sys/sys/ata.h ============================================================================== --- head/sys/sys/ata.h Thu May 24 11:03:03 2012 (r235896) +++ head/sys/sys/ata.h Thu May 24 11:07:39 2012 (r235897) @@ -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*/