File:  [DragonFly] / src / sys / bus / cam / scsi / scsi_da.c
Revision 1.16: download - view: text, annotated - select for diffs
Thu May 13 23:49:11 2004 UTC (10 years, 6 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
device switch 1/many: Remove d_autoq, add d_clone (where d_autoq was).

d_autoq was used to allow the device port dispatch to mix old-style synchronous
calls with new style messaging calls within a particular device.  It was never
used for that purpose.

d_clone will be more fully implemented as work continues.  We are going to
install d_port in the dev_t (struct specinfo) structure itself and d_clone
will be needed to allow devices to 'revector' the port on a minor-number
by minor-number basis, in particular allowing minor numbers to be directly
dispatched to distinct threads.  This is something we will be needing later
on.

    1: /*
    2:  * Implementation of SCSI Direct Access Peripheral driver for CAM.
    3:  *
    4:  * Copyright (c) 1997 Justin T. Gibbs.
    5:  * All rights reserved.
    6:  *
    7:  * Redistribution and use in source and binary forms, with or without
    8:  * modification, are permitted provided that the following conditions
    9:  * are met:
   10:  * 1. Redistributions of source code must retain the above copyright
   11:  *    notice, this list of conditions, and the following disclaimer,
   12:  *    without modification, immediately at the beginning of the file.
   13:  * 2. The name of the author may not be used to endorse or promote products
   14:  *    derived from this software without specific prior written permission.
   15:  *
   16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19:  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   20:  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26:  * SUCH DAMAGE.
   27:  *
   28:  * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.46 2003/10/21 22:18:19 thomas Exp $
   29:  * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.16 2004/05/13 23:49:11 dillon Exp $
   30:  */
   31: 
   32: #ifdef _KERNEL
   33: #include "opt_hw_wdog.h"
   34: #endif /* _KERNEL */
   35: 
   36: #include <sys/param.h>
   37: #include <sys/bootmaj.h>
   38: 
   39: #ifdef _KERNEL
   40: #include <sys/systm.h>
   41: #include <sys/kernel.h>
   42: #include <sys/buf.h>
   43: #include <sys/sysctl.h>
   44: #include <sys/taskqueue.h>
   45: #endif /* _KERNEL */
   46: 
   47: #include <sys/devicestat.h>
   48: #include <sys/conf.h>
   49: #include <sys/disk.h>
   50: #include <sys/eventhandler.h>
   51: #ifdef _KERNEL
   52: #include <sys/malloc.h>
   53: #include <sys/cons.h>
   54: #include <sys/proc.h>
   55: #endif
   56: #include <sys/buf2.h>
   57: 
   58: #include <machine/md_var.h>
   59: 
   60: #ifdef _KERNEL
   61: #include <vm/vm.h>
   62: #include <vm/pmap.h>
   63: #endif
   64: 
   65: #ifndef _KERNEL
   66: #include <stdio.h>
   67: #include <string.h>
   68: #endif /* _KERNEL */
   69: 
   70: #include "../cam.h"
   71: #include "../cam_ccb.h"
   72: #include "../cam_extend.h"
   73: #include "../cam_periph.h"
   74: #include "../cam_xpt_periph.h"
   75: 
   76: #include "scsi_message.h"
   77: 
   78: #ifndef _KERNEL 
   79: #include "scsi_da.h"
   80: #endif /* !_KERNEL */
   81: 
   82: #ifdef _KERNEL
   83: typedef enum {
   84: 	DA_STATE_PROBE,
   85: 	DA_STATE_NORMAL
   86: } da_state;
   87: 
   88: typedef enum {
   89: 	DA_FLAG_PACK_INVALID	= 0x001,
   90: 	DA_FLAG_NEW_PACK	= 0x002,
   91: 	DA_FLAG_PACK_LOCKED	= 0x004,
   92: 	DA_FLAG_PACK_REMOVABLE	= 0x008,
   93: 	DA_FLAG_TAGGED_QUEUING	= 0x010,
   94: 	DA_FLAG_NEED_OTAG	= 0x020,
   95: 	DA_FLAG_WENT_IDLE	= 0x040,
   96: 	DA_FLAG_RETRY_UA	= 0x080,
   97: 	DA_FLAG_OPEN		= 0x100,
   98: 	DA_FLAG_SCTX_INIT	= 0x200
   99: } da_flags;
  100: 
  101: typedef enum {
  102: 	DA_Q_NONE		= 0x00,
  103: 	DA_Q_NO_SYNC_CACHE	= 0x01,
  104: 	DA_Q_NO_6_BYTE		= 0x02,
  105: 	DA_Q_NO_PREVENT		= 0x04
  106: } da_quirks;
  107: 
  108: typedef enum {
  109: 	DA_CCB_PROBE		= 0x01,
  110: 	DA_CCB_BUFFER_IO	= 0x02,
  111: 	DA_CCB_WAITING		= 0x03,
  112: 	DA_CCB_DUMP		= 0x04,
  113: 	DA_CCB_TYPE_MASK	= 0x0F,
  114: 	DA_CCB_RETRY_UA		= 0x10
  115: } da_ccb_state;
  116: 
  117: /* Offsets into our private area for storing information */
  118: #define ccb_state	ppriv_field0
  119: #define ccb_bp		ppriv_ptr1
  120: 
  121: struct disk_params {
  122: 	u_int8_t  heads;
  123: 	u_int16_t cylinders;
  124: 	u_int8_t  secs_per_track;
  125: 	u_int32_t secsize;	/* Number of bytes/sector */
  126: 	u_int32_t sectors;	/* total number sectors */
  127: };
  128: 
  129: struct da_softc {
  130: 	struct	 buf_queue_head buf_queue;
  131: 	struct	 devstat device_stats;
  132: 	SLIST_ENTRY(da_softc) links;
  133: 	LIST_HEAD(, ccb_hdr) pending_ccbs;
  134: 	da_state state;
  135: 	da_flags flags;	
  136: 	da_quirks quirks;
  137: 	int	 minimum_cmd_size;
  138: 	int	 ordered_tag_count;
  139: 	struct	 disk_params params;
  140: 	struct	 disk disk;
  141: 	union	 ccb saved_ccb;
  142: 	struct task		sysctl_task;
  143: 	struct sysctl_ctx_list	sysctl_ctx;
  144: 	struct sysctl_oid	*sysctl_tree;
  145: };
  146: 
  147: struct da_quirk_entry {
  148: 	struct scsi_inquiry_pattern inq_pat;
  149: 	da_quirks quirks;
  150: };
  151: 
  152: static const char quantum[] = "QUANTUM";
  153: static const char microp[] = "MICROP";
  154: 
  155: static struct da_quirk_entry da_quirk_table[] =
  156: {
  157: 	/* SPI, FC devices */
  158: 	{
  159: 		/*
  160: 		 * Fujitsu M2513A MO drives.
  161: 		 * Tested devices: M2513A2 firmware versions 1200 & 1300.
  162: 		 * (dip switch selects whether T_DIRECT or T_OPTICAL device)
  163: 		 * Reported by: W.Scholten <whs@xs4all.nl>
  164: 		 */
  165: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
  166: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  167: 	},
  168: 	{
  169: 		/* See above. */
  170: 		{T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
  171: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  172: 	},
  173: 	{
  174: 		/*
  175: 		 * This particular Fujitsu drive doesn't like the
  176: 		 * synchronize cache command.
  177: 		 * Reported by: Tom Jackson <toj@gorilla.net>
  178: 		 */
  179: 		{T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
  180: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  181: 	
  182: 	},
  183: 	{
  184: 		/*
  185: 		 * This drive doesn't like the synchronize cache command
  186: 		 * either.  Reported by: Matthew Jacob <mjacob@feral.com>
  187: 		 * in NetBSD PR kern/6027, August 24, 1998.
  188: 		 */
  189: 		{T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
  190: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  191: 	},
  192: 	{
  193: 		/*
  194: 		 * This drive doesn't like the synchronize cache command
  195: 		 * either.  Reported by: Hellmuth Michaelis (hm@kts.org)
  196: 		 * (PR 8882).
  197: 		 */
  198: 		{T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
  199: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  200: 	},
  201: 	{
  202: 		/*
  203: 		 * Doesn't like the synchronize cache command.
  204: 		 * Reported by: Blaz Zupan <blaz@gold.amis.net>
  205: 		 */
  206: 		{T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
  207: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  208: 	},
  209: 	{
  210: 		/*
  211: 		 * Doesn't like the synchronize cache command.
  212: 		 */
  213: 		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
  214: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  215: 	},
  216: 	{
  217: 		/*
  218: 		 * Doesn't like the synchronize cache command.
  219: 		 */
  220: 		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
  221: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  222: 	},
  223: 	{
  224: 		/*
  225: 		 * Doesn't work correctly with 6 byte reads/writes.
  226: 		 * Returns illegal request, and points to byte 9 of the
  227: 		 * 6-byte CDB.
  228: 		 * Reported by:  Adam McDougall <bsdx@spawnet.com>
  229: 		 */
  230: 		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
  231: 		/*quirks*/ DA_Q_NO_6_BYTE
  232: 	},
  233: 	{
  234: 		/* See above. */
  235: 		{T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
  236: 		/*quirks*/ DA_Q_NO_6_BYTE
  237: 	},
  238: 	/* XXX USB floppy quirks temporarily enabled for 4.9R */
  239: 	/* USB floppy devices supported by umass(4) */
  240: 	{
  241: 		/*
  242: 		 * This USB floppy drive uses the UFI command set. This
  243: 		 * command set is a derivative of the ATAPI command set and
  244: 		 * does not support READ_6 commands only READ_10. It also does
  245: 		 * not support sync cache (0x35).
  246: 		 */
  247: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Y-E DATA", "USB-FDU", "*"},
  248: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  249: 	},
  250: 	{
  251: 		/* Another USB floppy */
  252: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "MATSHITA", "FDD CF-VFDU*","*"},
  253: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  254: 	},
  255: 	{
  256: 		/*
  257: 		 * The vendor, product and version strings coming from the
  258: 		 * controller are null terminated instead of being padded with
  259: 		 * spaces. The trailing wildcard character '*' is required.
  260: 		 */
  261: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "SMSC*", "USB FDC*","*"},
  262: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  263: 	},
  264: 	{
  265: 		/*
  266: 		 * SmartDisk (Mitsumi) USB floppy drive
  267: 		 * PR: kern/50226
  268: 		 */
  269: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "MITSUMI", "USB FDD", "*"},
  270: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  271: 	},
  272: #ifdef DA_OLD_QUIRKS
  273: 	/* USB mass storage devices supported by umass(4) */
  274: 	{
  275: 		/*
  276: 		 * Sony Memory Stick adapter MSAC-US1 and
  277: 		 * Sony PCG-C1VJ Internal Memory Stick Slot (MSC-U01).
  278: 		 * Make all sony MS* products use this quirk.
  279: 		 */
  280: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "MS*", "*"},
  281: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  282: 	},
  283: 	{
  284: 		/*
  285: 		 * Sony Memory Stick adapter for the CLIE series
  286: 		 * of PalmOS PDA's
  287: 		 */
  288: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "CLIE*", "*"},
  289: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  290: 	},
  291: 	{
  292: 		/*
  293: 		 * Intelligent Stick USB disk-on-key
  294: 		 * PR: kern/53005
  295: 		 */
  296: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "USB Card",
  297: 		 "IntelligentStick*", "*"},
  298: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  299: 	},
  300: 	{
  301: 		/*
  302: 		 * Sony DSC cameras (DSC-S30, DSC-S50, DSC-S70)
  303: 		 */
  304: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
  305: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  306: 	},
  307: 	{
  308: 		/*
  309: 		 * Microtech USB CameraMate
  310: 		 */
  311: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "eUSB    Compact*",
  312: 		 "Compact Flash*", "*"},
  313: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  314: 	},
  315: 	{
  316: 		/*
  317: 		 * Olympus digital cameras (C-3040ZOOM, C-2040ZOOM, C-1)
  318: 		 */
  319: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "C-*", "*"},
  320: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  321: 	},
  322: 	{
  323: 		/*
  324: 		 * Olympus digital cameras (E-100RS, E-10).
  325: 		 */
  326: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "E-*", "*"},
  327: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  328: 	},
  329: 	{
  330: 		/*
  331: 		 * KingByte Pen Drives
  332: 		 */
  333: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "NO BRAND", "PEN DRIVE", "*"},
  334: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  335:  	},
  336:  	{
  337: 		/*
  338: 		 * FujiFilm Camera
  339: 		 */
  340:  		{T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJIFILMUSB-DRIVEUNIT",
  341: 		 "USB-DRIVEUNIT", "*"},
  342:  		/*quirks*/ DA_Q_NO_SYNC_CACHE
  343:  	},
  344: 	{
  345: 		/*
  346: 		 * Minolta Dimage E203
  347: 		 */
  348: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "MINOLTA", "DiMAGE E203", "*"},
  349: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  350: 	},
  351: 	{
  352: 		/*
  353: 		 * Apacer HandyDrive
  354: 		 * PR: kern/43627
  355: 		 */
  356: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Apacer", "HandyDrive", "*"},
  357: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  358: 	},
  359: 	{
  360: 		/*
  361: 		 * Daisy Technology PhotoClip on Zoran chip
  362: 		 * PR: kern/43580
  363: 		 */
  364: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "ZORAN", "COACH", "*"},
  365: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  366: 	},
  367: 	{
  368: 		/*
  369: 		 * Sony USB Key-Storage
  370: 		 * PR: kern/46386
  371: 		 */
  372: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Storage Media", "*"},
  373: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  374: 	},
  375: #endif /* DA_OLD_QUIRKS */
  376: 	{
  377: 		/*
  378: 		 * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
  379: 		 * PR: kern/51675
  380: 		 */
  381: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
  382: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  383: 	},
  384: 	{
  385: 		/*
  386: 		 * Jungsoft NEXDISK USB flash key
  387: 		 * PR: kern/54737
  388: 		 */
  389: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
  390: 		/*quirks*/ DA_Q_NO_SYNC_CACHE
  391: 	},
  392: 	{
  393: 		/*
  394: 		 * Creative Nomad MUVO mp3 player (USB)
  395: 		 * PR: kern/53094
  396: 		 */
  397: 		{T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
  398: 		/*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
  399: 	},
  400: };
  401: 
  402: static	d_open_t	daopen;
  403: static	d_close_t	daclose;
  404: static	d_strategy_t	dastrategy;
  405: static	d_ioctl_t	daioctl;
  406: static	d_dump_t	dadump;
  407: static	periph_init_t	dainit;
  408: static	void		daasync(void *callback_arg, u_int32_t code,
  409: 				struct cam_path *path, void *arg);
  410: static	int		dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
  411: static	periph_ctor_t	daregister;
  412: static	periph_dtor_t	dacleanup;
  413: static	periph_start_t	dastart;
  414: static	periph_oninv_t	daoninvalidate;
  415: static	void		dadone(struct cam_periph *periph,
  416: 			       union ccb *done_ccb);
  417: static  int		daerror(union ccb *ccb, u_int32_t cam_flags,
  418: 				u_int32_t sense_flags);
  419: static void		daprevent(struct cam_periph *periph, int action);
  420: static void		dasetgeom(struct cam_periph *periph,
  421: 				  struct scsi_read_capacity_data * rdcap);
  422: static timeout_t	dasendorderedtag;
  423: static void		dashutdown(void *arg, int howto);
  424: 
  425: #ifndef DA_DEFAULT_TIMEOUT
  426: #define DA_DEFAULT_TIMEOUT 60	/* Timeout in seconds */
  427: #endif
  428: 
  429: #ifndef	DA_DEFAULT_RETRY
  430: #define	DA_DEFAULT_RETRY	4
  431: #endif
  432: 
  433: static int da_retry_count = DA_DEFAULT_RETRY;
  434: static int da_default_timeout = DA_DEFAULT_TIMEOUT;
  435: 
  436: SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
  437:             "CAM Direct Access Disk driver");
  438: SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
  439:            &da_retry_count, 0, "Normal I/O retry count");
  440: TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
  441: SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
  442:            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
  443: TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
  444: 
  445: /*
  446:  * DA_ORDEREDTAG_INTERVAL determines how often, relative
  447:  * to the default timeout, we check to see whether an ordered
  448:  * tagged transaction is appropriate to prevent simple tag
  449:  * starvation.  Since we'd like to ensure that there is at least
  450:  * 1/2 of the timeout length left for a starved transaction to
  451:  * complete after we've sent an ordered tag, we must poll at least
  452:  * four times in every timeout period.  This takes care of the worst
  453:  * case where a starved transaction starts during an interval that
  454:  * meets the requirement "don't send an ordered tag" test so it takes
  455:  * us two intervals to determine that a tag must be sent.
  456:  */
  457: #ifndef DA_ORDEREDTAG_INTERVAL
  458: #define DA_ORDEREDTAG_INTERVAL 4
  459: #endif
  460: 
  461: static struct periph_driver dadriver =
  462: {
  463: 	dainit, "da",
  464: 	TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
  465: };
  466: 
  467: DATA_SET(periphdriver_set, dadriver);
  468: 
  469: /* For 2.2-stable support */
  470: #ifndef D_DISK
  471: #define D_DISK 0
  472: #endif
  473: 
  474: static struct cdevsw da_cdevsw = {
  475: 	/* name */	"da",
  476: 	/* maj */	DA_CDEV_MAJOR,
  477: 	/* flags */	D_DISK,
  478: 	/* port */      NULL,
  479: 	/* clone */     NULL,
  480: 
  481: 	/* open */	daopen,
  482: 	/* close */	daclose,
  483: 	/* read */	physread,
  484: 	/* write */	physwrite,
  485: 	/* ioctl */	daioctl,
  486: 	/* poll */	nopoll,
  487: 	/* mmap */	nommap,
  488: 	/* strategy */	dastrategy,
  489: 	/* dump */	dadump,
  490: 	/* psize */	nopsize
  491: };
  492: 
  493: static SLIST_HEAD(,da_softc) softc_list;
  494: static struct extend_array *daperiphs;
  495: 
  496: static int
  497: daopen(dev_t dev, int flags, int fmt, struct thread *td)
  498: {
  499: 	struct cam_periph *periph;
  500: 	struct da_softc *softc;
  501: 	struct disklabel *label;	
  502: 	int unit;
  503: 	int part;
  504: 	int error;
  505: 	int s;
  506: 
  507: 	unit = dkunit(dev);
  508: 	part = dkpart(dev);
  509: 	periph = cam_extend_get(daperiphs, unit);
  510: 	if (periph == NULL)
  511: 		return (ENXIO);	
  512: 
  513: 	softc = (struct da_softc *)periph->softc;
  514: 
  515: 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
  516: 	    ("daopen: dev=%s (unit %d , partition %d)\n", devtoname(dev),
  517: 	     unit, part));
  518: 
  519: 	if ((error = cam_periph_lock(periph, PCATCH)) != 0) {
  520: 		return (error); /* error code from tsleep */
  521: 	}
  522: 
  523: 	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
  524: 		return(ENXIO);
  525: 	softc->flags |= DA_FLAG_OPEN;
  526: 
  527: 	s = splsoftcam();
  528: 	if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
  529: 		/* Invalidate our pack information. */
  530: 		disk_invalidate(&softc->disk);
  531: 		softc->flags &= ~DA_FLAG_PACK_INVALID;
  532: 	}
  533: 	splx(s);
  534: 
  535: 	/* Do a read capacity */
  536: 	{
  537: 		struct scsi_read_capacity_data *rcap;
  538: 		union  ccb *ccb;
  539: 
  540: 		rcap = malloc(sizeof(*rcap), M_TEMP, M_INTWAIT | M_ZERO);
  541: 		
  542: 		ccb = cam_periph_getccb(periph, /*priority*/1);
  543: 		scsi_read_capacity(&ccb->csio,
  544: 				   /*retries*/1,
  545: 				   /*cbfncp*/dadone,
  546: 				   MSG_SIMPLE_Q_TAG,
  547: 				   rcap,
  548: 				   SSD_FULL_SIZE,
  549: 				   /*timeout*/60000);
  550: 		ccb->ccb_h.ccb_bp = NULL;
  551: 
  552: 		error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
  553: 					  /*sense_flags*/SF_RETRY_UA |
  554: 							 SF_RETRY_SELTO,
  555: 					  &softc->device_stats);
  556: 
  557: 		xpt_release_ccb(ccb);
  558: 
  559: 		if (error == 0) {
  560: 			dasetgeom(periph, rcap);
  561: 		}
  562: 
  563: 		free(rcap, M_TEMP);
  564: 	}
  565: 
  566: 	if (error == 0) {
  567: 		struct ccb_getdev cgd;
  568: 
  569: 		/* Build label for whole disk. */
  570: 		label = &softc->disk.d_label;
  571: 		bzero(label, sizeof(*label));
  572: 		label->d_type = DTYPE_SCSI;
  573: 
  574: 		/*
  575: 		 * Grab the inquiry data to get the vendor and product names.
  576: 		 * Put them in the typename and packname for the label.
  577: 		 */
  578: 		xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1);
  579: 		cgd.ccb_h.func_code = XPT_GDEV_TYPE;
  580: 		xpt_action((union ccb *)&cgd);
  581: 
  582: 		strncpy(label->d_typename, cgd.inq_data.vendor,
  583: 			min(SID_VENDOR_SIZE, sizeof(label->d_typename)));
  584: 		strncpy(label->d_packname, cgd.inq_data.product,
  585: 			min(SID_PRODUCT_SIZE, sizeof(label->d_packname)));
  586: 		
  587: 		label->d_secsize = softc->params.secsize;
  588: 		label->d_nsectors = softc->params.secs_per_track;
  589: 		label->d_ntracks = softc->params.heads;
  590: 		label->d_ncylinders = softc->params.cylinders;
  591: 		label->d_secpercyl = softc->params.heads
  592: 				  * softc->params.secs_per_track;
  593: 		label->d_secperunit = softc->params.sectors;
  594: 
  595: 		if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
  596: 		    (softc->quirks & DA_Q_NO_PREVENT) == 0)
  597: 			daprevent(periph, PR_PREVENT);
  598: 	
  599: 		/*
  600: 		 * Check to see whether or not the blocksize is set yet.
  601: 		 * If it isn't, set it and then clear the blocksize
  602: 		 * unavailable flag for the device statistics.
  603: 		 */
  604: 		if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0){
  605: 			softc->device_stats.block_size = softc->params.secsize;
  606: 			softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
  607: 		}
  608: 	}
  609: 	
  610: 	if (error != 0) {
  611: 		if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
  612: 		    (softc->quirks & DA_Q_NO_PREVENT) == 0)
  613: 			daprevent(periph, PR_ALLOW);
  614: 		softc->flags &= ~DA_FLAG_OPEN;
  615: 		cam_periph_release(periph);
  616: 	}
  617: 	cam_periph_unlock(periph);
  618: 	return (error);
  619: }
  620: 
  621: static int
  622: daclose(dev_t dev, int flag, int fmt, struct thread *td)
  623: {
  624: 	struct	cam_periph *periph;
  625: 	struct	da_softc *softc;
  626: 	int	unit;
  627: 	int	error;
  628: 
  629: 	unit = dkunit(dev);
  630: 	periph = cam_extend_get(daperiphs, unit);
  631: 	if (periph == NULL)
  632: 		return (ENXIO);	
  633: 
  634: 	softc = (struct da_softc *)periph->softc;
  635: 
  636: 	if ((error = cam_periph_lock(periph, 0)) != 0) {
  637: 		return (error); /* error code from tsleep */
  638: 	}
  639: 
  640: 	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
  641: 		union	ccb *ccb;
  642: 
  643: 		ccb = cam_periph_getccb(periph, /*priority*/1);
  644: 
  645: 		scsi_synchronize_cache(&ccb->csio,
  646: 				       /*retries*/1,
  647: 				       /*cbfcnp*/dadone,
  648: 				       MSG_SIMPLE_Q_TAG,
  649: 				       /*begin_lba*/0,/* Cover the whole disk */
  650: 				       /*lb_count*/0,
  651: 				       SSD_FULL_SIZE,
  652: 				       5 * 60 * 1000);
  653: 
  654: 		cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
  655: 				  /*sense_flags*/SF_RETRY_UA,
  656: 				  &softc->device_stats);
  657: 
  658: 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
  659: 			if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
  660: 			     CAM_SCSI_STATUS_ERROR) {
  661: 				int asc, ascq;
  662: 				int sense_key, error_code;
  663: 
  664: 				scsi_extract_sense(&ccb->csio.sense_data,
  665: 						   &error_code,
  666: 						   &sense_key, 
  667: 						   &asc, &ascq);
  668: 				if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
  669: 					scsi_sense_print(&ccb->csio);
  670: 			} else {
  671: 				xpt_print_path(periph->path);
  672: 				printf("Synchronize cache failed, status "
  673: 				       "== 0x%x, scsi status == 0x%x\n",
  674: 				       ccb->csio.ccb_h.status,
  675: 				       ccb->csio.scsi_status);
  676: 			}
  677: 		}
  678: 
  679: 		if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
  680: 			cam_release_devq(ccb->ccb_h.path,
  681: 					 /*relsim_flags*/0,
  682: 					 /*reduction*/0,
  683: 					 /*timeout*/0,
  684: 					 /*getcount_only*/0);
  685: 
  686: 		xpt_release_ccb(ccb);
  687: 
  688: 	}
  689: 
  690: 	if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
  691: 		if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
  692: 			daprevent(periph, PR_ALLOW);
  693: 		/*
  694: 		 * If we've got removeable media, mark the blocksize as
  695: 		 * unavailable, since it could change when new media is
  696: 		 * inserted.
  697: 		 */
  698: 		softc->device_stats.flags |= DEVSTAT_BS_UNAVAILABLE;
  699: 	}
  700: 
  701: 	softc->flags &= ~DA_FLAG_OPEN;
  702: 	cam_periph_unlock(periph);
  703: 	cam_periph_release(periph);
  704: 	return (0);	
  705: }
  706: 
  707: /*
  708:  * Actually translate the requested transfer into one the physical driver
  709:  * can understand.  The transfer is described by a buf and will include
  710:  * only one physical transfer.
  711:  */
  712: static void
  713: dastrategy(struct buf *bp)
  714: {
  715: 	struct cam_periph *periph;
  716: 	struct da_softc *softc;
  717: 	u_int  unit;
  718: 	u_int  part;
  719: 	int    s;
  720: 	
  721: 	unit = dkunit(bp->b_dev);
  722: 	part = dkpart(bp->b_dev);
  723: 	periph = cam_extend_get(daperiphs, unit);
  724: 	if (periph == NULL) {
  725: 		bp->b_error = ENXIO;
  726: 		goto bad;		
  727: 	}
  728: 	softc = (struct da_softc *)periph->softc;
  729: #if 0
  730: 	/*
  731: 	 * check it's not too big a transfer for our adapter
  732: 	 */
  733: 	scsi_minphys(bp,&sd_switch);
  734: #endif
  735: 
  736: 	/*
  737: 	 * Mask interrupts so that the pack cannot be invalidated until
  738: 	 * after we are in the queue.  Otherwise, we might not properly
  739: 	 * clean up one of the buffers.
  740: 	 */
  741: 	s = splbio();
  742: 	
  743: 	/*
  744: 	 * If the device has been made invalid, error out
  745: 	 */
  746: 	if ((softc->flags & DA_FLAG_PACK_INVALID)) {
  747: 		splx(s);
  748: 		bp->b_error = ENXIO;
  749: 		goto bad;
  750: 	}
  751: 	
  752: 	/*
  753: 	 * Place it in the queue of disk activities for this disk
  754: 	 */
  755: 	bufqdisksort(&softc->buf_queue, bp);
  756: 
  757: 	splx(s);
  758: 	
  759: 	/*
  760: 	 * Schedule ourselves for performing the work.
  761: 	 */
  762: 	xpt_schedule(periph, /* XXX priority */1);
  763: 
  764: 	return;
  765: bad:
  766: 	bp->b_flags |= B_ERROR;
  767: 
  768: 	/*
  769: 	 * Correctly set the buf to indicate a completed xfer
  770: 	 */
  771: 	bp->b_resid = bp->b_bcount;
  772: 	biodone(bp);
  773: 	return;
  774: }
  775: 
  776: /* For 2.2-stable support */
  777: #ifndef ENOIOCTL
  778: #define ENOIOCTL -1
  779: #endif
  780: 
  781: static int
  782: daioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
  783: {
  784: 	struct cam_periph *periph;
  785: 	struct da_softc *softc;
  786: 	int unit;
  787: 	int error;
  788: 
  789: 	unit = dkunit(dev);
  790: 	periph = cam_extend_get(daperiphs, unit);
  791: 	if (periph == NULL)
  792: 		return (ENXIO);	
  793: 
  794: 	softc = (struct da_softc *)periph->softc;
  795: 
  796: 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("daioctl\n"));
  797: 
  798: 	if ((error = cam_periph_lock(periph, PCATCH)) != 0) {
  799: 		return (error); /* error code from tsleep */
  800: 	}	
  801: 
  802: 	error = cam_periph_ioctl(periph, cmd, addr, daerror);
  803: 
  804: 	cam_periph_unlock(periph);
  805: 	
  806: 	return (error);
  807: }
  808: 
  809: static int
  810: dadump(dev_t dev)
  811: {
  812: 	struct	    cam_periph *periph;
  813: 	struct	    da_softc *softc;
  814: 	u_int	    unit;
  815: 	u_int	    part;
  816: 	u_int	    secsize;
  817: 	u_int	    num;	/* number of sectors to write */
  818: 	u_int	    blknum;
  819: 	long	    blkcnt;
  820: 	vm_paddr_t  addr;	
  821: 	struct	    ccb_scsiio csio;
  822: 	int         dumppages = MAXDUMPPGS;
  823: 	int	    error;
  824: 	int         i;
  825: 
  826: 	/* toss any characters present prior to dump */
  827: 	while (cncheckc() != -1)
  828: 		;
  829: 
  830: 	unit = dkunit(dev);
  831: 	part = dkpart(dev);
  832: 	periph = cam_extend_get(daperiphs, unit);
  833: 	if (periph == NULL) {
  834: 		return (ENXIO);
  835: 	}
  836: 	softc = (struct da_softc *)periph->softc;
  837: 	
  838: 	if ((softc->flags & DA_FLAG_PACK_INVALID) != 0)
  839: 		return (ENXIO);
  840: 
  841: 	error = disk_dumpcheck(dev, &num, &blknum, &secsize);
  842: 	if (error)
  843: 		return (error);
  844: 
  845: 	addr = 0;	/* starting address */
  846: 	blkcnt = howmany(PAGE_SIZE, secsize);
  847: 
  848: 	while (num > 0) {
  849: 		caddr_t va = NULL;
  850: 
  851: 		if ((num / blkcnt) < dumppages)
  852: 			dumppages = num / blkcnt;
  853: 
  854: 		for (i = 0; i < dumppages; ++i) {
  855: 			vm_paddr_t a = addr + (i * PAGE_SIZE);
  856: 			if (is_physical_memory(a))
  857: 				va = pmap_kenter_temporary(trunc_page(a), i);
  858: 			else
  859: 				va = pmap_kenter_temporary(trunc_page(0), i);
  860: 		}
  861: 
  862: 		xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
  863: 		csio.ccb_h.ccb_state = DA_CCB_DUMP;
  864: 		scsi_read_write(&csio,
  865: 				/*retries*/1,
  866: 				dadone,
  867: 				MSG_ORDERED_Q_TAG,
  868: 				/*read*/FALSE,
  869: 				/*byte2*/0,
  870: 				/*minimum_cmd_size*/ softc->minimum_cmd_size,
  871: 				blknum,
  872: 				blkcnt * dumppages,
  873: 				/*data_ptr*/(u_int8_t *) va,
  874: 				/*dxfer_len*/blkcnt * secsize * dumppages,
  875: 				/*sense_len*/SSD_FULL_SIZE,
  876: 				DA_DEFAULT_TIMEOUT * 1000);		
  877: 		xpt_polled_action((union ccb *)&csio);
  878: 
  879: 		if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
  880: 			printf("Aborting dump due to I/O error.\n");
  881: 			if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
  882: 			     CAM_SCSI_STATUS_ERROR)
  883: 				scsi_sense_print(&csio);
  884: 			else
  885: 				printf("status == 0x%x, scsi status == 0x%x\n",
  886: 				       csio.ccb_h.status, csio.scsi_status);
  887: 			return(EIO);
  888: 		}
  889: 		
  890: 		if (dumpstatus(addr, (off_t)num * softc->params.secsize) < 0)
  891: 			return (EINTR);
  892: 
  893: 		/* update block count */
  894: 		num -= blkcnt * dumppages;
  895: 		blknum += blkcnt * dumppages;
  896: 		addr += PAGE_SIZE * dumppages;
  897: 	}
  898: 
  899: 	/*
  900: 	 * Sync the disk cache contents to the physical media.
  901: 	 */
  902: 	if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
  903: 
  904: 		xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
  905: 		csio.ccb_h.ccb_state = DA_CCB_DUMP;
  906: 		scsi_synchronize_cache(&csio,
  907: 				       /*retries*/1,
  908: 				       /*cbfcnp*/dadone,
  909: 				       MSG_SIMPLE_Q_TAG,
  910: 				       /*begin_lba*/0,/* Cover the whole disk */
  911: 				       /*lb_count*/0,
  912: 				       SSD_FULL_SIZE,
  913: 				       5 * 60 * 1000);
  914: 		xpt_polled_action((union ccb *)&csio);
  915: 
  916: 		if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
  917: 			if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
  918: 			     CAM_SCSI_STATUS_ERROR) {
  919: 				int asc, ascq;
  920: 				int sense_key, error_code;
  921: 
  922: 				scsi_extract_sense(&csio.sense_data,
  923: 						   &error_code,
  924: 						   &sense_key, 
  925: 						   &asc, &ascq);
  926: 				if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
  927: 					scsi_sense_print(&csio);
  928: 			} else {
  929: 				xpt_print_path(periph->path);
  930: 				printf("Synchronize cache failed, status "
  931: 				       "== 0x%x, scsi status == 0x%x\n",
  932: 				       csio.ccb_h.status, csio.scsi_status);
  933: 			}
  934: 		}
  935: 	}
  936: 	return (0);
  937: }
  938: 
  939: static void
  940: dainit(void)
  941: {
  942: 	cam_status status;
  943: 	struct cam_path *path;
  944: 
  945: 	/*
  946: 	 * Create our extend array for storing the devices we attach to.
  947: 	 */
  948: 	daperiphs = cam_extend_new();
  949: 	SLIST_INIT(&softc_list);
  950: 	if (daperiphs == NULL) {
  951: 		printf("da: Failed to alloc extend array!\n");
  952: 		return;
  953: 	}
  954: 	
  955: 	/*
  956: 	 * Install a global async callback.  This callback will
  957: 	 * receive async callbacks like "new device found".
  958: 	 */
  959: 	status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
  960: 				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
  961: 
  962: 	if (status == CAM_REQ_CMP) {
  963: 		struct ccb_setasync csa;
  964: 
  965:                 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
  966:                 csa.ccb_h.func_code = XPT_SASYNC_CB;
  967:                 csa.event_enable = AC_FOUND_DEVICE;
  968:                 csa.callback = daasync;
  969:                 csa.callback_arg = NULL;
  970:                 xpt_action((union ccb *)&csa);
  971: 		status = csa.ccb_h.status;
  972:                 xpt_free_path(path);
  973:         }
  974: 
  975: 	if (status != CAM_REQ_CMP) {
  976: 		printf("da: Failed to attach master async callback "
  977: 		       "due to status 0x%x!\n", status);
  978: 	} else {
  979: 
  980: 		/*
  981: 		 * Schedule a periodic event to occasionally send an
  982: 		 * ordered tag to a device.
  983: 		 */
  984: 		timeout(dasendorderedtag, NULL,
  985: 			(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
  986: 
  987: 		/* Register our shutdown event handler */
  988: 		if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 
  989: 					   NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
  990: 		    printf("dainit: shutdown event registration failed!\n");
  991: 	}
  992: }
  993: 
  994: static void
  995: daoninvalidate(struct cam_periph *periph)
  996: {
  997: 	int s;
  998: 	struct da_softc *softc;
  999: 	struct buf *q_bp;
 1000: 	struct ccb_setasync csa;
 1001: 
 1002: 	softc = (struct da_softc *)periph->softc;
 1003: 
 1004: 	/*
 1005: 	 * De-register any async callbacks.
 1006: 	 */
 1007: 	xpt_setup_ccb(&csa.ccb_h, periph->path,
 1008: 		      /* priority */ 5);
 1009: 	csa.ccb_h.func_code = XPT_SASYNC_CB;
 1010: 	csa.event_enable = 0;
 1011: 	csa.callback = daasync;
 1012: 	csa.callback_arg = periph;
 1013: 	xpt_action((union ccb *)&csa);
 1014: 
 1015: 	softc->flags |= DA_FLAG_PACK_INVALID;
 1016: 
 1017: 	/*
 1018: 	 * Although the oninvalidate() routines are always called at
 1019: 	 * splsoftcam, we need to be at splbio() here to keep the buffer
 1020: 	 * queue from being modified while we traverse it.
 1021: 	 */
 1022: 	s = splbio();
 1023: 
 1024: 	/*
 1025: 	 * Return all queued I/O with ENXIO.
 1026: 	 * XXX Handle any transactions queued to the card
 1027: 	 *     with XPT_ABORT_CCB.
 1028: 	 */
 1029: 	while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){
 1030: 		bufq_remove(&softc->buf_queue, q_bp);
 1031: 		q_bp->b_resid = q_bp->b_bcount;
 1032: 		q_bp->b_error = ENXIO;
 1033: 		q_bp->b_flags |= B_ERROR;
 1034: 		biodone(q_bp);
 1035: 	}
 1036: 	splx(s);
 1037: 
 1038: 	SLIST_REMOVE(&softc_list, softc, da_softc, links);
 1039: 
 1040: 	xpt_print_path(periph->path);
 1041: 	printf("lost device\n");
 1042: }
 1043: 
 1044: static void
 1045: dacleanup(struct cam_periph *periph)
 1046: {
 1047: 	struct da_softc *softc;
 1048: 
 1049: 	softc = (struct da_softc *)periph->softc;
 1050: 
 1051: 	devstat_remove_entry(&softc->device_stats);
 1052: 	cam_extend_release(daperiphs, periph->unit_number);
 1053: 	xpt_print_path(periph->path);
 1054: 	printf("removing device entry\n");
 1055: 	/*
 1056: 	 * If we can't free the sysctl tree, oh well...
 1057: 	 */
 1058: 	if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
 1059: 	    && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
 1060: 		xpt_print_path(periph->path);
 1061: 		printf("can't remove sysctl context\n");
 1062: 	}
 1063: 	if (softc->disk.d_dev) {
 1064: 		disk_destroy(&softc->disk);
 1065: 	}
 1066: 	free(softc, M_DEVBUF);
 1067: }
 1068: 
 1069: static void
 1070: daasync(void *callback_arg, u_int32_t code,
 1071: 	struct cam_path *path, void *arg)
 1072: {
 1073: 	struct cam_periph *periph;
 1074: 
 1075: 	periph = (struct cam_periph *)callback_arg;
 1076: 	switch (code) {
 1077: 	case AC_FOUND_DEVICE:
 1078: 	{
 1079: 		struct ccb_getdev *cgd;
 1080: 		cam_status status;
 1081:  
 1082: 		cgd = (struct ccb_getdev *)arg;
 1083: 
 1084: 		if (SID_TYPE(&cgd->inq_data) != T_DIRECT
 1085: 		    && SID_TYPE(&cgd->inq_data) != T_RBC
 1086: 		    && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
 1087: 			break;
 1088: 
 1089: 		/*
 1090: 		 * Allocate a peripheral instance for
 1091: 		 * this device and start the probe
 1092: 		 * process.
 1093: 		 */
 1094: 		status = cam_periph_alloc(daregister, daoninvalidate,
 1095: 					  dacleanup, dastart,
 1096: 					  "da", CAM_PERIPH_BIO,
 1097: 					  cgd->ccb_h.path, daasync,
 1098: 					  AC_FOUND_DEVICE, cgd);
 1099: 
 1100: 		if (status != CAM_REQ_CMP
 1101: 		 && status != CAM_REQ_INPROG)
 1102: 			printf("daasync: Unable to attach to new device "
 1103: 				"due to status 0x%x\n", status);
 1104: 		break;
 1105: 	}
 1106: 	case AC_SENT_BDR:
 1107: 	case AC_BUS_RESET:
 1108: 	{
 1109: 		struct da_softc *softc;
 1110: 		struct ccb_hdr *ccbh;
 1111: 		int s;
 1112: 
 1113: 		softc = (struct da_softc *)periph->softc;
 1114: 		s = splsoftcam();
 1115: 		/*
 1116: 		 * Don't fail on the expected unit attention
 1117: 		 * that will occur.
 1118: 		 */
 1119: 		softc->flags |= DA_FLAG_RETRY_UA;
 1120: 		for (ccbh = LIST_FIRST(&softc->pending_ccbs);
 1121: 		     ccbh != NULL; ccbh = LIST_NEXT(ccbh, periph_links.le))
 1122: 			ccbh->ccb_state |= DA_CCB_RETRY_UA;
 1123: 		splx(s);
 1124: 		/* FALLTHROUGH*/
 1125: 	}
 1126: 	default:
 1127: 		cam_periph_async(periph, code, path, arg);
 1128: 		break;
 1129: 	}
 1130: }
 1131: 
 1132: static void
 1133: dasysctlinit(void *context, int pending)
 1134: {
 1135: 	struct cam_periph *periph;
 1136: 	struct da_softc *softc;
 1137: 	char tmpstr[80], tmpstr2[80];
 1138: 
 1139: 	periph = (struct cam_periph *)context;
 1140: 	softc = (struct da_softc *)periph->softc;
 1141: 
 1142: 	snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
 1143: 	snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
 1144: 
 1145: 	sysctl_ctx_init(&softc->sysctl_ctx);
 1146: 	softc->flags |= DA_FLAG_SCTX_INIT;
 1147: 	softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
 1148: 		SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
 1149: 		CTLFLAG_RD, 0, tmpstr);
 1150: 	if (softc->sysctl_tree == NULL) {
 1151: 		printf("dasysctlinit: unable to allocate sysctl tree\n");
 1152: 		return;
 1153: 	}
 1154: 
 1155: 	/*
 1156: 	 * Now register the sysctl handler, so the user can the value on
 1157: 	 * the fly.
 1158: 	 */
 1159: 	SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
 1160: 		OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
 1161: 		&softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
 1162: 		"Minimum CDB size");
 1163: }
 1164: 
 1165: static int
 1166: dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
 1167: {
 1168: 	int error, value;
 1169: 
 1170: 	value = *(int *)arg1;
 1171: 
 1172: 	error = sysctl_handle_int(oidp, &value, 0, req);
 1173: 
 1174: 	if ((error != 0)
 1175: 	 || (req->newptr == NULL))
 1176: 		return (error);
 1177: 
 1178: 	/*
 1179: 	 * Acceptable values here are 6, 10 or 12.  It's possible we may
 1180: 	 * support a 16 byte minimum command size in the future, since
 1181: 	 * there are now READ(16) and WRITE(16) commands defined in the
 1182: 	 * SBC-2 spec.
 1183: 	 */
 1184: 	if (value < 6)
 1185: 		value = 6;
 1186: 	else if ((value > 6)
 1187: 	      && (value <= 10))
 1188: 		value = 10;
 1189: 	else if (value > 10)
 1190: 		value = 12;
 1191: 
 1192: 	*(int *)arg1 = value;
 1193: 
 1194: 	return (0);
 1195: }
 1196: 
 1197: static cam_status
 1198: daregister(struct cam_periph *periph, void *arg)
 1199: {
 1200: 	int s;
 1201: 	struct da_softc *softc;
 1202: 	struct ccb_setasync csa;
 1203: 	struct ccb_pathinq cpi;
 1204: 	struct ccb_getdev *cgd;
 1205: 	char tmpstr[80];
 1206: 	caddr_t match;
 1207: 
 1208: 	cgd = (struct ccb_getdev *)arg;
 1209: 	if (periph == NULL) {
 1210: 		printf("daregister: periph was NULL!!\n");
 1211: 		return(CAM_REQ_CMP_ERR);
 1212: 	}
 1213: 
 1214: 	if (cgd == NULL) {
 1215: 		printf("daregister: no getdev CCB, can't register device\n");
 1216: 		return(CAM_REQ_CMP_ERR);
 1217: 	}
 1218: 
 1219: 	softc = malloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO);
 1220: 	LIST_INIT(&softc->pending_ccbs);
 1221: 	softc->state = DA_STATE_PROBE;
 1222: 	bufq_init(&softc->buf_queue);
 1223: 	if (SID_IS_REMOVABLE(&cgd->inq_data))
 1224: 		softc->flags |= DA_FLAG_PACK_REMOVABLE;
 1225: 	if ((cgd->inq_data.flags & SID_CmdQue) != 0)
 1226: 		softc->flags |= DA_FLAG_TAGGED_QUEUING;
 1227: 
 1228: 	periph->softc = softc;
 1229: 	
 1230: 	cam_extend_set(daperiphs, periph->unit_number, periph);
 1231: 
 1232: 	/*
 1233: 	 * See if this device has any quirks.
 1234: 	 */
 1235: 	match = cam_quirkmatch((caddr_t)&cgd->inq_data,
 1236: 			       (caddr_t)da_quirk_table,
 1237: 			       sizeof(da_quirk_table)/sizeof(*da_quirk_table),
 1238: 			       sizeof(*da_quirk_table), scsi_inquiry_match);
 1239: 
 1240: 	if (match != NULL)
 1241: 		softc->quirks = ((struct da_quirk_entry *)match)->quirks;
 1242: 	else
 1243: 		softc->quirks = DA_Q_NONE;
 1244: 
 1245: 	TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
 1246: 
 1247: 	/* Check if the SIM does not want 6 byte commands */
 1248: 	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
 1249: 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 1250: 	xpt_action((union ccb *)&cpi);
 1251: 	if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
 1252: 		softc->quirks |= DA_Q_NO_6_BYTE;
 1253: 
 1254: 	/*
 1255: 	 * RBC devices don't have to support READ(6), only READ(10).
 1256: 	 */
 1257: 	if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
 1258: 		softc->minimum_cmd_size = 10;
 1259: 	else
 1260: 		softc->minimum_cmd_size = 6;
 1261: 
 1262: 	/*
 1263: 	 * Load the user's default, if any.
 1264: 	 */
 1265: 	snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
 1266: 		 periph->unit_number);
 1267: 	TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
 1268: 
 1269: 	/*
 1270: 	 * 6, 10 and 12 are the currently permissible values.
 1271: 	 */
 1272: 	if (softc->minimum_cmd_size < 6)
 1273: 		softc->minimum_cmd_size = 6;
 1274: 	else if ((softc->minimum_cmd_size > 6)
 1275: 	      && (softc->minimum_cmd_size <= 10))
 1276: 		softc->minimum_cmd_size = 10;
 1277: 	else if (softc->minimum_cmd_size > 12)
 1278: 		softc->minimum_cmd_size = 12;
 1279: 
 1280: 	/*
 1281: 	 * Block our timeout handler while we
 1282: 	 * add this softc to the dev list.
 1283: 	 */
 1284: 	s = splsoftclock();
 1285: 	SLIST_INSERT_HEAD(&softc_list, softc, links);
 1286: 	splx(s);
 1287: 
 1288: 	/*
 1289: 	 * The DA driver supports a blocksize, but
 1290: 	 * we don't know the blocksize until we do 
 1291: 	 * a read capacity.  So, set a flag to
 1292: 	 * indicate that the blocksize is 
 1293: 	 * unavailable right now.  We'll clear the
 1294: 	 * flag as soon as we've done a read capacity.
 1295: 	 */
 1296: 	devstat_add_entry(&softc->device_stats, "da", 
 1297: 			  periph->unit_number, 0,
 1298: 	  		  DEVSTAT_BS_UNAVAILABLE,
 1299: 			  SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI,
 1300: 			  DEVSTAT_PRIORITY_DISK);
 1301: 
 1302: 	/*
 1303: 	 * Register this media as a disk
 1304: 	 */
 1305: 	disk_create(periph->unit_number, &softc->disk, 0, &da_cdevsw);
 1306: 
 1307: 	/*
 1308: 	 * Add async callbacks for bus reset and
 1309: 	 * bus device reset calls.  I don't bother
 1310: 	 * checking if this fails as, in most cases,
 1311: 	 * the system will function just fine without
 1312: 	 * them and the only alternative would be to
 1313: 	 * not attach the device on failure.
 1314: 	 */
 1315: 	xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5);
 1316: 	csa.ccb_h.func_code = XPT_SASYNC_CB;
 1317: 	csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE;
 1318: 	csa.callback = daasync;
 1319: 	csa.callback_arg = periph;
 1320: 	xpt_action((union ccb *)&csa);
 1321: 	/*
 1322: 	 * Lock this peripheral until we are setup.
 1323: 	 * This first call can't block
 1324: 	 */
 1325: 	(void)cam_periph_lock(periph, 0);
 1326: 	xpt_schedule(periph, /*priority*/5);
 1327: 
 1328: 	return(CAM_REQ_CMP);
 1329: }
 1330: 
 1331: static void
 1332: dastart(struct cam_periph *periph, union ccb *start_ccb)
 1333: {
 1334: 	struct da_softc *softc;
 1335: 
 1336: 	softc = (struct da_softc *)periph->softc;
 1337: 
 1338: 	
 1339: 	switch (softc->state) {
 1340: 	case DA_STATE_NORMAL:
 1341: 	{
 1342: 		/* Pull a buffer from the queue and get going on it */		
 1343: 		struct buf *bp;
 1344: 		int s;
 1345: 
 1346: 		/*
 1347: 		 * See if there is a buf with work for us to do..
 1348: 		 */
 1349: 		s = splbio();
 1350: 		bp = bufq_first(&softc->buf_queue);
 1351: 		if (periph->immediate_priority <= periph->pinfo.priority) {
 1352: 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
 1353: 					("queuing for immediate ccb\n"));
 1354: 			start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
 1355: 			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
 1356: 					  periph_links.sle);
 1357: 			periph->immediate_priority = CAM_PRIORITY_NONE;
 1358: 			splx(s);
 1359: 			wakeup(&periph->ccb_list);
 1360: 		} else if (bp == NULL) {
 1361: 			splx(s);
 1362: 			xpt_release_ccb(start_ccb);
 1363: 		} else {
 1364: 			int oldspl;
 1365: 			u_int8_t tag_code;
 1366: 
 1367: 			bufq_remove(&softc->buf_queue, bp);
 1368: 
 1369: 			devstat_start_transaction(&softc->device_stats);
 1370: 
 1371: 			if ((bp->b_flags & B_ORDERED) != 0
 1372: 			 || (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
 1373: 				softc->flags &= ~DA_FLAG_NEED_OTAG;
 1374: 				softc->ordered_tag_count++;
 1375: 				tag_code = MSG_ORDERED_Q_TAG;
 1376: 			} else {
 1377: 				tag_code = MSG_SIMPLE_Q_TAG;
 1378: 			}
 1379: 			scsi_read_write(&start_ccb->csio,
 1380: 					/*retries*/da_retry_count,
 1381: 					dadone,
 1382: 					tag_code,
 1383: 					bp->b_flags & B_READ,
 1384: 					/*byte2*/0,
 1385: 					softc->minimum_cmd_size,
 1386: 					bp->b_pblkno,
 1387: 					bp->b_bcount / softc->params.secsize,
 1388: 					bp->b_data,
 1389: 					bp->b_bcount,
 1390: 					/*sense_len*/SSD_FULL_SIZE,
 1391: 					da_default_timeout * 1000);
 1392: 			start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
 1393: 
 1394: 			/*
 1395: 			 * Block out any asyncronous callbacks
 1396: 			 * while we touch the pending ccb list.
 1397: 			 */
 1398: 			oldspl = splcam();
 1399: 			LIST_INSERT_HEAD(&softc->pending_ccbs,
 1400: 					 &start_ccb->ccb_h, periph_links.le);
 1401: 			splx(oldspl);
 1402: 
 1403: 			/* We expect a unit attention from this device */
 1404: 			if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
 1405: 				start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
 1406: 				softc->flags &= ~DA_FLAG_RETRY_UA;
 1407: 			}
 1408: 
 1409: 			start_ccb->ccb_h.ccb_bp = bp;
 1410: 			bp = bufq_first(&softc->buf_queue);
 1411: 			splx(s);
 1412: 
 1413: 			xpt_action(start_ccb);
 1414: 		}
 1415: 		
 1416: 		if (bp != NULL) {
 1417: 			/* Have more work to do, so ensure we stay scheduled */
 1418: 			xpt_schedule(periph, /* XXX priority */1);
 1419: 		}
 1420: 		break;
 1421: 	}
 1422: 	case DA_STATE_PROBE:
 1423: 	{
 1424: 		struct ccb_scsiio *csio;
 1425: 		struct scsi_read_capacity_data *rcap;
 1426: 
 1427: 		rcap = malloc(sizeof(*rcap), M_TEMP, M_INTWAIT | M_ZERO);
 1428: 		csio = &start_ccb->csio;
 1429: 		scsi_read_capacity(csio,
 1430: 				   /*retries*/4,
 1431: 				   dadone,
 1432: 				   MSG_SIMPLE_Q_TAG,
 1433: 				   rcap,
 1434: 				   SSD_FULL_SIZE,
 1435: 				   /*timeout*/5000);
 1436: 		start_ccb->ccb_h.ccb_bp = NULL;
 1437: 		start_ccb->ccb_h.ccb_state = DA_CCB_PROBE;
 1438: 		xpt_action(start_ccb);
 1439: 		break;
 1440: 	}
 1441: 	}
 1442: }
 1443: 
 1444: static int
 1445: cmd6workaround(union ccb *ccb)
 1446: {
 1447: 	struct scsi_rw_6 cmd6;
 1448: 	struct scsi_rw_10 *cmd10;
 1449: 	struct da_softc *softc;
 1450: 	u_int8_t *cdb;
 1451: 	int frozen;
 1452: 
 1453: 	cdb = ccb->csio.cdb_io.cdb_bytes;
 1454: 
 1455: 	/* Translation only possible if CDB is an array and cmd is R/W6 */
 1456: 	if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
 1457: 	    (*cdb != READ_6 && *cdb != WRITE_6))
 1458: 		return 0;
 1459: 
 1460: 	xpt_print_path(ccb->ccb_h.path);
 1461:  	printf("READ(6)/WRITE(6) not supported, "
 1462: 	       "increasing minimum_cmd_size to 10.\n");
 1463:  	softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
 1464: 	softc->minimum_cmd_size = 10;
 1465: 
 1466: 	bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
 1467: 	cmd10 = (struct scsi_rw_10 *)cdb;
 1468: 	cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
 1469: 	cmd10->byte2 = 0;
 1470: 	scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
 1471: 	cmd10->reserved = 0;
 1472: 	scsi_ulto2b(cmd6.length, cmd10->length);
 1473: 	cmd10->control = cmd6.control;
 1474: 	ccb->csio.cdb_len = sizeof(*cmd10);
 1475: 
 1476: 	/* Requeue request, unfreezing queue if necessary */
 1477: 	frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
 1478:  	ccb->ccb_h.status = CAM_REQUEUE_REQ;
 1479: 	xpt_action(ccb);
 1480: 	if (frozen) {
 1481: 		cam_release_devq(ccb->ccb_h.path,
 1482: 				 /*relsim_flags*/0,
 1483: 				 /*reduction*/0,
 1484: 				 /*timeout*/0,
 1485: 				 /*getcount_only*/0);
 1486: 	}
 1487: 	return (ERESTART);
 1488: }
 1489: 
 1490: static void
 1491: dadone(struct cam_periph *periph, union ccb *done_ccb)
 1492: {
 1493: 	struct da_softc *softc;
 1494: 	struct ccb_scsiio *csio;
 1495: 
 1496: 	softc = (struct da_softc *)periph->softc;
 1497: 	csio = &done_ccb->csio;
 1498: 	switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
 1499: 	case DA_CCB_BUFFER_IO:
 1500: 	{
 1501: 		struct buf *bp;
 1502: 		int    oldspl;
 1503: 
 1504: 		bp = (struct buf *)done_ccb->ccb_h.ccb_bp;
 1505: 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 1506: 			int error;
 1507: 			int s;
 1508: 			int sf;
 1509: 			
 1510: 			if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
 1511: 				sf = SF_RETRY_UA;
 1512: 			else
 1513: 				sf = 0;
 1514: 
 1515: 			/* Retry selection timeouts */
 1516: 			sf |= SF_RETRY_SELTO;
 1517: 
 1518: 			if ((error = daerror(done_ccb, 0, sf)) == ERESTART) {
 1519: 				/*
 1520: 				 * A retry was scheuled, so
 1521: 				 * just return.
 1522: 				 */
 1523: 				return;
 1524: 			}
 1525: 			if (error != 0) {
 1526: 				struct buf *q_bp;
 1527: 
 1528: 				s = splbio();
 1529: 
 1530: 				if (error == ENXIO) {
 1531: 					/*
 1532: 					 * Catastrophic error.  Mark our pack as
 1533: 					 * invalid.
 1534: 					 */
 1535: 					/* XXX See if this is really a media
 1536: 					 *     change first.
 1537: 					 */
 1538: 					xpt_print_path(periph->path);
 1539: 					printf("Invalidating pack\n");
 1540: 					softc->flags |= DA_FLAG_PACK_INVALID;
 1541: 				}
 1542: 
 1543: 				/*
 1544: 				 * return all queued I/O with EIO, so that
 1545: 				 * the client can retry these I/Os in the
 1546: 				 * proper order should it attempt to recover.
 1547: 				 */
 1548: 				while ((q_bp = bufq_first(&softc->buf_queue))
 1549: 					!= NULL) {
 1550: 					bufq_remove(&softc->buf_queue, q_bp);
 1551: 					q_bp->b_resid = q_bp->b_bcount;
 1552: 					q_bp->b_error = EIO;
 1553: 					q_bp->b_flags |= B_ERROR;
 1554: 					biodone(q_bp);
 1555: 				}
 1556: 				splx(s);
 1557: 				bp->b_error = error;
 1558: 				bp->b_resid = bp->b_bcount;
 1559: 				bp->b_flags |= B_ERROR;
 1560: 			} else {
 1561: 				bp->b_resid = csio->resid;
 1562: 				bp->b_error = 0;
 1563: 				if (bp->b_resid != 0)
 1564: 					bp->b_flags |= B_ERROR;
 1565: 			}
 1566: 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 1567: 				cam_release_devq(done_ccb->ccb_h.path,
 1568: 						 /*relsim_flags*/0,
 1569: 						 /*reduction*/0,
 1570: 						 /*timeout*/0,
 1571: 						 /*getcount_only*/0);
 1572: 		} else {
 1573: 			bp->b_resid = csio->resid;
 1574: 			if (csio->resid > 0)
 1575: 				bp->b_flags |= B_ERROR;
 1576: 		}
 1577: 
 1578: 		/*
 1579: 		 * Block out any asyncronous callbacks
 1580: 		 * while we touch the pending ccb list.
 1581: 		 */
 1582: 		oldspl = splcam();
 1583: 		LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
 1584: 		splx(oldspl);
 1585: 
 1586: 		if (softc->device_stats.busy_count == 0)
 1587: 			softc->flags |= DA_FLAG_WENT_IDLE;
 1588: 
 1589: 		devstat_end_transaction_buf(&softc->device_stats, bp);
 1590: 		biodone(bp);
 1591: 		break;
 1592: 	}
 1593: 	case DA_CCB_PROBE:
 1594: 	{
 1595: 		struct	   scsi_read_capacity_data *rdcap;
 1596: 		char	   announce_buf[80];
 1597: 
 1598: 		rdcap = (struct scsi_read_capacity_data *)csio->data_ptr;
 1599: 		
 1600: 		if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 1601: 			struct disk_params *dp;
 1602: 
 1603: 			dasetgeom(periph, rdcap);
 1604: 			dp = &softc->params;
 1605: 			snprintf(announce_buf, sizeof(announce_buf),
 1606: 			        "%luMB (%u %u byte sectors: %dH %dS/T %dC)",
 1607: 				(unsigned long) (((u_int64_t)dp->secsize *
 1608: 				dp->sectors) / (1024*1024)), dp->sectors,
 1609: 				dp->secsize, dp->heads, dp->secs_per_track,
 1610: 				dp->cylinders);
 1611: 		} else {
 1612: 			int	error;
 1613: 
 1614: 			announce_buf[0] = '\0';
 1615: 
 1616: 			/*
 1617: 			 * Retry any UNIT ATTENTION type errors.  They
 1618: 			 * are expected at boot.
 1619: 			 */
 1620: 			error = daerror(done_ccb, 0, SF_RETRY_UA |
 1621: 					SF_RETRY_SELTO | SF_NO_PRINT);
 1622: 			if (error == ERESTART) {
 1623: 				/*
 1624: 				 * A retry was scheuled, so
 1625: 				 * just return.
 1626: 				 */
 1627: 				return;
 1628: 			} else if (error != 0) {
 1629: 				struct scsi_sense_data *sense;
 1630: 				int asc, ascq;
 1631: 				int sense_key, error_code;
 1632: 				int have_sense;
 1633: 				cam_status status;
 1634: 				struct ccb_getdev cgd;
 1635: 
 1636: 				/* Don't wedge this device's queue */
 1637: 				cam_release_devq(done_ccb->ccb_h.path,
 1638: 						 /*relsim_flags*/0,
 1639: 						 /*reduction*/0,
 1640: 						 /*timeout*/0,
 1641: 						 /*getcount_only*/0);
 1642: 
 1643: 				status = done_ccb->ccb_h.status;
 1644: 
 1645: 				xpt_setup_ccb(&cgd.ccb_h, 
 1646: 					      done_ccb->ccb_h.path,
 1647: 					      /* priority */ 1);
 1648: 				cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 1649: 				xpt_action((union ccb *)&cgd);
 1650: 
 1651: 				if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
 1652: 				 || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
 1653: 				 || ((status & CAM_AUTOSNS_VALID) == 0))
 1654: 					have_sense = FALSE;
 1655: 				else
 1656: 					have_sense = TRUE;
 1657: 
 1658: 				if (have_sense) {
 1659: 					sense = &csio->sense_data;
 1660: 					scsi_extract_sense(sense, &error_code,
 1661: 							   &sense_key, 
 1662: 							   &asc, &ascq);
 1663: 				}
 1664: 				/*
 1665: 				 * Attach to anything that claims to be a
 1666: 				 * direct access or optical disk device,
 1667: 				 * as long as it doesn't return a "Logical
 1668: 				 * unit not supported" (0x25) error.
 1669: 				 */
 1670: 				if ((have_sense) && (asc != 0x25)
 1671: 				 && (error_code == SSD_CURRENT_ERROR))
 1672: 					snprintf(announce_buf,
 1673: 					    sizeof(announce_buf),
 1674: 						"Attempt to query device "
 1675: 						"size failed: %s, %s",
 1676: 						scsi_sense_key_text[sense_key],
 1677: 						scsi_sense_desc(asc,ascq,
 1678: 								&cgd.inq_data));
 1679: 				else { 
 1680: 					if (have_sense)
 1681: 						scsi_sense_print(
 1682: 							&done_ccb->csio);
 1683: 					else {
 1684: 						xpt_print_path(periph->path);
 1685: 						printf("got CAM status %#x\n",
 1686: 						       done_ccb->ccb_h.status);
 1687: 					}
 1688: 
 1689: 					xpt_print_path(periph->path);
 1690: 					printf("fatal error, failed" 
 1691: 					       " to attach to device\n");
 1692: 
 1693: 					/*
 1694: 					 * Free up resources.
 1695: 					 */
 1696: 					cam_periph_invalidate(periph);
 1697: 				} 
 1698: 			}
 1699: 		}
 1700: 		free(rdcap, M_TEMP);
 1701: 		if (announce_buf[0] != '\0') {
 1702: 			xpt_announce_periph(periph, announce_buf);
 1703: 			/*
 1704: 			 * Create our sysctl variables, now that we know
 1705: 			 * we have successfully attached.
 1706: 			 */
 1707: 			taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
 1708: 		}
 1709: 		softc->state = DA_STATE_NORMAL;		
 1710: 		/*
 1711: 		 * Since our peripheral may be invalidated by an error
 1712: 		 * above or an external event, we must release our CCB
 1713: 		 * before releasing the probe lock on the peripheral.
 1714: 		 * The peripheral will only go away once the last lock
 1715: 		 * is removed, and we need it around for the CCB release
 1716: 		 * operation.
 1717: 		 */
 1718: 		xpt_release_ccb(done_ccb);
 1719: 		cam_periph_unlock(periph);
 1720: 		return;
 1721: 	}
 1722: 	case DA_CCB_WAITING:
 1723: 	{
 1724: 		/* Caller will release the CCB */
 1725: 		wakeup(&done_ccb->ccb_h.cbfcnp);
 1726: 		return;
 1727: 	}
 1728: 	case DA_CCB_DUMP:
 1729: 		/* No-op.  We're polling */
 1730: 		return;
 1731: 	default:
 1732: 		break;
 1733: 	}
 1734: 	xpt_release_ccb(done_ccb);
 1735: }
 1736: 
 1737: static int
 1738: daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
 1739: {
 1740: 	struct da_softc	  *softc;
 1741: 	struct cam_periph *periph;
 1742: 	int error;
 1743: 
 1744: 	periph = xpt_path_periph(ccb->ccb_h.path);
 1745: 	softc = (struct da_softc *)periph->softc;
 1746: 
 1747:  	/*
 1748: 	 * Automatically detect devices that do not support
 1749:  	 * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
 1750:  	 */
 1751: 	error = 0;
 1752: 	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
 1753: 		error = cmd6workaround(ccb);
 1754: 	} else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
 1755: 		   CAM_SCSI_STATUS_ERROR)
 1756: 	 && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
 1757: 	 && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
 1758: 	 && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
 1759: 	 && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
 1760: 		int sense_key, error_code, asc, ascq;
 1761: 
 1762:  		scsi_extract_sense(&ccb->csio.sense_data,
 1763: 				   &error_code, &sense_key, &asc, &ascq);
 1764: 		if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
 1765:  			error = cmd6workaround(ccb);
 1766: 	}
 1767: 	if (error == ERESTART)
 1768: 		return (ERESTART);
 1769: 
 1770: 	/*
 1771: 	 * XXX
 1772: 	 * Until we have a better way of doing pack validation,
 1773: 	 * don't treat UAs as errors.
 1774: 	 */
 1775: 	sense_flags |= SF_RETRY_UA;
 1776: 	return(cam_periph_error(ccb, cam_flags, sense_flags,
 1777: 				&softc->saved_ccb));
 1778: }
 1779: 
 1780: static void
 1781: daprevent(struct cam_periph *periph, int action)
 1782: {
 1783: 	struct	da_softc *softc;
 1784: 	union	ccb *ccb;		
 1785: 	int	error;
 1786: 		
 1787: 	softc = (struct da_softc *)periph->softc;
 1788: 
 1789: 	if (((action == PR_ALLOW)
 1790: 	  && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
 1791: 	 || ((action == PR_PREVENT)
 1792: 	  && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
 1793: 		return;
 1794: 	}
 1795: 
 1796: 	ccb = cam_periph_getccb(periph, /*priority*/1);
 1797: 
 1798: 	scsi_prevent(&ccb->csio,
 1799: 		     /*retries*/1,
 1800: 		     /*cbcfp*/dadone,
 1801: 		     MSG_SIMPLE_Q_TAG,
 1802: 		     action,
 1803: 		     SSD_FULL_SIZE,
 1804: 		     5000);
 1805: 
 1806: 	error = cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
 1807: 				  /*sense_flags*/0, &softc->device_stats);
 1808: 
 1809: 	if (error == 0) {
 1810: 		if (action == PR_ALLOW)
 1811: 			softc->flags &= ~DA_FLAG_PACK_LOCKED;
 1812: 		else
 1813: 			softc->flags |= DA_FLAG_PACK_LOCKED;
 1814: 	}
 1815: 
 1816: 	xpt_release_ccb(ccb);
 1817: }
 1818: 
 1819: static void
 1820: dasetgeom(struct cam_periph *periph, struct scsi_read_capacity_data * rdcap)
 1821: {
 1822: 	struct ccb_calc_geometry ccg;
 1823: 	struct da_softc *softc;
 1824: 	struct disk_params *dp;
 1825: 
 1826: 	softc = (struct da_softc *)periph->softc;
 1827: 
 1828: 	dp = &softc->params;
 1829: 	dp->secsize = scsi_4btoul(rdcap->length);
 1830: 	dp->sectors = scsi_4btoul(rdcap->addr) + 1;
 1831: 	/*
 1832: 	 * Have the controller provide us with a geometry
 1833: 	 * for this disk.  The only time the geometry
 1834: 	 * matters is when we boot and the controller
 1835: 	 * is the only one knowledgeable enough to come
 1836: 	 * up with something that will make this a bootable
 1837: 	 * device.
 1838: 	 */
 1839: 	xpt_setup_ccb(&ccg.ccb_h, periph->path, /*priority*/1);
 1840: 	ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
 1841: 	ccg.block_size = dp->secsize;
 1842: 	ccg.volume_size = dp->sectors;
 1843: 	ccg.heads = 0;
 1844: 	ccg.secs_per_track = 0;
 1845: 	ccg.cylinders = 0;
 1846: 	xpt_action((union ccb*)&ccg);
 1847: 	dp->heads = ccg.heads;
 1848: 	dp->secs_per_track = ccg.secs_per_track;
 1849: 	dp->cylinders = ccg.cylinders;
 1850: }
 1851: 
 1852: static void
 1853: dasendorderedtag(void *arg)
 1854: {
 1855: 	struct da_softc *softc;
 1856: 	int s;
 1857: 
 1858: 	for (softc = SLIST_FIRST(&softc_list);
 1859: 	     softc != NULL;
 1860: 	     softc = SLIST_NEXT(softc, links)) {
 1861: 		s = splsoftcam();
 1862: 		if ((softc->ordered_tag_count == 0) 
 1863: 		 && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
 1864: 			softc->flags |= DA_FLAG_NEED_OTAG;
 1865: 		}
 1866: 		if (softc->device_stats.busy_count > 0)
 1867: 			softc->flags &= ~DA_FLAG_WENT_IDLE;
 1868: 
 1869: 		softc->ordered_tag_count = 0;
 1870: 		splx(s);
 1871: 	}
 1872: 	/* Queue us up again */
 1873: 	timeout(dasendorderedtag, NULL,
 1874: 		(da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL);
 1875: }
 1876: 
 1877: /*
 1878:  * Step through all DA peripheral drivers, and if the device is still open,
 1879:  * sync the disk cache to physical media.
 1880:  */
 1881: static void
 1882: dashutdown(void * arg, int howto)
 1883: {
 1884: 	struct cam_periph *periph;
 1885: 	struct da_softc *softc;
 1886: 
 1887: 	for (periph = TAILQ_FIRST(&dadriver.units); periph != NULL;
 1888: 	     periph = TAILQ_NEXT(periph, unit_links)) {
 1889: 		union ccb ccb;
 1890: 		softc = (struct da_softc *)periph->softc;
 1891: 
 1892: 		/*
 1893: 		 * We only sync the cache if the drive is still open, and
 1894: 		 * if the drive is capable of it..
 1895: 		 */
 1896: 		if (((softc->flags & DA_FLAG_OPEN) == 0)
 1897: 		 || (softc->quirks & DA_Q_NO_SYNC_CACHE))
 1898: 			continue;
 1899: 
 1900: 		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
 1901: 
 1902: 		ccb.ccb_h.ccb_state = DA_CCB_DUMP;
 1903: 		scsi_synchronize_cache(&ccb.csio,
 1904: 				       /*retries*/1,
 1905: 				       /*cbfcnp*/dadone,
 1906: 				       MSG_SIMPLE_Q_TAG,
 1907: 				       /*begin_lba*/0, /* whole disk */
 1908: 				       /*lb_count*/0,
 1909: 				       SSD_FULL_SIZE,
 1910: 				       5 * 60 * 1000);
 1911: 
 1912: 		xpt_polled_action(&ccb);
 1913: 
 1914: 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 1915: 			if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
 1916: 			     CAM_SCSI_STATUS_ERROR)
 1917: 			 && (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
 1918: 				int error_code, sense_key, asc, ascq;
 1919: 
 1920: 				scsi_extract_sense(&ccb.csio.sense_data,
 1921: 						   &error_code, &sense_key,
 1922: 						   &asc, &ascq);
 1923: 
 1924: 				if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
 1925: 					scsi_sense_print(&ccb.csio);
 1926: 			} else {
 1927: 				xpt_print_path(periph->path);
 1928: 				printf("Synchronize cache failed, status "
 1929: 				       "== 0x%x, scsi status == 0x%x\n",
 1930: 				       ccb.ccb_h.status, ccb.csio.scsi_status);
 1931: 			}
 1932: 		}
 1933: 
 1934: 		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
 1935: 			cam_release_devq(ccb.ccb_h.path,
 1936: 					 /*relsim_flags*/0,
 1937: 					 /*reduction*/0,
 1938: 					 /*timeout*/0,
 1939: 					 /*getcount_only*/0);
 1940: 
 1941: 	}
 1942: }
 1943: 
 1944: #else /* !_KERNEL */
 1945: 
 1946: /*
 1947:  * XXX This is only left out of the kernel build to silence warnings.  If,
 1948:  * for some reason this function is used in the kernel, the ifdefs should
 1949:  * be moved so it is included both in the kernel and userland.
 1950:  */
 1951: void
 1952: scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
 1953: 		 void (*cbfcnp)(struct cam_periph *, union ccb *),
 1954: 		 u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
 1955: 		 u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
 1956: 		 u_int32_t timeout)
 1957: {
 1958: 	struct scsi_format_unit *scsi_cmd;
 1959: 
 1960: 	scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
 1961: 	scsi_cmd->opcode = FORMAT_UNIT;
 1962: 	scsi_cmd->byte2 = byte2;
 1963: 	scsi_ulto2b(ileave, scsi_cmd->interleave);
 1964: 
 1965: 	cam_fill_csio(csio,
 1966: 		      retries,
 1967: 		      cbfcnp,
 1968: 		      /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
 1969: 		      tag_action,
 1970: 		      data_ptr,
 1971: 		      dxfer_len,
 1972: 		      sense_len,
 1973: 		      sizeof(*scsi_cmd),
 1974: 		      timeout);
 1975: }
 1976: 
 1977: #endif /* _KERNEL */