From owner-svn-src-stable@FreeBSD.ORG Sat Sep 14 09:01:43 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 7D3B1688; Sat, 14 Sep 2013 09:01:43 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 698A92AAC; Sat, 14 Sep 2013 09:01:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r8E91hbG091607; Sat, 14 Sep 2013 09:01:43 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r8E91gtt091603; Sat, 14 Sep 2013 09:01:42 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201309140901.r8E91gtt091603@svn.freebsd.org> From: Alexander Motin Date: Sat, 14 Sep 2013 09:01:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r255544 - in stable/9/sys/cam: . scsi X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Sep 2013 09:01:43 -0000 Author: mav Date: Sat Sep 14 09:01:42 2013 New Revision: 255544 URL: http://svnweb.freebsd.org/changeset/base/255544 Log: MFC r253322, r253370: Improve handling of 0x3F/0x0E "Reported LUNs data has changed" and 0x25/0x00 "Logical unit not supported" errors. First initiates specific target rescan, second -- destroys specific LUN. That allows to automatically detect changes in list of device LUNs. This mechanism doesn't work when target is completely idle, but probably that is all what can be done without active polling. Modified: stable/9/sys/cam/cam_periph.c stable/9/sys/cam/scsi/scsi_all.c stable/9/sys/cam/scsi/scsi_all.h stable/9/sys/cam/scsi/scsi_xpt.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/cam/cam_periph.c ============================================================================== --- stable/9/sys/cam/cam_periph.c Sat Sep 14 08:58:28 2013 (r255543) +++ stable/9/sys/cam/cam_periph.c Sat Sep 14 09:01:42 2013 (r255544) @@ -75,7 +75,7 @@ static int camperiphscsistatuserror(uni int *openings, u_int32_t *relsim_flags, u_int32_t *timeout, - int *print, + u_int32_t *action, const char **action_string); static int camperiphscsisenseerror(union ccb *ccb, union ccb **orig_ccb, @@ -84,7 +84,7 @@ static int camperiphscsisenseerror(unio int *openings, u_int32_t *relsim_flags, u_int32_t *timeout, - int *print, + u_int32_t *action, const char **action_string); static int nperiph_drivers; @@ -1283,7 +1283,7 @@ static int camperiphscsistatuserror(union ccb *ccb, union ccb **orig_ccb, cam_flags camflags, u_int32_t sense_flags, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout, int *print, const char **action_string) + u_int32_t *timeout, u_int32_t *action, const char **action_string) { int error; @@ -1302,7 +1302,7 @@ camperiphscsistatuserror(union ccb *ccb, openings, relsim_flags, timeout, - print, + action, action_string); break; case SCSI_STATUS_QUEUE_FULL: @@ -1357,7 +1357,7 @@ camperiphscsistatuserror(union ccb *ccb, } *timeout = 0; error = ERESTART; - *print = 0; + *action &= ~SSQ_PRINT_SENSE; break; } /* FALLTHROUGH */ @@ -1389,7 +1389,7 @@ static int camperiphscsisenseerror(union ccb *ccb, union ccb **orig, cam_flags camflags, u_int32_t sense_flags, int *openings, u_int32_t *relsim_flags, - u_int32_t *timeout, int *print, const char **action_string) + u_int32_t *timeout, u_int32_t *action, const char **action_string) { struct cam_periph *periph; union ccb *orig_ccb = ccb; @@ -1412,7 +1412,7 @@ camperiphscsisenseerror(union ccb *ccb, * imperitive that we don't violate this assumption. */ error = ERESTART; - *print = 0; + *action &= ~SSQ_PRINT_SENSE; } else { scsi_sense_action err_action; struct ccb_getdev cgd; @@ -1584,7 +1584,7 @@ camperiphscsisenseerror(union ccb *ccb, } sense_error_done: - *print = ((err_action & SSQ_PRINT_SENSE) != 0); + *action = err_action; } return (error); } @@ -1598,32 +1598,32 @@ int cam_periph_error(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags, union ccb *save_ccb) { - union ccb *orig_ccb; + struct cam_path *newpath; + union ccb *orig_ccb, *scan_ccb; struct cam_periph *periph; const char *action_string; cam_status status; - int frozen, error, openings, print, lost_device; - int error_code, sense_key, asc, ascq; - u_int32_t relsim_flags, timeout; + int frozen, error, openings; + u_int32_t action, relsim_flags, timeout; - print = 1; + action = SSQ_PRINT_SENSE; periph = xpt_path_periph(ccb->ccb_h.path); action_string = NULL; status = ccb->ccb_h.status; frozen = (status & CAM_DEV_QFRZN) != 0; status &= CAM_STATUS_MASK; - openings = relsim_flags = timeout = lost_device = 0; + openings = relsim_flags = timeout = 0; orig_ccb = ccb; switch (status) { case CAM_REQ_CMP: error = 0; - print = 0; + action &= ~SSQ_PRINT_SENSE; break; case CAM_SCSI_STATUS_ERROR: error = camperiphscsistatuserror(ccb, &orig_ccb, camflags, sense_flags, &openings, &relsim_flags, - &timeout, &print, &action_string); + &timeout, &action, &action_string); break; case CAM_AUTOSENSE_FAIL: error = EIO; /* we have to kill the command */ @@ -1654,8 +1654,7 @@ cam_periph_error(union ccb *ccb, cam_fla /* FALLTHROUGH */ case CAM_DEV_NOT_THERE: error = ENXIO; - print = 0; - lost_device = 1; + action = SSQ_LOST; break; case CAM_REQ_INVALID: case CAM_PATH_INVALID: @@ -1686,7 +1685,7 @@ cam_periph_error(union ccb *ccb, cam_fla action_string = "Retry was blocked"; } else { error = ERESTART; - print = 0; + action &= ~SSQ_PRINT_SENSE; } break; case CAM_RESRC_UNAVAIL: @@ -1725,12 +1724,12 @@ cam_periph_error(union ccb *ccb, cam_fla if ((sense_flags & SF_PRINT_ALWAYS) || CAM_DEBUGGED(ccb->ccb_h.path, CAM_DEBUG_INFO)) - print = 1; + action |= SSQ_PRINT_SENSE; else if (sense_flags & SF_NO_PRINT) - print = 0; - if (print) + action &= ~SSQ_PRINT_SENSE; + if ((action & SSQ_PRINT_SENSE) != 0) cam_error_print(orig_ccb, CAM_ESF_ALL, CAM_EPF_ALL); - if (error != 0 && print) { + if (error != 0 && (action & SSQ_PRINT_SENSE) != 0) { if (error != ERESTART) { if (action_string == NULL) action_string = "Unretryable error"; @@ -1742,8 +1741,7 @@ cam_periph_error(union ccb *ccb, cam_fla xpt_print(ccb->ccb_h.path, "Retrying command\n"); } - if (lost_device) { - struct cam_path *newpath; + if ((action & SSQ_LOST) != 0) { lun_id_t lun_id; /* @@ -1752,10 +1750,10 @@ cam_periph_error(union ccb *ccb, cam_fla * then we only get rid of the device(s) specified by the * path in the original CCB. */ - if (status == CAM_DEV_NOT_THERE) - lun_id = xpt_path_lun_id(ccb->ccb_h.path); - else + if (status == CAM_SEL_TIMEOUT) lun_id = CAM_LUN_WILDCARD; + else + lun_id = xpt_path_lun_id(ccb->ccb_h.path); /* Should we do more if we can't create the path?? */ if (xpt_create_path(&newpath, periph, @@ -1770,12 +1768,29 @@ cam_periph_error(union ccb *ccb, cam_fla xpt_async(AC_LOST_DEVICE, newpath, NULL); xpt_free_path(newpath); } + } /* Broadcast UNIT ATTENTIONs to all periphs. */ - } else if (scsi_extract_sense_ccb(ccb, - &error_code, &sense_key, &asc, &ascq) && - sense_key == SSD_KEY_UNIT_ATTENTION) { + if ((action & SSQ_UA) != 0) xpt_async(AC_UNIT_ATTENTION, orig_ccb->ccb_h.path, orig_ccb); + + /* Rescan target on "Reported LUNs data has changed" */ + if ((action & SSQ_RESCAN) != 0) { + if (xpt_create_path(&newpath, NULL, + xpt_path_path_id(ccb->ccb_h.path), + xpt_path_target_id(ccb->ccb_h.path), + CAM_LUN_WILDCARD) == CAM_REQ_CMP) { + + scan_ccb = xpt_alloc_ccb_nowait(); + if (scan_ccb != NULL) { + scan_ccb->ccb_h.path = newpath; + scan_ccb->ccb_h.func_code = XPT_SCAN_TGT; + scan_ccb->crcn.flags = 0; + xpt_rescan(scan_ccb); + } else + xpt_print(newpath, + "Can't allocate CCB to rescan target\n"); + } } /* Attempt a retry */ Modified: stable/9/sys/cam/scsi/scsi_all.c ============================================================================== --- stable/9/sys/cam/scsi/scsi_all.c Sat Sep 14 08:58:28 2013 (r255543) +++ stable/9/sys/cam/scsi/scsi_all.c Sat Sep 14 09:01:42 2013 (r255544) @@ -1645,7 +1645,7 @@ static struct asc_table_entry asc_table[ { SST(0x24, 0x08, SS_RDEF, /* XXX TBD */ "Invalid XCDB") }, /* DTLPWROMAEBKVF */ - { SST(0x25, 0x00, SS_FATAL | ENXIO, + { SST(0x25, 0x00, SS_FATAL | ENXIO | SSQ_LOST, "Logical unit not supported") }, /* DTLPWROMAEBKVF */ { SST(0x26, 0x00, SS_FATAL | EINVAL, @@ -2163,7 +2163,7 @@ static struct asc_table_entry asc_table[ { SST(0x3F, 0x0D, SS_RDEF, "Volume set reassigned") }, /* DTLPWROMAE */ - { SST(0x3F, 0x0E, SS_RDEF, /* XXX TBD */ + { SST(0x3F, 0x0E, SS_RDEF | SSQ_RESCAN , "Reported LUNs data has changed") }, /* DTLPWROMAEBKVF */ { SST(0x3F, 0x0F, SS_RDEF, /* XXX TBD */ @@ -3263,6 +3263,7 @@ scsi_error_action(struct ccb_scsiio *csi action |= SS_RETRY|SSQ_DECREMENT_COUNT| SSQ_PRINT_SENSE; } + action |= SSQ_UA; } } if ((action & SS_MASK) >= SS_START && Modified: stable/9/sys/cam/scsi/scsi_all.h ============================================================================== --- stable/9/sys/cam/scsi/scsi_all.h Sat Sep 14 08:58:28 2013 (r255543) +++ stable/9/sys/cam/scsi/scsi_all.h Sat Sep 14 09:01:42 2013 (r255544) @@ -88,6 +88,9 @@ typedef enum { * and text. */ SSQ_PRINT_SENSE = 0x0800, + SSQ_UA = 0x1000, /* Broadcast UA. */ + SSQ_RESCAN = 0x2000, /* Rescan target for LUNs. */ + SSQ_LOST = 0x4000, /* Destroy the LUNs. */ SSQ_MASK = 0xff00 } scsi_sense_action_qualifier; Modified: stable/9/sys/cam/scsi/scsi_xpt.c ============================================================================== --- stable/9/sys/cam/scsi/scsi_xpt.c Sat Sep 14 08:58:28 2013 (r255543) +++ stable/9/sys/cam/scsi/scsi_xpt.c Sat Sep 14 09:01:42 2013 (r255544) @@ -1877,8 +1877,8 @@ scsi_scan_bus(struct cam_periph *periph, if ((work_ccb->cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) && !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) && - !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) { - reset_ccb = xpt_alloc_ccb_nowait(); + !timevalisset(&request_ccb->ccb_h.path->bus->last_reset) && + (reset_ccb = xpt_alloc_ccb_nowait()) != NULL) { xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path, CAM_PRIORITY_NONE); reset_ccb->ccb_h.func_code = XPT_RESET_BUS;