From owner-svn-src-projects@FreeBSD.ORG Sat Aug 20 19:09:25 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D895A106567C; Sat, 20 Aug 2011 19:09:25 +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 C89E58FC0C; Sat, 20 Aug 2011 19:09:25 +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 p7KJ9PZQ065369; Sat, 20 Aug 2011 19:09:25 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p7KJ9PSK065364; Sat, 20 Aug 2011 19:09:25 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201108201909.p7KJ9PSK065364@svn.freebsd.org> From: Alexander Motin Date: Sat, 20 Aug 2011 19:09:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225047 - projects/zfsd/head/sys/cam/scsi X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Aug 2011 19:09:25 -0000 Author: mav Date: Sat Aug 20 19:09:25 2011 New Revision: 225047 URL: http://svn.freebsd.org/changeset/base/225047 Log: Fetch list of supported diagnostic pages for SES to find whether optional Additional Element Status page is supported. If it's not, do not try to query it. Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.h projects/zfsd/head/sys/cam/scsi/scsi_enc.c projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.h ============================================================================== --- projects/zfsd/head/sys/cam/scsi/scsi_all.h Sat Aug 20 18:45:38 2011 (r225046) +++ projects/zfsd/head/sys/cam/scsi/scsi_all.h Sat Aug 20 19:09:25 2011 (r225047) @@ -992,6 +992,13 @@ struct scsi_vpd_id_scsi_name uint8_t name_string[256]; }; +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; Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc.c ============================================================================== --- projects/zfsd/head/sys/cam/scsi/scsi_enc.c Sat Aug 20 18:45:38 2011 (r225046) +++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c Sat Aug 20 19:09:25 2011 (r225047) @@ -907,7 +907,7 @@ enc_ctor(struct cam_periph *periph, void goto out; } enc->periph = periph; - enc->current_action = ENC_UPDATE_NONE; + enc->current_action = ENC_UPDATE_INVALID; enc->enc_type = enc_type(cgd); sx_init(&enc->enc_cache_lock, "enccache"); Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h ============================================================================== --- projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Sat Aug 20 18:45:38 2011 (r225046) +++ projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Sat Aug 20 19:09:25 2011 (r225047) @@ -154,6 +154,7 @@ struct enc_softc { /* The action on which the state machine is currently working. */ uint32_t current_action; #define ENC_UPDATE_NONE 0x00 +#define ENC_UPDATE_INVALID 0xff /* Callout for auto-updating enclosure status */ struct callout status_updater; Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c ============================================================================== --- projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c Sat Aug 20 18:45:38 2011 (r225046) +++ projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c Sat Aug 20 19:09:25 2011 (r225047) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc /* SES Diagnostic Page Codes */ typedef enum { + SesSupportedPages = 0x0, SesConfigPage = 0x1, SesControlPage = 0x2, SesStatusPage = SesControlPage, @@ -237,6 +238,7 @@ struct ses_iterator { typedef enum { SES_UPDATE_NONE, + SES_UPDATE_PAGES, SES_UPDATE_GETCONFIG, SES_UPDATE_GETSTATUS, SES_UPDATE_GETELMDESCS, @@ -253,6 +255,7 @@ static enc_softc_cleanup_t ses_softc_cle static fsm_fill_handler_t ses_fill_rcv_diag_io; static fsm_fill_handler_t ses_fill_control_request; +static fsm_done_handler_t ses_process_pages; static fsm_done_handler_t ses_process_config; static fsm_done_handler_t ses_process_status; static fsm_done_handler_t ses_process_elm_descs; @@ -265,6 +268,15 @@ struct enc_fsm_state enc_fsm_states[SES_ { { "SES_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL }, { + "SES_UPDATE_PAGES", + SesSupportedPages, + SCSZ, + 60 * 1000, + ses_fill_rcv_diag_io, + ses_process_pages, + enc_error + }, + { "SES_UPDATE_GETCONFIG", SesConfigPage, SCSZ, @@ -352,6 +364,7 @@ typedef struct ses_cache { typedef struct ses_softc { uint32_t ses_flags; #define SES_FLAG_TIMEDCOMP 0x01 +#define SES_FLAG_ADDLSTATUS 0x02 ses_control_reqlist_t ses_requests; ses_control_reqlist_t ses_pending_requests; @@ -1211,6 +1224,55 @@ out: } /** + * \brief Process the list of supported pages and update flags. + * + * \param enc SES device to query. + * \param buf Buffer containing the config page. + * \param xfer_len Length of the config page in the buffer. + * + * \return 0 on success, errno otherwise. + */ +static int +ses_process_pages(enc_softc_t *enc, struct enc_fsm_state *state, + union ccb *ccb, uint8_t **bufp, int xfer_len) +{ + ses_softc_t *ses; + struct scsi_diag_page *page; + int err, i, length; + + CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE, + ("entering %s(%p, %d)\n", __func__, bufp, xfer_len)); + ses = enc->enc_private; + err = -1; + + if (xfer_len < sizeof(*page)) { + ENC_LOG(enc, "Unable to parse Diag Pages List Header\n"); + err = EIO; + goto out; + } + page = (struct scsi_diag_page *)*bufp; + length = scsi_2btoul(page->length); + if (length + offsetof(struct scsi_diag_page, params) > xfer_len) { + ENC_LOG(enc, "Diag Pages List Too Long\n"); + goto out; + } + ENC_DLOG(enc, "%s: page length %d, xfer_len %d\n", + __func__, length, xfer_len); + + err = 0; + for (i = 0; i < length; i++) { + if (page->params[i] == SesAddlElementStatus) { + ses->ses_flags |= SES_FLAG_ADDLSTATUS; + break; + } + } + +out: + ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err); + return (err); +} + +/** * \brief Process the config page and update associated structures. * * \param enc SES device to query. @@ -1411,7 +1473,8 @@ out: else { enc_update_request(enc, SES_UPDATE_GETSTATUS); enc_update_request(enc, SES_UPDATE_GETELMDESCS); - enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); + if (ses->ses_flags & SES_FLAG_ADDLSTATUS) + enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); enc_update_request(enc, SES_PUBLISH_CACHE); } ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err); @@ -1817,6 +1880,7 @@ static int ses_process_elm_descs(enc_softc_t *enc, struct enc_fsm_state *state, union ccb *ccb, uint8_t **bufp, int xfer_len) { + ses_softc_t *ses; struct ses_iterator iter; enc_element_t *element; int err; @@ -1829,6 +1893,7 @@ ses_process_elm_descs(enc_softc_t *enc, const struct ses_page_hdr *phdr; const struct ses_elm_desc_hdr *hdr; + ses = enc->enc_private; enc_cache = &enc->enc_daemon_cache; ses_cache = enc_cache->private; buf = *bufp; @@ -1891,8 +1956,10 @@ ses_process_elm_descs(enc_softc_t *enc, err = 0; out: - if (err == 0) - enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); + if (err == 0) { + if (ses->ses_flags & SES_FLAG_ADDLSTATUS) + enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); + } enc_update_request(enc, SES_PUBLISH_CACHE); return (err); } @@ -2633,8 +2700,12 @@ ses_handle_string(enc_softc_t *enc, enci static void ses_poll_status(enc_softc_t *enc) { + ses_softc_t *ses; + + ses = enc->enc_private; enc_update_request(enc, SES_UPDATE_GETSTATUS); - enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); + if (ses->ses_flags & SES_FLAG_ADDLSTATUS) + enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS); } /** @@ -2710,6 +2781,8 @@ ses_softc_init(enc_softc_t *enc, int doi TAILQ_INIT(&ses_softc->ses_requests); TAILQ_INIT(&ses_softc->ses_pending_requests); + enc_update_request(enc, SES_UPDATE_PAGES); + // XXX: Move this to the FSM so it doesn't hang init if (0) (void) ses_set_timed_completion(enc, 1);