The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/scsi/scsi_da.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD: releng/9.2/sys/cam/scsi/scsi_da.c 253200 2013-07-11 09:10:17Z smh $");
   31 
   32 #include <sys/param.h>
   33 
   34 #ifdef _KERNEL
   35 #include <sys/systm.h>
   36 #include <sys/kernel.h>
   37 #include <sys/bio.h>
   38 #include <sys/sysctl.h>
   39 #include <sys/taskqueue.h>
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <sys/conf.h>
   43 #include <sys/devicestat.h>
   44 #include <sys/eventhandler.h>
   45 #include <sys/malloc.h>
   46 #include <sys/cons.h>
   47 #include <sys/endian.h>
   48 #include <sys/proc.h>
   49 #include <geom/geom.h>
   50 #include <geom/geom_disk.h>
   51 #endif /* _KERNEL */
   52 
   53 #ifndef _KERNEL
   54 #include <stdio.h>
   55 #include <string.h>
   56 #endif /* _KERNEL */
   57 
   58 #include <cam/cam.h>
   59 #include <cam/cam_ccb.h>
   60 #include <cam/cam_periph.h>
   61 #include <cam/cam_xpt_periph.h>
   62 #include <cam/cam_sim.h>
   63 
   64 #include <cam/scsi/scsi_message.h>
   65 
   66 #ifndef _KERNEL 
   67 #include <cam/scsi/scsi_da.h>
   68 #endif /* !_KERNEL */
   69 
   70 #ifdef _KERNEL
   71 typedef enum {
   72         DA_STATE_PROBE_RC,
   73         DA_STATE_PROBE_RC16,
   74         DA_STATE_PROBE_LBP,
   75         DA_STATE_PROBE_BLK_LIMITS,
   76         DA_STATE_PROBE_BDC,
   77         DA_STATE_PROBE_ATA,
   78         DA_STATE_NORMAL
   79 } da_state;
   80 
   81 typedef enum {
   82         DA_FLAG_PACK_INVALID    = 0x001,
   83         DA_FLAG_NEW_PACK        = 0x002,
   84         DA_FLAG_PACK_LOCKED     = 0x004,
   85         DA_FLAG_PACK_REMOVABLE  = 0x008,
   86         DA_FLAG_SAW_MEDIA       = 0x010,
   87         DA_FLAG_NEED_OTAG       = 0x020,
   88         DA_FLAG_WENT_IDLE       = 0x040,
   89         DA_FLAG_RETRY_UA        = 0x080,
   90         DA_FLAG_OPEN            = 0x100,
   91         DA_FLAG_SCTX_INIT       = 0x200,
   92         DA_FLAG_CAN_RC16        = 0x400,
   93         DA_FLAG_PROBED          = 0x800         
   94 } da_flags;
   95 
   96 typedef enum {
   97         DA_Q_NONE               = 0x00,
   98         DA_Q_NO_SYNC_CACHE      = 0x01,
   99         DA_Q_NO_6_BYTE          = 0x02,
  100         DA_Q_NO_PREVENT         = 0x04,
  101         DA_Q_4K                 = 0x08
  102 } da_quirks;
  103 
  104 #define DA_Q_BIT_STRING         \
  105         "\020"                  \
  106         "\001NO_SYNC_CACHE"     \
  107         "\002NO_6_BYTE"         \
  108         "\003NO_PREVENT"        \
  109         "\0044K"
  110 
  111 typedef enum {
  112         DA_CCB_PROBE_RC         = 0x01,
  113         DA_CCB_PROBE_RC16       = 0x02,
  114         DA_CCB_PROBE_LBP        = 0x03,
  115         DA_CCB_PROBE_BLK_LIMITS = 0x04,
  116         DA_CCB_PROBE_BDC        = 0x05,
  117         DA_CCB_PROBE_ATA        = 0x06,
  118         DA_CCB_BUFFER_IO        = 0x07,
  119         DA_CCB_WAITING          = 0x08,
  120         DA_CCB_DUMP             = 0x0A,
  121         DA_CCB_DELETE           = 0x0B,
  122         DA_CCB_TUR              = 0x0C,
  123         DA_CCB_TYPE_MASK        = 0x0F,
  124         DA_CCB_RETRY_UA         = 0x10
  125 } da_ccb_state;
  126 
  127 /*
  128  * Order here is important for method choice
  129  *
  130  * We prefer ATA_TRIM as tests run against a Sandforce 2281 SSD attached to
  131  * LSI 2008 (mps) controller (FW: v12, Drv: v14) resulted 20% quicker deletes
  132  * using ATA_TRIM than the corresponding UNMAP results for a real world mysql
  133  * import taking 5mins.
  134  *
  135  */
  136 typedef enum {
  137         DA_DELETE_NONE,
  138         DA_DELETE_DISABLE,
  139         DA_DELETE_ATA_TRIM,
  140         DA_DELETE_UNMAP,
  141         DA_DELETE_WS16,
  142         DA_DELETE_WS10,
  143         DA_DELETE_ZERO,
  144         DA_DELETE_MIN = DA_DELETE_ATA_TRIM,
  145         DA_DELETE_MAX = DA_DELETE_ZERO
  146 } da_delete_methods;
  147 
  148 static const char *da_delete_method_names[] =
  149     { "NONE", "DISABLE", "ATA_TRIM", "UNMAP", "WS16", "WS10", "ZERO" };
  150 static const char *da_delete_method_desc[] =
  151     { "NONE", "DISABLED", "ATA TRIM", "UNMAP", "WRITE SAME(16) with UNMAP",
  152       "WRITE SAME(10) with UNMAP", "ZERO" };
  153 
  154 /* Offsets into our private area for storing information */
  155 #define ccb_state       ppriv_field0
  156 #define ccb_bp          ppriv_ptr1
  157 
  158 struct disk_params {
  159         u_int8_t  heads;
  160         u_int32_t cylinders;
  161         u_int8_t  secs_per_track;
  162         u_int32_t secsize;      /* Number of bytes/sector */
  163         u_int64_t sectors;      /* total number sectors */
  164         u_int     stripesize;
  165         u_int     stripeoffset;
  166 };
  167 
  168 #define UNMAP_RANGE_MAX         0xffffffff
  169 #define UNMAP_HEAD_SIZE         8
  170 #define UNMAP_RANGE_SIZE        16
  171 #define UNMAP_MAX_RANGES        2048 /* Protocol Max is 4095 */
  172 #define UNMAP_BUF_SIZE          ((UNMAP_MAX_RANGES * UNMAP_RANGE_SIZE) + \
  173                                 UNMAP_HEAD_SIZE)
  174 
  175 #define WS10_MAX_BLKS           0xffff
  176 #define WS16_MAX_BLKS           0xffffffff
  177 #define ATA_TRIM_MAX_RANGES     ((UNMAP_BUF_SIZE / \
  178         (ATA_DSM_RANGE_SIZE * ATA_DSM_BLK_SIZE)) * ATA_DSM_BLK_SIZE)
  179 
  180 struct da_softc {
  181         struct   bio_queue_head bio_queue;
  182         struct   bio_queue_head delete_queue;
  183         struct   bio_queue_head delete_run_queue;
  184         SLIST_ENTRY(da_softc) links;
  185         LIST_HEAD(, ccb_hdr) pending_ccbs;
  186         da_state state;
  187         da_flags flags; 
  188         da_quirks quirks;
  189         int      sort_io_queue;
  190         int      minimum_cmd_size;
  191         int      error_inject;
  192         int      ordered_tag_count;
  193         int      outstanding_cmds;
  194         int      trim_max_ranges;
  195         int      delete_running;
  196         int      tur;
  197         int      delete_available;      /* Delete methods possibly available */
  198         uint32_t                unmap_max_ranges;
  199         uint32_t                unmap_max_lba;
  200         uint64_t                ws_max_blks;
  201         da_delete_methods       delete_method;
  202         struct   disk_params params;
  203         struct   disk *disk;
  204         union    ccb saved_ccb;
  205         struct task             sysctl_task;
  206         struct sysctl_ctx_list  sysctl_ctx;
  207         struct sysctl_oid       *sysctl_tree;
  208         struct callout          sendordered_c;
  209         uint64_t wwpn;
  210         uint8_t  unmap_buf[UNMAP_BUF_SIZE];
  211         struct scsi_read_capacity_data_long rcaplong;
  212         struct callout          mediapoll_c;
  213 };
  214 
  215 #define dadeleteflag(softc, delete_method, enable)                      \
  216         if (enable) {                                                   \
  217                 softc->delete_available |= (1 << delete_method);        \
  218         } else {                                                        \
  219                 softc->delete_available &= ~(1 << delete_method);       \
  220         }
  221 
  222 struct da_quirk_entry {
  223         struct scsi_inquiry_pattern inq_pat;
  224         da_quirks quirks;
  225 };
  226 
  227 static const char quantum[] = "QUANTUM";
  228 static const char microp[] = "MICROP";
  229 
  230 static struct da_quirk_entry da_quirk_table[] =
  231 {
  232         /* SPI, FC devices */
  233         {
  234                 /*
  235                  * Fujitsu M2513A MO drives.
  236                  * Tested devices: M2513A2 firmware versions 1200 & 1300.
  237                  * (dip switch selects whether T_DIRECT or T_OPTICAL device)
  238                  * Reported by: W.Scholten <whs@xs4all.nl>
  239                  */
  240                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
  241                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  242         },
  243         {
  244                 /* See above. */
  245                 {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
  246                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  247         },
  248         {
  249                 /*
  250                  * This particular Fujitsu drive doesn't like the
  251                  * synchronize cache command.
  252                  * Reported by: Tom Jackson <toj@gorilla.net>
  253                  */
  254                 {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
  255                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  256         },
  257         {
  258                 /*
  259                  * This drive doesn't like the synchronize cache command
  260                  * either.  Reported by: Matthew Jacob <mjacob@feral.com>
  261                  * in NetBSD PR kern/6027, August 24, 1998.
  262                  */
  263                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
  264                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  265         },
  266         {
  267                 /*
  268                  * This drive doesn't like the synchronize cache command
  269                  * either.  Reported by: Hellmuth Michaelis (hm@kts.org)
  270                  * (PR 8882).
  271                  */
  272                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
  273                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  274         },
  275         {
  276                 /*
  277                  * Doesn't like the synchronize cache command.
  278                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
  279                  */
  280                 {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
  281                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  282         },
  283         {
  284                 /*
  285                  * Doesn't like the synchronize cache command.
  286                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
  287                  */
  288                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
  289                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  290         },
  291         {
  292                 /*
  293                  * Doesn't like the synchronize cache command.
  294                  */
  295                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
  296                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  297         },
  298         {
  299                 /*
  300                  * Doesn't like the synchronize cache command.
  301                  * Reported by: walter@pelissero.de
  302                  */
  303                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
  304                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  305         },
  306         {
  307                 /*
  308                  * Doesn't work correctly with 6 byte reads/writes.
  309                  * Returns illegal request, and points to byte 9 of the
  310                  * 6-byte CDB.
  311                  * Reported by:  Adam McDougall <bsdx@spawnet.com>
  312                  */
  313                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
  314                 /*quirks*/ DA_Q_NO_6_BYTE
  315         },
  316         {
  317                 /* See above. */
  318                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
  319                 /*quirks*/ DA_Q_NO_6_BYTE
  320         },
  321         {
  322                 /*
  323                  * Doesn't like the synchronize cache command.
  324                  * Reported by: walter@pelissero.de
  325                  */
  326                 {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
  327                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  328         },
  329         {
  330                 /*
  331                  * The CISS RAID controllers do not support SYNC_CACHE
  332                  */
  333                 {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
  334                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  335         },
  336         /* USB mass storage devices supported by umass(4) */
  337         {
  338                 /*
  339                  * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
  340                  * PR: kern/51675
  341                  */
  342                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
  343                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  344         },
  345         {
  346                 /*
  347                  * Power Quotient Int. (PQI) USB flash key
  348                  * PR: kern/53067
  349                  */
  350                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
  351                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  352         },
  353         {
  354                 /*
  355                  * Creative Nomad MUVO mp3 player (USB)
  356                  * PR: kern/53094
  357                  */
  358                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
  359                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
  360         },
  361         {
  362                 /*
  363                  * Jungsoft NEXDISK USB flash key
  364                  * PR: kern/54737
  365                  */
  366                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
  367                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  368         },
  369         {
  370                 /*
  371                  * FreeDik USB Mini Data Drive
  372                  * PR: kern/54786
  373                  */
  374                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive",
  375                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  376         },
  377         {
  378                 /*
  379                  * Sigmatel USB Flash MP3 Player
  380                  * PR: kern/57046
  381                  */
  382                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
  383                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
  384         },
  385         {
  386                 /*
  387                  * Neuros USB Digital Audio Computer
  388                  * PR: kern/63645
  389                  */
  390                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
  391                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  392         },
  393         {
  394                 /*
  395                  * SEAGRAND NP-900 MP3 Player
  396                  * PR: kern/64563
  397                  */
  398                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
  399                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
  400         },
  401         {
  402                 /*
  403                  * iRiver iFP MP3 player (with UMS Firmware)
  404                  * PR: kern/54881, i386/63941, kern/66124
  405                  */
  406                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"},
  407                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  408         },
  409         {
  410                 /*
  411                  * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
  412                  * PR: kern/70158
  413                  */
  414                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
  415                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  416         },
  417         {
  418                 /*
  419                  * ZICPlay USB MP3 Player with FM
  420                  * PR: kern/75057
  421                  */
  422                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
  423                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  424         },
  425         {
  426                 /*
  427                  * TEAC USB floppy mechanisms
  428                  */
  429                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
  430                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  431         },
  432         {
  433                 /*
  434                  * Kingston DataTraveler II+ USB Pen-Drive.
  435                  * Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
  436                  */
  437                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+",
  438                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  439         },
  440         {
  441                 /*
  442                  * USB DISK Pro PMAP
  443                  * Reported by: jhs
  444                  * PR: usb/96381
  445                  */
  446                 {T_DIRECT, SIP_MEDIA_REMOVABLE, " ", "USB DISK Pro", "PMAP"},
  447                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  448         },
  449         {
  450                 /*
  451                  * Motorola E398 Mobile Phone (TransFlash memory card).
  452                  * Reported by: Wojciech A. Koszek <dunstan@FreeBSD.czest.pl>
  453                  * PR: usb/89889
  454                  */
  455                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone",
  456                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  457         },
  458         {
  459                 /*
  460                  * Qware BeatZkey! Pro
  461                  * PR: usb/79164
  462                  */
  463                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE",
  464                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  465         },
  466         {
  467                 /*
  468                  * Time DPA20B 1GB MP3 Player
  469                  * PR: usb/81846
  470                  */
  471                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*",
  472                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  473         },
  474         {
  475                 /*
  476                  * Samsung USB key 128Mb
  477                  * PR: usb/90081
  478                  */
  479                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb",
  480                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  481         },
  482         {
  483                 /*
  484                  * Kingston DataTraveler 2.0 USB Flash memory.
  485                  * PR: usb/89196
  486                  */
  487                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0",
  488                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  489         },
  490         {
  491                 /*
  492                  * Creative MUVO Slim mp3 player (USB)
  493                  * PR: usb/86131
  494                  */
  495                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
  496                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
  497                 },
  498         {
  499                 /*
  500                  * United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3)
  501                  * PR: usb/80487
  502                  */
  503                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK",
  504                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  505         },
  506         {
  507                 /*
  508                  * SanDisk Micro Cruzer 128MB
  509                  * PR: usb/75970
  510                  */
  511                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer",
  512                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  513         },
  514         {
  515                 /*
  516                  * TOSHIBA TransMemory USB sticks
  517                  * PR: kern/94660
  518                  */
  519                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory",
  520                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  521         },
  522         {
  523                 /*
  524                  * PNY USB Flash keys
  525                  * PR: usb/75578, usb/72344, usb/65436 
  526                  */
  527                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
  528                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  529         },
  530         {
  531                 /*
  532                  * Genesys 6-in-1 Card Reader
  533                  * PR: usb/94647
  534                  */
  535                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
  536                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  537         },
  538         {
  539                 /*
  540                  * Rekam Digital CAMERA
  541                  * PR: usb/98713
  542                  */
  543                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*",
  544                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  545         },
  546         {
  547                 /*
  548                  * iRiver H10 MP3 player
  549                  * PR: usb/102547
  550                  */
  551                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*",
  552                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  553         },
  554         {
  555                 /*
  556                  * iRiver U10 MP3 player
  557                  * PR: usb/92306
  558                  */
  559                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "U10*",
  560                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  561         },
  562         {
  563                 /*
  564                  * X-Micro Flash Disk
  565                  * PR: usb/96901
  566                  */
  567                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro", "Flash Disk",
  568                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  569         },
  570         {
  571                 /*
  572                  * EasyMP3 EM732X USB 2.0 Flash MP3 Player
  573                  * PR: usb/96546
  574                  */
  575                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*",
  576                 "1.00"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  577         },
  578         {
  579                 /*
  580                  * Denver MP3 player
  581                  * PR: usb/107101
  582                  */
  583                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "DENVER", "MP3 PLAYER",
  584                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  585         },
  586         {
  587                 /*
  588                  * Philips USB Key Audio KEY013
  589                  * PR: usb/68412
  590                  */
  591                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "PHILIPS", "Key*", "*"},
  592                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
  593         },
  594         {
  595                 /*
  596                  * JNC MP3 Player
  597                  * PR: usb/94439
  598                  */
  599                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JNC*" , "MP3 Player*",
  600                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  601         },
  602         {
  603                 /*
  604                  * SAMSUNG MP0402H
  605                  * PR: usb/108427
  606                  */
  607                 {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "MP0402H", "*"},
  608                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  609         },
  610         {
  611                 /*
  612                  * I/O Magic USB flash - Giga Bank
  613                  * PR: usb/108810
  614                  */
  615                 {T_DIRECT, SIP_MEDIA_FIXED, "GS-Magic", "stor*", "*"},
  616                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  617         },
  618         {
  619                 /*
  620                  * JoyFly 128mb USB Flash Drive
  621                  * PR: 96133
  622                  */
  623                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "Flash Disk*",
  624                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  625         },
  626         {
  627                 /*
  628                  * ChipsBnk usb stick
  629                  * PR: 103702
  630                  */
  631                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ChipsBnk", "USB*",
  632                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  633         },
  634         {
  635                 /*
  636                  * Storcase (Kingston) InfoStation IFS FC2/SATA-R 201A
  637                  * PR: 129858
  638                  */
  639                 {T_DIRECT, SIP_MEDIA_FIXED, "IFS", "FC2/SATA-R*",
  640                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  641         },
  642         {
  643                 /*
  644                  * Samsung YP-U3 mp3-player
  645                  * PR: 125398
  646                  */
  647                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Samsung", "YP-U3",
  648                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  649         },
  650         {
  651                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Netac", "OnlyDisk*",
  652                  "2000"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  653         },
  654         {
  655                 /*
  656                  * Sony Cyber-Shot DSC cameras
  657                  * PR: usb/137035
  658                  */
  659                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
  660                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
  661         },
  662         {
  663                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler G3",
  664                  "1.00"}, /*quirks*/ DA_Q_NO_PREVENT
  665         },
  666         /* ATA/SATA devices over SAS/USB/... */
  667         {
  668                 /* Hitachi Advanced Format (4k) drives */
  669                 { T_DIRECT, SIP_MEDIA_FIXED, "Hitachi", "H??????????E3*", "*" },
  670                 /*quirks*/DA_Q_4K
  671         },
  672         {
  673                 /* Samsung Advanced Format (4k) drives */
  674                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD155UI*", "*" },
  675                 /*quirks*/DA_Q_4K
  676         },
  677         {
  678                 /* Samsung Advanced Format (4k) drives */
  679                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD155UI*", "*" },
  680                 /*quirks*/DA_Q_4K
  681         },
  682         {
  683                 /* Samsung Advanced Format (4k) drives */
  684                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD204UI*", "*" },
  685                 /*quirks*/DA_Q_4K
  686         },
  687         {
  688                 /* Samsung Advanced Format (4k) drives */
  689                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD204UI*", "*" },
  690                 /*quirks*/DA_Q_4K
  691         },
  692         {
  693                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  694                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DL*", "*" },
  695                 /*quirks*/DA_Q_4K
  696         },
  697         {
  698                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  699                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DL", "*", "*" },
  700                 /*quirks*/DA_Q_4K
  701         },
  702         {
  703                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  704                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???DM*", "*" },
  705                 /*quirks*/DA_Q_4K
  706         },
  707         {
  708                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  709                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???DM*", "*", "*" },
  710                 /*quirks*/DA_Q_4K
  711         },
  712         {
  713                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  714                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DM*", "*" },
  715                 /*quirks*/DA_Q_4K
  716         },
  717         {
  718                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  719                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DM", "*", "*" },
  720                 /*quirks*/DA_Q_4K
  721         },
  722         {
  723                 /* Seagate Momentus Advanced Format (4k) drives */
  724                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500423AS*", "*" },
  725                 /*quirks*/DA_Q_4K
  726         },
  727         {
  728                 /* Seagate Momentus Advanced Format (4k) drives */
  729                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "3AS*", "*" },
  730                 /*quirks*/DA_Q_4K
  731         },
  732         {
  733                 /* Seagate Momentus Advanced Format (4k) drives */
  734                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500424AS*", "*" },
  735                 /*quirks*/DA_Q_4K
  736         },
  737         {
  738                 /* Seagate Momentus Advanced Format (4k) drives */
  739                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "4AS*", "*" },
  740                 /*quirks*/DA_Q_4K
  741         },
  742         {
  743                 /* Seagate Momentus Advanced Format (4k) drives */
  744                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640423AS*", "*" },
  745                 /*quirks*/DA_Q_4K
  746         },
  747         {
  748                 /* Seagate Momentus Advanced Format (4k) drives */
  749                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "3AS*", "*" },
  750                 /*quirks*/DA_Q_4K
  751         },
  752         {
  753                 /* Seagate Momentus Advanced Format (4k) drives */
  754                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640424AS*", "*" },
  755                 /*quirks*/DA_Q_4K
  756         },
  757         {
  758                 /* Seagate Momentus Advanced Format (4k) drives */
  759                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "4AS*", "*" },
  760                 /*quirks*/DA_Q_4K
  761         },
  762         {
  763                 /* Seagate Momentus Advanced Format (4k) drives */
  764                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750420AS*", "*" },
  765                 /*quirks*/DA_Q_4K
  766         },
  767         {
  768                 /* Seagate Momentus Advanced Format (4k) drives */
  769                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "0AS*", "*" },
  770                 /*quirks*/DA_Q_4K
  771         },
  772         {
  773                 /* Seagate Momentus Advanced Format (4k) drives */
  774                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750422AS*", "*" },
  775                 /*quirks*/DA_Q_4K
  776         },
  777         {
  778                 /* Seagate Momentus Advanced Format (4k) drives */
  779                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "2AS*", "*" },
  780                 /*quirks*/DA_Q_4K
  781         },
  782         {
  783                 /* Seagate Momentus Advanced Format (4k) drives */
  784                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750423AS*", "*" },
  785                 /*quirks*/DA_Q_4K
  786         },
  787         {
  788                 /* Seagate Momentus Advanced Format (4k) drives */
  789                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "3AS*", "*" },
  790                 /*quirks*/DA_Q_4K
  791         },
  792         {
  793                 /* Seagate Momentus Thin Advanced Format (4k) drives */
  794                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???LT*", "*" },
  795                 /*quirks*/DA_Q_4K
  796         },
  797         {
  798                 /* Seagate Momentus Thin Advanced Format (4k) drives */
  799                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???LT*", "*", "*" },
  800                 /*quirks*/DA_Q_4K
  801         },
  802         {
  803                 /* WDC Caviar Green Advanced Format (4k) drives */
  804                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RS*", "*" },
  805                 /*quirks*/DA_Q_4K
  806         },
  807         {
  808                 /* WDC Caviar Green Advanced Format (4k) drives */
  809                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RS*", "*" },
  810                 /*quirks*/DA_Q_4K
  811         },
  812         {
  813                 /* WDC Caviar Green Advanced Format (4k) drives */
  814                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RX*", "*" },
  815                 /*quirks*/DA_Q_4K
  816         },
  817         {
  818                 /* WDC Caviar Green Advanced Format (4k) drives */
  819                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RX*", "*" },
  820                 /*quirks*/DA_Q_4K
  821         },
  822         {
  823                 /* WDC Caviar Green Advanced Format (4k) drives */
  824                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RS*", "*" },
  825                 /*quirks*/DA_Q_4K
  826         },
  827         {
  828                 /* WDC Caviar Green Advanced Format (4k) drives */
  829                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RS*", "*" },
  830                 /*quirks*/DA_Q_4K
  831         },
  832         {
  833                 /* WDC Caviar Green Advanced Format (4k) drives */
  834                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RX*", "*" },
  835                 /*quirks*/DA_Q_4K
  836         },
  837         {
  838                 /* WDC Caviar Green Advanced Format (4k) drives */
  839                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RX*", "*" },
  840                 /*quirks*/DA_Q_4K
  841         },
  842         {
  843                 /* WDC Scorpio Black Advanced Format (4k) drives */
  844                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PKT*", "*" },
  845                 /*quirks*/DA_Q_4K
  846         },
  847         {
  848                 /* WDC Scorpio Black Advanced Format (4k) drives */
  849                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PKT*", "*" },
  850                 /*quirks*/DA_Q_4K
  851         },
  852         {
  853                 /* WDC Scorpio Black Advanced Format (4k) drives */
  854                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PKT*", "*" },
  855                 /*quirks*/DA_Q_4K
  856         },
  857         {
  858                 /* WDC Scorpio Black Advanced Format (4k) drives */
  859                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PKT*", "*" },
  860                 /*quirks*/DA_Q_4K
  861         },
  862         {
  863                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  864                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PVT*", "*" },
  865                 /*quirks*/DA_Q_4K
  866         },
  867         {
  868                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  869                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PVT*", "*" },
  870                 /*quirks*/DA_Q_4K
  871         },
  872         {
  873                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  874                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PVT*", "*" },
  875                 /*quirks*/DA_Q_4K
  876         },
  877         {
  878                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  879                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PVT*", "*" },
  880                 /*quirks*/DA_Q_4K
  881         },
  882         {
  883                 /*
  884                  * Olympus FE-210 camera
  885                  */
  886                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "FE210*",
  887                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  888         },
  889         {
  890                 /*
  891                  * LG UP3S MP3 player
  892                  */
  893                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "LG", "UP3S",
  894                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  895         },
  896         {
  897                 /*
  898                  * Laser MP3-2GA13 MP3 player
  899                  */
  900                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "(HS) Flash Disk",
  901                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
  902         },
  903         {
  904                 /*
  905                  * LaCie external 250GB Hard drive des by Porsche
  906                  * Submitted by: Ben Stuyts <ben@altesco.nl>
  907                  * PR: 121474
  908                  */
  909                 {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HM250JI", "*"},
  910                 /*quirks*/ DA_Q_NO_SYNC_CACHE
  911         },
  912         /* SATA SSDs */
  913         {
  914                 /*
  915                  * Corsair Force 2 SSDs
  916                  * 4k optimised & trim only works in 4k requests + 4k aligned
  917                  */
  918                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair CSSD-F*", "*" },
  919                 /*quirks*/DA_Q_4K
  920         },
  921         {
  922                 /*
  923                  * Corsair Force 3 SSDs
  924                  * 4k optimised & trim only works in 4k requests + 4k aligned
  925                  */
  926                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force 3*", "*" },
  927                 /*quirks*/DA_Q_4K
  928         },
  929         {
  930                 /*
  931                  * Corsair Force GT SSDs
  932                  * 4k optimised & trim only works in 4k requests + 4k aligned
  933                  */
  934                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force GT*", "*" },
  935                 /*quirks*/DA_Q_4K
  936         },
  937         {
  938                 /*
  939                  * Crucial M4 SSDs
  940                  * 4k optimised & trim only works in 4k requests + 4k aligned
  941                  */
  942                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "M4-CT???M4SSD2*", "*" },
  943                 /*quirks*/DA_Q_4K
  944         },
  945         {
  946                 /*
  947                  * Crucial RealSSD C300 SSDs
  948                  * 4k optimised
  949                  */
  950                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "C300-CTFDDAC???MAG*",
  951                 "*" }, /*quirks*/DA_Q_4K
  952         },
  953         {
  954                 /*
  955                  * Intel 320 Series SSDs
  956                  * 4k optimised & trim only works in 4k requests + 4k aligned
  957                  */
  958                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSA2CW*", "*" },
  959                 /*quirks*/DA_Q_4K
  960         },
  961         {
  962                 /*
  963                  * Intel 330 Series SSDs
  964                  * 4k optimised & trim only works in 4k requests + 4k aligned
  965                  */
  966                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2CT*", "*" },
  967                 /*quirks*/DA_Q_4K
  968         },
  969         {
  970                 /*
  971                  * Intel 510 Series SSDs
  972                  * 4k optimised & trim only works in 4k requests + 4k aligned
  973                  */
  974                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2MH*", "*" },
  975                 /*quirks*/DA_Q_4K
  976         },
  977         {
  978                 /*
  979                  * Intel 520 Series SSDs
  980                  * 4k optimised & trim only works in 4k requests + 4k aligned
  981                  */
  982                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BW*", "*" },
  983                 /*quirks*/DA_Q_4K
  984         },
  985         {
  986                 /*
  987                  * Kingston E100 Series SSDs
  988                  * 4k optimised & trim only works in 4k requests + 4k aligned
  989                  */
  990                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SE100S3*", "*" },
  991                 /*quirks*/DA_Q_4K
  992         },
  993         {
  994                 /*
  995                  * Kingston HyperX 3k SSDs
  996                  * 4k optimised & trim only works in 4k requests + 4k aligned
  997                  */
  998                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SH103S3*", "*" },
  999                 /*quirks*/DA_Q_4K
 1000         },
 1001         {
 1002                 /*
 1003                  * OCZ Agility 3 SSDs
 1004                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1005                  */
 1006                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-AGILITY3*", "*" },
 1007                 /*quirks*/DA_Q_4K
 1008         },
 1009         {
 1010                 /*
 1011                  * OCZ Deneva R Series SSDs
 1012                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1013                  */
 1014                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "DENRSTE251M45*", "*" },
 1015                 /*quirks*/DA_Q_4K
 1016         },
 1017         {
 1018                 /*
 1019                  * OCZ Vertex 2 SSDs (inc pro series)
 1020                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1021                  */
 1022                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ?VERTEX2*", "*" },
 1023                 /*quirks*/DA_Q_4K
 1024         },
 1025         {
 1026                 /*
 1027                  * OCZ Vertex 3 SSDs
 1028                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1029                  */
 1030                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX3*", "*" },
 1031                 /*quirks*/DA_Q_4K
 1032         },
 1033         {
 1034                 /*
 1035                  * OCZ Vertex 4 SSDs
 1036                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1037                  */
 1038                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX4*", "*" },
 1039                 /*quirks*/DA_Q_4K
 1040         },
 1041         {
 1042                 /*
 1043                  * Samsung 830 Series SSDs
 1044                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1045                  */
 1046                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG SSD 830 Series*", "*" },
 1047                 /*quirks*/DA_Q_4K
 1048         },
 1049         {
 1050                 /*
 1051                  * SuperTalent TeraDrive CT SSDs
 1052                  * 4k optimised & trim only works in 4k requests + 4k aligned
 1053                  */
 1054                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "FTM??CT25H*", "*" },
 1055                 /*quirks*/DA_Q_4K
 1056         },
 1057         {
 1058                 /*
 1059                  * XceedIOPS SATA SSDs
 1060                  * 4k optimised
 1061                  */
 1062                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SG9XCS2D*", "*" },
 1063                 /*quirks*/DA_Q_4K
 1064         },
 1065 };
 1066 
 1067 static  disk_strategy_t dastrategy;
 1068 static  dumper_t        dadump;
 1069 static  periph_init_t   dainit;
 1070 static  void            daasync(void *callback_arg, u_int32_t code,
 1071                                 struct cam_path *path, void *arg);
 1072 static  void            dasysctlinit(void *context, int pending);
 1073 static  int             dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
 1074 static  int             dadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
 1075 static  int             dadeletemaxsysctl(SYSCTL_HANDLER_ARGS);
 1076 static  void            dadeletemethodset(struct da_softc *softc,
 1077                                           da_delete_methods delete_method);
 1078 static  off_t           dadeletemaxsize(struct da_softc *softc,
 1079                                         da_delete_methods delete_method);
 1080 static  void            dadeletemethodchoose(struct da_softc *softc,
 1081                                              da_delete_methods default_method);
 1082 static  void            daprobedone(struct cam_periph *periph, union ccb *ccb);
 1083 
 1084 static  periph_ctor_t   daregister;
 1085 static  periph_dtor_t   dacleanup;
 1086 static  periph_start_t  dastart;
 1087 static  periph_oninv_t  daoninvalidate;
 1088 static  void            dadone(struct cam_periph *periph,
 1089                                union ccb *done_ccb);
 1090 static  int             daerror(union ccb *ccb, u_int32_t cam_flags,
 1091                                 u_int32_t sense_flags);
 1092 static void             daprevent(struct cam_periph *periph, int action);
 1093 static void             dareprobe(struct cam_periph *periph);
 1094 static void             dasetgeom(struct cam_periph *periph, uint32_t block_len,
 1095                                   uint64_t maxsector,
 1096                                   struct scsi_read_capacity_data_long *rcaplong,
 1097                                   size_t rcap_size);
 1098 static timeout_t        dasendorderedtag;
 1099 static void             dashutdown(void *arg, int howto);
 1100 static timeout_t        damediapoll;
 1101 
 1102 #ifndef DA_DEFAULT_POLL_PERIOD
 1103 #define DA_DEFAULT_POLL_PERIOD  3
 1104 #endif
 1105 
 1106 #ifndef DA_DEFAULT_TIMEOUT
 1107 #define DA_DEFAULT_TIMEOUT 60   /* Timeout in seconds */
 1108 #endif
 1109 
 1110 #ifndef DA_DEFAULT_RETRY
 1111 #define DA_DEFAULT_RETRY        4
 1112 #endif
 1113 
 1114 #ifndef DA_DEFAULT_SEND_ORDERED
 1115 #define DA_DEFAULT_SEND_ORDERED 1
 1116 #endif
 1117 
 1118 #define DA_SIO (softc->sort_io_queue >= 0 ? \
 1119     softc->sort_io_queue : cam_sort_io_queues)
 1120 
 1121 static int da_poll_period = DA_DEFAULT_POLL_PERIOD;
 1122 static int da_retry_count = DA_DEFAULT_RETRY;
 1123 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
 1124 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
 1125 
 1126 static SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
 1127             "CAM Direct Access Disk driver");
 1128 SYSCTL_INT(_kern_cam_da, OID_AUTO, poll_period, CTLFLAG_RW,
 1129            &da_poll_period, 0, "Media polling period in seconds");
 1130 TUNABLE_INT("kern.cam.da.poll_period", &da_poll_period);
 1131 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
 1132            &da_retry_count, 0, "Normal I/O retry count");
 1133 TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
 1134 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
 1135            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
 1136 TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
 1137 SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RW,
 1138            &da_send_ordered, 0, "Send Ordered Tags");
 1139 TUNABLE_INT("kern.cam.da.send_ordered", &da_send_ordered);
 1140 
 1141 /*
 1142  * DA_ORDEREDTAG_INTERVAL determines how often, relative
 1143  * to the default timeout, we check to see whether an ordered
 1144  * tagged transaction is appropriate to prevent simple tag
 1145  * starvation.  Since we'd like to ensure that there is at least
 1146  * 1/2 of the timeout length left for a starved transaction to
 1147  * complete after we've sent an ordered tag, we must poll at least
 1148  * four times in every timeout period.  This takes care of the worst
 1149  * case where a starved transaction starts during an interval that
 1150  * meets the requirement "don't send an ordered tag" test so it takes
 1151  * us two intervals to determine that a tag must be sent.
 1152  */
 1153 #ifndef DA_ORDEREDTAG_INTERVAL
 1154 #define DA_ORDEREDTAG_INTERVAL 4
 1155 #endif
 1156 
 1157 static struct periph_driver dadriver =
 1158 {
 1159         dainit, "da",
 1160         TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
 1161 };
 1162 
 1163 PERIPHDRIVER_DECLARE(da, dadriver);
 1164 
 1165 static MALLOC_DEFINE(M_SCSIDA, "scsi_da", "scsi_da buffers");
 1166 
 1167 static int
 1168 daopen(struct disk *dp)
 1169 {
 1170         struct cam_periph *periph;
 1171         struct da_softc *softc;
 1172         int unit;
 1173         int error;
 1174 
 1175         periph = (struct cam_periph *)dp->d_drv1;
 1176         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
 1177                 return (ENXIO);
 1178         }
 1179 
 1180         cam_periph_lock(periph);
 1181         if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
 1182                 cam_periph_unlock(periph);
 1183                 cam_periph_release(periph);
 1184                 return (error);
 1185         }
 1186 
 1187         unit = periph->unit_number;
 1188         softc = (struct da_softc *)periph->softc;
 1189         softc->flags |= DA_FLAG_OPEN;
 1190 
 1191         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
 1192             ("daopen\n"));
 1193 
 1194         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
 1195                 /* Invalidate our pack information. */
 1196                 softc->flags &= ~DA_FLAG_PACK_INVALID;
 1197         }
 1198 
 1199         dareprobe(periph);
 1200 
 1201         /* Wait for the disk size update.  */
 1202         error = cam_periph_sleep(periph, &softc->disk->d_mediasize, PRIBIO,
 1203             "dareprobe", 0);
 1204         if (error != 0)
 1205                 xpt_print(periph->path, "unable to retrieve capacity data");
 1206 
 1207         if (periph->flags & CAM_PERIPH_INVALID ||
 1208             softc->disk->d_sectorsize == 0 ||
 1209             softc->disk->d_mediasize == 0)
 1210                 error = ENXIO;
 1211 
 1212         if (error == 0 && (softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
 1213             (softc->quirks & DA_Q_NO_PREVENT) == 0)
 1214                 daprevent(periph, PR_PREVENT);
 1215 
 1216         if (error == 0)
 1217                 softc->flags |= DA_FLAG_SAW_MEDIA;
 1218 
 1219         cam_periph_unhold(periph);
 1220         cam_periph_unlock(periph);
 1221 
 1222         if (error != 0) {
 1223                 softc->flags &= ~DA_FLAG_OPEN;
 1224                 cam_periph_release(periph);
 1225         }
 1226 
 1227         return (error);
 1228 }
 1229 
 1230 static int
 1231 daclose(struct disk *dp)
 1232 {
 1233         struct  cam_periph *periph;
 1234         struct  da_softc *softc;
 1235 
 1236         periph = (struct cam_periph *)dp->d_drv1;
 1237         cam_periph_lock(periph);
 1238         if (cam_periph_hold(periph, PRIBIO) != 0) {
 1239                 cam_periph_unlock(periph);
 1240                 cam_periph_release(periph);
 1241                 return (0);
 1242         }
 1243 
 1244         softc = (struct da_softc *)periph->softc;
 1245 
 1246         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
 1247             ("daclose\n"));
 1248 
 1249         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0
 1250          && (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
 1251                 union   ccb *ccb;
 1252 
 1253                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 1254 
 1255                 scsi_synchronize_cache(&ccb->csio,
 1256                                        /*retries*/1,
 1257                                        /*cbfcnp*/dadone,
 1258                                        MSG_SIMPLE_Q_TAG,
 1259                                        /*begin_lba*/0,/* Cover the whole disk */
 1260                                        /*lb_count*/0,
 1261                                        SSD_FULL_SIZE,
 1262                                        5 * 60 * 1000);
 1263 
 1264                 cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
 1265                                   /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
 1266                                   softc->disk->d_devstat);
 1267                 xpt_release_ccb(ccb);
 1268 
 1269         }
 1270 
 1271         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
 1272                 if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
 1273                         daprevent(periph, PR_ALLOW);
 1274                 /*
 1275                  * If we've got removeable media, mark the blocksize as
 1276                  * unavailable, since it could change when new media is
 1277                  * inserted.
 1278                  */
 1279                 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
 1280         }
 1281 
 1282         softc->flags &= ~DA_FLAG_OPEN;
 1283         cam_periph_unhold(periph);
 1284         cam_periph_unlock(periph);
 1285         cam_periph_release(periph);
 1286         return (0);     
 1287 }
 1288 
 1289 static void
 1290 daschedule(struct cam_periph *periph)
 1291 {
 1292         struct da_softc *softc = (struct da_softc *)periph->softc;
 1293         uint32_t prio;
 1294 
 1295         if (softc->state != DA_STATE_NORMAL)
 1296                 return;
 1297 
 1298         /* Check if cam_periph_getccb() was called. */
 1299         prio = periph->immediate_priority;
 1300 
 1301         /* Check if we have more work to do. */
 1302         if (bioq_first(&softc->bio_queue) ||
 1303             (!softc->delete_running && bioq_first(&softc->delete_queue)) ||
 1304             softc->tur) {
 1305                 prio = CAM_PRIORITY_NORMAL;
 1306         }
 1307 
 1308         /* Schedule CCB if any of above is true. */
 1309         if (prio != CAM_PRIORITY_NONE)
 1310                 xpt_schedule(periph, prio);
 1311 }
 1312 
 1313 /*
 1314  * Actually translate the requested transfer into one the physical driver
 1315  * can understand.  The transfer is described by a buf and will include
 1316  * only one physical transfer.
 1317  */
 1318 static void
 1319 dastrategy(struct bio *bp)
 1320 {
 1321         struct cam_periph *periph;
 1322         struct da_softc *softc;
 1323         
 1324         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 1325         softc = (struct da_softc *)periph->softc;
 1326 
 1327         cam_periph_lock(periph);
 1328 
 1329         /*
 1330          * If the device has been made invalid, error out
 1331          */
 1332         if ((softc->flags & DA_FLAG_PACK_INVALID)) {
 1333                 cam_periph_unlock(periph);
 1334                 biofinish(bp, NULL, ENXIO);
 1335                 return;
 1336         }
 1337 
 1338         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastrategy(%p)\n", bp));
 1339 
 1340         /*
 1341          * Place it in the queue of disk activities for this disk
 1342          */
 1343         if (bp->bio_cmd == BIO_DELETE) {
 1344                 if (bp->bio_bcount == 0)
 1345                         biodone(bp);
 1346                 else if (DA_SIO)
 1347                         bioq_disksort(&softc->delete_queue, bp);
 1348                 else
 1349                         bioq_insert_tail(&softc->delete_queue, bp);
 1350         } else if (DA_SIO) {
 1351                 bioq_disksort(&softc->bio_queue, bp);
 1352         } else {
 1353                 bioq_insert_tail(&softc->bio_queue, bp);
 1354         }
 1355 
 1356         /*
 1357          * Schedule ourselves for performing the work.
 1358          */
 1359         daschedule(periph);
 1360         cam_periph_unlock(periph);
 1361 
 1362         return;
 1363 }
 1364 
 1365 static int
 1366 dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
 1367 {
 1368         struct      cam_periph *periph;
 1369         struct      da_softc *softc;
 1370         u_int       secsize;
 1371         struct      ccb_scsiio csio;
 1372         struct      disk *dp;
 1373         int         error = 0;
 1374 
 1375         dp = arg;
 1376         periph = dp->d_drv1;
 1377         softc = (struct da_softc *)periph->softc;
 1378         cam_periph_lock(periph);
 1379         secsize = softc->params.secsize;
 1380         
 1381         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
 1382                 cam_periph_unlock(periph);
 1383                 return (ENXIO);
 1384         }
 1385 
 1386         if (length > 0) {
 1387                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 1388                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
 1389                 scsi_read_write(&csio,
 1390                                 /*retries*/0,
 1391                                 dadone,
 1392                                 MSG_ORDERED_Q_TAG,
 1393                                 /*read*/SCSI_RW_WRITE,
 1394                                 /*byte2*/0,
 1395                                 /*minimum_cmd_size*/ softc->minimum_cmd_size,
 1396                                 offset / secsize,
 1397                                 length / secsize,
 1398                                 /*data_ptr*/(u_int8_t *) virtual,
 1399                                 /*dxfer_len*/length,
 1400                                 /*sense_len*/SSD_FULL_SIZE,
 1401                                 da_default_timeout * 1000);
 1402                 xpt_polled_action((union ccb *)&csio);
 1403 
 1404                 error = cam_periph_error((union ccb *)&csio,
 1405                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
 1406                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
 1407                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
 1408                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
 1409                 if (error != 0)
 1410                         printf("Aborting dump due to I/O error.\n");
 1411                 cam_periph_unlock(periph);
 1412                 return (error);
 1413         }
 1414                 
 1415         /*
 1416          * Sync the disk cache contents to the physical media.
 1417          */
 1418         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
 1419 
 1420                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 1421                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
 1422                 scsi_synchronize_cache(&csio,
 1423                                        /*retries*/0,
 1424                                        /*cbfcnp*/dadone,
 1425                                        MSG_SIMPLE_Q_TAG,
 1426                                        /*begin_lba*/0,/* Cover the whole disk */
 1427                                        /*lb_count*/0,
 1428                                        SSD_FULL_SIZE,
 1429                                        5 * 60 * 1000);
 1430                 xpt_polled_action((union ccb *)&csio);
 1431 
 1432                 error = cam_periph_error((union ccb *)&csio,
 1433                     0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
 1434                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
 1435                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
 1436                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
 1437                 if (error != 0)
 1438                         xpt_print(periph->path, "Synchronize cache failed\n");
 1439         }
 1440         cam_periph_unlock(periph);
 1441         return (error);
 1442 }
 1443 
 1444 static int
 1445 dagetattr(struct bio *bp)
 1446 {
 1447         int ret;
 1448         struct cam_periph *periph;
 1449 
 1450         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 1451         cam_periph_lock(periph);
 1452         ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
 1453             periph->path);
 1454         cam_periph_unlock(periph);
 1455         if (ret == 0)
 1456                 bp->bio_completed = bp->bio_length;
 1457         return ret;
 1458 }
 1459 
 1460 static void
 1461 dainit(void)
 1462 {
 1463         cam_status status;
 1464 
 1465         /*
 1466          * Install a global async callback.  This callback will
 1467          * receive async callbacks like "new device found".
 1468          */
 1469         status = xpt_register_async(AC_FOUND_DEVICE, daasync, NULL, NULL);
 1470 
 1471         if (status != CAM_REQ_CMP) {
 1472                 printf("da: Failed to attach master async callback "
 1473                        "due to status 0x%x!\n", status);
 1474         } else if (da_send_ordered) {
 1475 
 1476                 /* Register our shutdown event handler */
 1477                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 
 1478                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
 1479                     printf("dainit: shutdown event registration failed!\n");
 1480         }
 1481 }
 1482 
 1483 /*
 1484  * Callback from GEOM, called when it has finished cleaning up its
 1485  * resources.
 1486  */
 1487 static void
 1488 dadiskgonecb(struct disk *dp)
 1489 {
 1490         struct cam_periph *periph;
 1491 
 1492         periph = (struct cam_periph *)dp->d_drv1;
 1493         cam_periph_release(periph);
 1494 }
 1495 
 1496 static void
 1497 daoninvalidate(struct cam_periph *periph)
 1498 {
 1499         struct da_softc *softc;
 1500 
 1501         softc = (struct da_softc *)periph->softc;
 1502 
 1503         /*
 1504          * De-register any async callbacks.
 1505          */
 1506         xpt_register_async(0, daasync, periph, periph->path);
 1507 
 1508         softc->flags |= DA_FLAG_PACK_INVALID;
 1509 
 1510         /*
 1511          * Return all queued I/O with ENXIO.
 1512          * XXX Handle any transactions queued to the card
 1513          *     with XPT_ABORT_CCB.
 1514          */
 1515         bioq_flush(&softc->bio_queue, NULL, ENXIO);
 1516         bioq_flush(&softc->delete_queue, NULL, ENXIO);
 1517 
 1518         /*
 1519          * Tell GEOM that we've gone away, we'll get a callback when it is
 1520          * done cleaning up its resources.
 1521          */
 1522         disk_gone(softc->disk);
 1523 
 1524         xpt_print(periph->path, "lost device - %d outstanding, %d refs\n",
 1525                   softc->outstanding_cmds, periph->refcount);
 1526 }
 1527 
 1528 static void
 1529 dacleanup(struct cam_periph *periph)
 1530 {
 1531         struct da_softc *softc;
 1532 
 1533         softc = (struct da_softc *)periph->softc;
 1534 
 1535         xpt_print(periph->path, "removing device entry\n");
 1536         cam_periph_unlock(periph);
 1537 
 1538         /*
 1539          * If we can't free the sysctl tree, oh well...
 1540          */
 1541         if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
 1542             && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
 1543                 xpt_print(periph->path, "can't remove sysctl context\n");
 1544         }
 1545 
 1546         callout_drain(&softc->mediapoll_c);
 1547         disk_destroy(softc->disk);
 1548         callout_drain(&softc->sendordered_c);
 1549         free(softc, M_DEVBUF);
 1550         cam_periph_lock(periph);
 1551 }
 1552 
 1553 static void
 1554 daasync(void *callback_arg, u_int32_t code,
 1555         struct cam_path *path, void *arg)
 1556 {
 1557         struct cam_periph *periph;
 1558         struct da_softc *softc;
 1559 
 1560         periph = (struct cam_periph *)callback_arg;
 1561         switch (code) {
 1562         case AC_FOUND_DEVICE:
 1563         {
 1564                 struct ccb_getdev *cgd;
 1565                 cam_status status;
 1566  
 1567                 cgd = (struct ccb_getdev *)arg;
 1568                 if (cgd == NULL)
 1569                         break;
 1570 
 1571                 if (cgd->protocol != PROTO_SCSI)
 1572                         break;
 1573 
 1574                 if (SID_TYPE(&cgd->inq_data) != T_DIRECT
 1575                     && SID_TYPE(&cgd->inq_data) != T_RBC
 1576                     && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
 1577                         break;
 1578 
 1579                 /*
 1580                  * Allocate a peripheral instance for
 1581                  * this device and start the probe
 1582                  * process.
 1583                  */
 1584                 status = cam_periph_alloc(daregister, daoninvalidate,
 1585                                           dacleanup, dastart,
 1586                                           "da", CAM_PERIPH_BIO,
 1587                                           cgd->ccb_h.path, daasync,
 1588                                           AC_FOUND_DEVICE, cgd);
 1589 
 1590                 if (status != CAM_REQ_CMP
 1591                  && status != CAM_REQ_INPROG)
 1592                         printf("daasync: Unable to attach to new device "
 1593                                 "due to status 0x%x\n", status);
 1594                 return;
 1595         }
 1596         case AC_ADVINFO_CHANGED:
 1597         {
 1598                 uintptr_t buftype;
 1599 
 1600                 buftype = (uintptr_t)arg;
 1601                 if (buftype == CDAI_TYPE_PHYS_PATH) {
 1602                         struct da_softc *softc;
 1603 
 1604                         softc = periph->softc;
 1605                         disk_attr_changed(softc->disk, "GEOM::physpath",
 1606                                           M_NOWAIT);
 1607                 }
 1608                 break;
 1609         }
 1610         case AC_UNIT_ATTENTION:
 1611         {
 1612                 union ccb *ccb;
 1613                 int error_code, sense_key, asc, ascq;
 1614 
 1615                 softc = (struct da_softc *)periph->softc;
 1616                 ccb = (union ccb *)arg;
 1617 
 1618                 /*
 1619                  * Handle all UNIT ATTENTIONs except our own,
 1620                  * as they will be handled by daerror().
 1621                  */
 1622                 if (xpt_path_periph(ccb->ccb_h.path) != periph &&
 1623                     scsi_extract_sense_ccb(ccb,
 1624                      &error_code, &sense_key, &asc, &ascq)) {
 1625                         if (asc == 0x2A && ascq == 0x09) {
 1626                                 xpt_print(ccb->ccb_h.path,
 1627                                     "capacity data has changed\n");
 1628                                 dareprobe(periph);
 1629                         } else if (asc == 0x28 && ascq == 0x00)
 1630                                 disk_media_changed(softc->disk, M_NOWAIT);
 1631                 }
 1632                 cam_periph_async(periph, code, path, arg);
 1633                 break;
 1634         }
 1635         case AC_SCSI_AEN:
 1636                 softc = (struct da_softc *)periph->softc;
 1637                 if (!softc->tur) {
 1638                         if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
 1639                                 softc->tur = 1;
 1640                                 daschedule(periph);
 1641                         }
 1642                 }
 1643                 /* FALLTHROUGH */
 1644         case AC_SENT_BDR:
 1645         case AC_BUS_RESET:
 1646         {
 1647                 struct ccb_hdr *ccbh;
 1648 
 1649                 softc = (struct da_softc *)periph->softc;
 1650                 /*
 1651                  * Don't fail on the expected unit attention
 1652                  * that will occur.
 1653                  */
 1654                 softc->flags |= DA_FLAG_RETRY_UA;
 1655                 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
 1656                         ccbh->ccb_state |= DA_CCB_RETRY_UA;
 1657                 break;
 1658         }
 1659         default:
 1660                 break;
 1661         }
 1662         cam_periph_async(periph, code, path, arg);
 1663 }
 1664 
 1665 static void
 1666 dasysctlinit(void *context, int pending)
 1667 {
 1668         struct cam_periph *periph;
 1669         struct da_softc *softc;
 1670         char tmpstr[80], tmpstr2[80];
 1671         struct ccb_trans_settings cts;
 1672 
 1673         periph = (struct cam_periph *)context;
 1674         /*
 1675          * periph was held for us when this task was enqueued
 1676          */
 1677         if (periph->flags & CAM_PERIPH_INVALID) {
 1678                 cam_periph_release(periph);
 1679                 return;
 1680         }
 1681 
 1682         softc = (struct da_softc *)periph->softc;
 1683         snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
 1684         snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
 1685 
 1686         sysctl_ctx_init(&softc->sysctl_ctx);
 1687         softc->flags |= DA_FLAG_SCTX_INIT;
 1688         softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
 1689                 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
 1690                 CTLFLAG_RD, 0, tmpstr);
 1691         if (softc->sysctl_tree == NULL) {
 1692                 printf("dasysctlinit: unable to allocate sysctl tree\n");
 1693                 cam_periph_release(periph);
 1694                 return;
 1695         }
 1696 
 1697         /*
 1698          * Now register the sysctl handler, so the user can change the value on
 1699          * the fly.
 1700          */
 1701         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1702                 OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
 1703                 softc, 0, dadeletemethodsysctl, "A",
 1704                 "BIO_DELETE execution method");
 1705         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1706                 OID_AUTO, "delete_max", CTLTYPE_U64 | CTLFLAG_RW,
 1707                 softc, 0, dadeletemaxsysctl, "Q",
 1708                 "Maximum BIO_DELETE size");
 1709         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1710                 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
 1711                 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
 1712                 "Minimum CDB size");
 1713         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1714                 OID_AUTO, "sort_io_queue", CTLFLAG_RW, &softc->sort_io_queue, 0,
 1715                 "Sort IO queue to try and optimise disk access patterns");
 1716 
 1717         SYSCTL_ADD_INT(&softc->sysctl_ctx,
 1718                        SYSCTL_CHILDREN(softc->sysctl_tree),
 1719                        OID_AUTO,
 1720                        "error_inject",
 1721                        CTLFLAG_RW,
 1722                        &softc->error_inject,
 1723                        0,
 1724                        "error_inject leaf");
 1725 
 1726 
 1727         /*
 1728          * Add some addressing info.
 1729          */
 1730         memset(&cts, 0, sizeof (cts));
 1731         xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
 1732         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 1733         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1734         cam_periph_lock(periph);
 1735         xpt_action((union ccb *)&cts);
 1736         cam_periph_unlock(periph);
 1737         if (cts.ccb_h.status != CAM_REQ_CMP) {
 1738                 cam_periph_release(periph);
 1739                 return;
 1740         }
 1741         if (cts.protocol == PROTO_SCSI && cts.transport == XPORT_FC) {
 1742                 struct ccb_trans_settings_fc *fc = &cts.xport_specific.fc;
 1743                 if (fc->valid & CTS_FC_VALID_WWPN) {
 1744                         softc->wwpn = fc->wwpn;
 1745                         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1746                             SYSCTL_CHILDREN(softc->sysctl_tree),
 1747                             OID_AUTO, "wwpn", CTLFLAG_RD,
 1748                             &softc->wwpn, "World Wide Port Name");
 1749                 }
 1750         }
 1751         cam_periph_release(periph);
 1752 }
 1753 
 1754 static int
 1755 dadeletemaxsysctl(SYSCTL_HANDLER_ARGS)
 1756 {
 1757         int error;
 1758         uint64_t value;
 1759         struct da_softc *softc;
 1760 
 1761         softc = (struct da_softc *)arg1;
 1762 
 1763         value = softc->disk->d_delmaxsize;
 1764         error = sysctl_handle_64(oidp, &value, 0, req);
 1765         if ((error != 0) || (req->newptr == NULL))
 1766                 return (error);
 1767 
 1768         /* only accept values smaller than the calculated value */
 1769         if (value > dadeletemaxsize(softc, softc->delete_method)) {
 1770                 return (EINVAL);
 1771         }
 1772         softc->disk->d_delmaxsize = value;
 1773 
 1774         return (0);
 1775 }
 1776 
 1777 static int
 1778 dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
 1779 {
 1780         int error, value;
 1781 
 1782         value = *(int *)arg1;
 1783 
 1784         error = sysctl_handle_int(oidp, &value, 0, req);
 1785 
 1786         if ((error != 0)
 1787          || (req->newptr == NULL))
 1788                 return (error);
 1789 
 1790         /*
 1791          * Acceptable values here are 6, 10, 12 or 16.
 1792          */
 1793         if (value < 6)
 1794                 value = 6;
 1795         else if ((value > 6)
 1796               && (value <= 10))
 1797                 value = 10;
 1798         else if ((value > 10)
 1799               && (value <= 12))
 1800                 value = 12;
 1801         else if (value > 12)
 1802                 value = 16;
 1803 
 1804         *(int *)arg1 = value;
 1805 
 1806         return (0);
 1807 }
 1808 
 1809 static void
 1810 dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method)
 1811 {
 1812 
 1813 
 1814         softc->delete_method = delete_method;
 1815         softc->disk->d_delmaxsize = dadeletemaxsize(softc, delete_method);
 1816 
 1817         if (softc->delete_method > DA_DELETE_DISABLE)
 1818                 softc->disk->d_flags |= DISKFLAG_CANDELETE;
 1819         else
 1820                 softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
 1821 }
 1822 
 1823 static off_t
 1824 dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method)
 1825 {
 1826         off_t sectors;
 1827 
 1828         switch(delete_method) {
 1829         case DA_DELETE_UNMAP:
 1830                 sectors = (off_t)softc->unmap_max_lba * softc->unmap_max_ranges;
 1831                 break;
 1832         case DA_DELETE_ATA_TRIM:
 1833                 sectors = (off_t)ATA_DSM_RANGE_MAX * softc->trim_max_ranges;
 1834                 break;
 1835         case DA_DELETE_WS16:
 1836                 sectors = (off_t)min(softc->ws_max_blks, WS16_MAX_BLKS);
 1837                 break;
 1838         case DA_DELETE_ZERO:
 1839         case DA_DELETE_WS10:
 1840                 sectors = (off_t)min(softc->ws_max_blks, WS10_MAX_BLKS);
 1841                 break;
 1842         default:
 1843                 return 0;
 1844         }
 1845 
 1846         return (off_t)softc->params.secsize *
 1847             min(sectors, (off_t)softc->params.sectors);
 1848 }
 1849 
 1850 static void
 1851 daprobedone(struct cam_periph *periph, union ccb *ccb)
 1852 {
 1853         struct da_softc *softc;
 1854 
 1855         softc = (struct da_softc *)periph->softc;
 1856 
 1857         dadeletemethodchoose(softc, DA_DELETE_NONE);
 1858 
 1859         if (bootverbose && (softc->flags & DA_FLAG_PROBED) == 0) {
 1860                 char buf[80];
 1861                 int i, sep;
 1862 
 1863                 snprintf(buf, sizeof(buf), "Delete methods: <");
 1864                 sep = 0;
 1865                 for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
 1866                         if (softc->delete_available & (1 << i)) {
 1867                                 if (sep) {
 1868                                         strlcat(buf, ",", sizeof(buf));
 1869                                 } else {
 1870                                     sep = 1;
 1871                                 }
 1872                                 strlcat(buf, da_delete_method_names[i],
 1873                                     sizeof(buf));
 1874                                 if (i == softc->delete_method) {
 1875                                         strlcat(buf, "(*)", sizeof(buf));
 1876                                 }
 1877                         }
 1878                 }
 1879                 if (sep == 0) {
 1880                         if (softc->delete_method == DA_DELETE_NONE) 
 1881                                 strlcat(buf, "NONE(*)", sizeof(buf));
 1882                         else
 1883                                 strlcat(buf, "DISABLED(*)", sizeof(buf));
 1884                 }
 1885                 strlcat(buf, ">", sizeof(buf));
 1886                 printf("%s%d: %s\n", periph->periph_name,
 1887                     periph->unit_number, buf);
 1888         }
 1889 
 1890         /*
 1891          * Since our peripheral may be invalidated by an error
 1892          * above or an external event, we must release our CCB
 1893          * before releasing the probe lock on the peripheral.
 1894          * The peripheral will only go away once the last lock
 1895          * is removed, and we need it around for the CCB release
 1896          * operation.
 1897          */
 1898         xpt_release_ccb(ccb);
 1899         softc->state = DA_STATE_NORMAL;
 1900         daschedule(periph);
 1901         wakeup(&softc->disk->d_mediasize);
 1902         if ((softc->flags & DA_FLAG_PROBED) == 0) {
 1903                 softc->flags |= DA_FLAG_PROBED;
 1904                 cam_periph_unhold(periph);
 1905         } else
 1906                 cam_periph_release_locked(periph);
 1907 }
 1908 
 1909 static void
 1910 dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method)
 1911 {
 1912         int i, delete_method;
 1913 
 1914         delete_method = default_method;
 1915 
 1916         /*
 1917          * Use the pre-defined order to choose the best
 1918          * performing delete.
 1919          */
 1920         for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
 1921                 if (softc->delete_available & (1 << i)) {
 1922                         dadeletemethodset(softc, i);
 1923                         return;
 1924                 }
 1925         }
 1926         dadeletemethodset(softc, delete_method);
 1927 }
 1928 
 1929 static int
 1930 dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
 1931 {
 1932         char buf[16];
 1933         const char *p;
 1934         struct da_softc *softc;
 1935         int i, error, value;
 1936 
 1937         softc = (struct da_softc *)arg1;
 1938 
 1939         value = softc->delete_method;
 1940         if (value < 0 || value > DA_DELETE_MAX)
 1941                 p = "UNKNOWN";
 1942         else
 1943                 p = da_delete_method_names[value];
 1944         strncpy(buf, p, sizeof(buf));
 1945         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
 1946         if (error != 0 || req->newptr == NULL)
 1947                 return (error);
 1948         for (i = 0; i <= DA_DELETE_MAX; i++) {
 1949                 if (!(softc->delete_available & (1 << i)) ||
 1950                     strcmp(buf, da_delete_method_names[i]) != 0)
 1951                         continue;
 1952                 dadeletemethodset(softc, i);
 1953                 return (0);
 1954         }
 1955         return (EINVAL);
 1956 }
 1957 
 1958 static cam_status
 1959 daregister(struct cam_periph *periph, void *arg)
 1960 {
 1961         struct da_softc *softc;
 1962         struct ccb_pathinq cpi;
 1963         struct ccb_getdev *cgd;
 1964         char tmpstr[80];
 1965         caddr_t match;
 1966 
 1967         cgd = (struct ccb_getdev *)arg;
 1968         if (cgd == NULL) {
 1969                 printf("daregister: no getdev CCB, can't register device\n");
 1970                 return(CAM_REQ_CMP_ERR);
 1971         }
 1972 
 1973         softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
 1974             M_NOWAIT|M_ZERO);
 1975 
 1976         if (softc == NULL) {
 1977                 printf("daregister: Unable to probe new device. "
 1978                        "Unable to allocate softc\n");                           
 1979                 return(CAM_REQ_CMP_ERR);
 1980         }
 1981 
 1982         LIST_INIT(&softc->pending_ccbs);
 1983         softc->state = DA_STATE_PROBE_RC;
 1984         bioq_init(&softc->bio_queue);
 1985         bioq_init(&softc->delete_queue);
 1986         bioq_init(&softc->delete_run_queue);
 1987         if (SID_IS_REMOVABLE(&cgd->inq_data))
 1988                 softc->flags |= DA_FLAG_PACK_REMOVABLE;
 1989         softc->unmap_max_ranges = UNMAP_MAX_RANGES;
 1990         softc->unmap_max_lba = UNMAP_RANGE_MAX;
 1991         softc->ws_max_blks = WS16_MAX_BLKS;
 1992         softc->trim_max_ranges = ATA_TRIM_MAX_RANGES;
 1993         softc->sort_io_queue = -1;
 1994 
 1995         periph->softc = softc;
 1996 
 1997         /*
 1998          * See if this device has any quirks.
 1999          */
 2000         match = cam_quirkmatch((caddr_t)&cgd->inq_data,
 2001                                (caddr_t)da_quirk_table,
 2002                                sizeof(da_quirk_table)/sizeof(*da_quirk_table),
 2003                                sizeof(*da_quirk_table), scsi_inquiry_match);
 2004 
 2005         if (match != NULL)
 2006                 softc->quirks = ((struct da_quirk_entry *)match)->quirks;
 2007         else
 2008                 softc->quirks = DA_Q_NONE;
 2009 
 2010         /* Check if the SIM does not want 6 byte commands */
 2011         bzero(&cpi, sizeof(cpi));
 2012         xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 2013         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2014         xpt_action((union ccb *)&cpi);
 2015         if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
 2016                 softc->quirks |= DA_Q_NO_6_BYTE;
 2017 
 2018         TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
 2019 
 2020         /*
 2021          * Take an exclusive refcount on the periph while dastart is called
 2022          * to finish the probe.  The reference will be dropped in dadone at
 2023          * the end of probe.
 2024          */
 2025         (void)cam_periph_hold(periph, PRIBIO);
 2026 
 2027         /*
 2028          * Schedule a periodic event to occasionally send an
 2029          * ordered tag to a device.
 2030          */
 2031         callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
 2032         callout_reset(&softc->sendordered_c,
 2033             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
 2034             dasendorderedtag, softc);
 2035 
 2036         cam_periph_unlock(periph);
 2037         /*
 2038          * RBC devices don't have to support READ(6), only READ(10).
 2039          */
 2040         if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
 2041                 softc->minimum_cmd_size = 10;
 2042         else
 2043                 softc->minimum_cmd_size = 6;
 2044 
 2045         /*
 2046          * Load the user's default, if any.
 2047          */
 2048         snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
 2049                  periph->unit_number);
 2050         TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
 2051 
 2052         /*
 2053          * 6, 10, 12 and 16 are the currently permissible values.
 2054          */
 2055         if (softc->minimum_cmd_size < 6)
 2056                 softc->minimum_cmd_size = 6;
 2057         else if ((softc->minimum_cmd_size > 6)
 2058               && (softc->minimum_cmd_size <= 10))
 2059                 softc->minimum_cmd_size = 10;
 2060         else if ((softc->minimum_cmd_size > 10)
 2061               && (softc->minimum_cmd_size <= 12))
 2062                 softc->minimum_cmd_size = 12;
 2063         else if (softc->minimum_cmd_size > 12)
 2064                 softc->minimum_cmd_size = 16;
 2065 
 2066         /* Predict whether device may support READ CAPACITY(16). */
 2067         if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC3) {
 2068                 softc->flags |= DA_FLAG_CAN_RC16;
 2069                 softc->state = DA_STATE_PROBE_RC16;
 2070         }
 2071 
 2072         /*
 2073          * Register this media as a disk.
 2074          */
 2075         softc->disk = disk_alloc();
 2076         softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
 2077                           periph->unit_number, 0,
 2078                           DEVSTAT_BS_UNAVAILABLE,
 2079                           SID_TYPE(&cgd->inq_data) |
 2080                           XPORT_DEVSTAT_TYPE(cpi.transport),
 2081                           DEVSTAT_PRIORITY_DISK);
 2082         softc->disk->d_open = daopen;
 2083         softc->disk->d_close = daclose;
 2084         softc->disk->d_strategy = dastrategy;
 2085         softc->disk->d_dump = dadump;
 2086         softc->disk->d_getattr = dagetattr;
 2087         softc->disk->d_gone = dadiskgonecb;
 2088         softc->disk->d_name = "da";
 2089         softc->disk->d_drv1 = periph;
 2090         if (cpi.maxio == 0)
 2091                 softc->disk->d_maxsize = DFLTPHYS;      /* traditional default */
 2092         else if (cpi.maxio > MAXPHYS)
 2093                 softc->disk->d_maxsize = MAXPHYS;       /* for safety */
 2094         else
 2095                 softc->disk->d_maxsize = cpi.maxio;
 2096         softc->disk->d_unit = periph->unit_number;
 2097         softc->disk->d_flags = 0;
 2098         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
 2099                 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
 2100         if ((cpi.hba_misc & PIM_UNMAPPED) != 0)
 2101                 softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
 2102         cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor,
 2103             sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr));
 2104         strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr));
 2105         cam_strvis(&softc->disk->d_descr[strlen(softc->disk->d_descr)],
 2106             cgd->inq_data.product, sizeof(cgd->inq_data.product),
 2107             sizeof(softc->disk->d_descr) - strlen(softc->disk->d_descr));
 2108         softc->disk->d_hba_vendor = cpi.hba_vendor;
 2109         softc->disk->d_hba_device = cpi.hba_device;
 2110         softc->disk->d_hba_subvendor = cpi.hba_subvendor;
 2111         softc->disk->d_hba_subdevice = cpi.hba_subdevice;
 2112 
 2113         /*
 2114          * Acquire a reference to the periph before we register with GEOM.
 2115          * We'll release this reference once GEOM calls us back (via
 2116          * dadiskgonecb()) telling us that our provider has been freed.
 2117          */
 2118         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
 2119                 xpt_print(periph->path, "%s: lost periph during "
 2120                           "registration!\n", __func__);
 2121                 cam_periph_lock(periph);
 2122                 return (CAM_REQ_CMP_ERR);
 2123         }
 2124 
 2125         disk_create(softc->disk, DISK_VERSION);
 2126         cam_periph_lock(periph);
 2127 
 2128         /*
 2129          * Add async callbacks for events of interest.
 2130          * I don't bother checking if this fails as,
 2131          * in most cases, the system will function just
 2132          * fine without them and the only alternative
 2133          * would be to not attach the device on failure.
 2134          */
 2135         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
 2136             AC_ADVINFO_CHANGED | AC_SCSI_AEN | AC_UNIT_ATTENTION,
 2137             daasync, periph, periph->path);
 2138 
 2139         /*
 2140          * Emit an attribute changed notification just in case 
 2141          * physical path information arrived before our async
 2142          * event handler was registered, but after anyone attaching
 2143          * to our disk device polled it.
 2144          */
 2145         disk_attr_changed(softc->disk, "GEOM::physpath", M_NOWAIT);
 2146 
 2147         /*
 2148          * Schedule a periodic media polling events.
 2149          */
 2150         callout_init_mtx(&softc->mediapoll_c, periph->sim->mtx, 0);
 2151         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) &&
 2152             (cgd->inq_flags & SID_AEN) == 0 &&
 2153             da_poll_period != 0)
 2154                 callout_reset(&softc->mediapoll_c, da_poll_period * hz,
 2155                     damediapoll, periph);
 2156 
 2157         xpt_schedule(periph, CAM_PRIORITY_DEV);
 2158 
 2159         return(CAM_REQ_CMP);
 2160 }
 2161 
 2162 static void
 2163 dastart(struct cam_periph *periph, union ccb *start_ccb)
 2164 {
 2165         struct da_softc *softc;
 2166 
 2167         softc = (struct da_softc *)periph->softc;
 2168 
 2169         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n"));
 2170 
 2171 skipstate:
 2172         switch (softc->state) {
 2173         case DA_STATE_NORMAL:
 2174         {
 2175                 struct bio *bp, *bp1;
 2176                 uint8_t tag_code;
 2177 
 2178                 /* Execute immediate CCB if waiting. */
 2179                 if (periph->immediate_priority <= periph->pinfo.priority) {
 2180                         CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
 2181                                         ("queuing for immediate ccb\n"));
 2182                         start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
 2183                         SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
 2184                                           periph_links.sle);
 2185                         periph->immediate_priority = CAM_PRIORITY_NONE;
 2186                         wakeup(&periph->ccb_list);
 2187                         /* May have more work to do, so ensure we stay scheduled */
 2188                         daschedule(periph);
 2189                         break;
 2190                 }
 2191 
 2192                 /* Run BIO_DELETE if not running yet. */
 2193                 if (!softc->delete_running &&
 2194                     (bp = bioq_first(&softc->delete_queue)) != NULL) {
 2195                     uint64_t lba;
 2196                     uint64_t count; /* forward compat with WS32 */
 2197 
 2198                     /*
 2199                      * In each of the methods below, while its the caller's
 2200                      * responsibility to ensure the request will fit into a
 2201                      * single device request, we might have changed the delete
 2202                      * method due to the device incorrectly advertising either
 2203                      * its supported methods or limits.
 2204                      * 
 2205                      * To prevent this causing further issues we validate the
 2206                      * against the methods limits, and warn which would
 2207                      * otherwise be unnecessary.
 2208                      */
 2209 
 2210                     if (softc->delete_method == DA_DELETE_UNMAP) {
 2211                         uint8_t *buf = softc->unmap_buf;
 2212                         uint64_t lastlba = (uint64_t)-1;
 2213                         uint32_t lastcount = 0, c;
 2214                         uint64_t totalcount = 0;
 2215                         uint32_t off, ranges = 0;
 2216 
 2217                         /*
 2218                          * Currently this doesn't take the UNMAP
 2219                          * Granularity and Granularity Alignment
 2220                          * fields into account.
 2221                          *
 2222                          * This could result in both unoptimal unmap
 2223                          * requests as as well as UNMAP calls unmapping
 2224                          * fewer LBA's than requested.
 2225                          */
 2226 
 2227                         softc->delete_running = 1;
 2228                         bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
 2229                         bp1 = bp;
 2230                         do {
 2231                                 bioq_remove(&softc->delete_queue, bp1);
 2232                                 if (bp1 != bp)
 2233                                         bioq_insert_tail(&softc->delete_run_queue, bp1);
 2234                                 lba = bp1->bio_pblkno;
 2235                                 count = bp1->bio_bcount / softc->params.secsize;
 2236 
 2237                                 /* Try to extend the previous range. */
 2238                                 if (lba == lastlba) {
 2239                                         c = min(count, softc->unmap_max_lba -
 2240                                                 lastcount);
 2241                                         lastcount += c;
 2242                                         off = ((ranges - 1) * UNMAP_RANGE_SIZE) +
 2243                                               UNMAP_HEAD_SIZE;
 2244                                         scsi_ulto4b(lastcount, &buf[off + 8]);
 2245                                         count -= c;
 2246                                         lba +=c;
 2247                                         totalcount += c;
 2248                                 }
 2249 
 2250                                 while (count > 0) {
 2251                                         c = min(count, softc->unmap_max_lba);
 2252                                         if (totalcount + c > softc->unmap_max_lba ||
 2253                                             ranges >= softc->unmap_max_ranges) {
 2254                                                 xpt_print(periph->path,
 2255                                                   "%s issuing short delete %ld > %ld"
 2256                                                   "|| %d >= %d",
 2257                                                   da_delete_method_desc[softc->delete_method],
 2258                                                   totalcount + c, softc->unmap_max_lba,
 2259                                                   ranges, softc->unmap_max_ranges);
 2260                                                 break;
 2261                                         }
 2262                                         off = (ranges * UNMAP_RANGE_SIZE) +
 2263                                               UNMAP_HEAD_SIZE;
 2264                                         scsi_u64to8b(lba, &buf[off + 0]);
 2265                                         scsi_ulto4b(c, &buf[off + 8]);
 2266                                         lba += c;
 2267                                         totalcount += c;
 2268                                         ranges++;
 2269                                         count -= c;
 2270                                         lastcount = c;
 2271                                 }
 2272                                 lastlba = lba;
 2273                                 bp1 = bioq_first(&softc->delete_queue);
 2274                                 if (bp1 == NULL ||
 2275                                     ranges >= softc->unmap_max_ranges ||
 2276                                     totalcount + bp1->bio_bcount /
 2277                                      softc->params.secsize > softc->unmap_max_lba)
 2278                                         break;
 2279                         } while (1);
 2280                         scsi_ulto2b(ranges * 16 + 6, &buf[0]);
 2281                         scsi_ulto2b(ranges * 16, &buf[2]);
 2282 
 2283                         scsi_unmap(&start_ccb->csio,
 2284                                         /*retries*/da_retry_count,
 2285                                         /*cbfcnp*/dadone,
 2286                                         /*tag_action*/MSG_SIMPLE_Q_TAG,
 2287                                         /*byte2*/0,
 2288                                         /*data_ptr*/ buf,
 2289                                         /*dxfer_len*/ ranges * 16 + 8,
 2290                                         /*sense_len*/SSD_FULL_SIZE,
 2291                                         da_default_timeout * 1000);
 2292                         start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
 2293                         goto out;
 2294                     } else if (softc->delete_method == DA_DELETE_ATA_TRIM) {
 2295                                 uint8_t *buf = softc->unmap_buf;
 2296                                 uint64_t lastlba = (uint64_t)-1;
 2297                                 uint32_t lastcount = 0, c, requestcount;
 2298                                 int ranges = 0, off, block_count;
 2299 
 2300                                 softc->delete_running = 1;
 2301                                 bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
 2302                                 bp1 = bp;
 2303                                 do {
 2304                                         bioq_remove(&softc->delete_queue, bp1);
 2305                                         if (bp1 != bp)
 2306                                                 bioq_insert_tail(&softc->delete_run_queue, bp1);
 2307                                         lba = bp1->bio_pblkno;
 2308                                         count = bp1->bio_bcount / softc->params.secsize;
 2309                                         requestcount = count;
 2310 
 2311                                         /* Try to extend the previous range. */
 2312                                         if (lba == lastlba) {
 2313                                                 c = min(count, ATA_DSM_RANGE_MAX - lastcount);
 2314                                                 lastcount += c;
 2315                                                 off = (ranges - 1) * 8;
 2316                                                 buf[off + 6] = lastcount & 0xff;
 2317                                                 buf[off + 7] = (lastcount >> 8) & 0xff;
 2318                                                 count -= c;
 2319                                                 lba += c;
 2320                                         }
 2321 
 2322                                         while (count > 0) {
 2323                                                 c = min(count, ATA_DSM_RANGE_MAX);
 2324                                                 off = ranges * 8;
 2325 
 2326                                                 buf[off + 0] = lba & 0xff;
 2327                                                 buf[off + 1] = (lba >> 8) & 0xff;
 2328                                                 buf[off + 2] = (lba >> 16) & 0xff;
 2329                                                 buf[off + 3] = (lba >> 24) & 0xff;
 2330                                                 buf[off + 4] = (lba >> 32) & 0xff;
 2331                                                 buf[off + 5] = (lba >> 40) & 0xff;
 2332                                                 buf[off + 6] = c & 0xff;
 2333                                                 buf[off + 7] = (c >> 8) & 0xff;
 2334                                                 lba += c;
 2335                                                 ranges++;
 2336                                                 count -= c;
 2337                                                 lastcount = c;
 2338                                                 if (count != 0 && ranges == softc->trim_max_ranges) {
 2339                                                         xpt_print(periph->path,
 2340                                                           "%s issuing short delete %ld > %ld",
 2341                                                           da_delete_method_desc[softc->delete_method],
 2342                                                           requestcount,
 2343                                                           (softc->trim_max_ranges - ranges) *
 2344                                                           ATA_DSM_RANGE_MAX);
 2345                                                         break;
 2346                                                 }
 2347                                         }
 2348                                         lastlba = lba;
 2349                                         bp1 = bioq_first(&softc->delete_queue);
 2350                                         if (bp1 == NULL ||
 2351                                             bp1->bio_bcount / softc->params.secsize >
 2352                                             (softc->trim_max_ranges - ranges) *
 2353                                                     ATA_DSM_RANGE_MAX)
 2354                                                 break;
 2355                                 } while (1);
 2356 
 2357                                 block_count = (ranges + ATA_DSM_BLK_RANGES - 1) /
 2358                                               ATA_DSM_BLK_RANGES;
 2359                                 scsi_ata_trim(&start_ccb->csio,
 2360                                                 /*retries*/da_retry_count,
 2361                                                 /*cbfcnp*/dadone,
 2362                                                 /*tag_action*/MSG_SIMPLE_Q_TAG,
 2363                                                 block_count,
 2364                                                 /*data_ptr*/buf,
 2365                                                 /*dxfer_len*/block_count * ATA_DSM_BLK_SIZE,
 2366                                                 /*sense_len*/SSD_FULL_SIZE,
 2367                                                 da_default_timeout * 1000);
 2368                                 start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
 2369                                 goto out;
 2370                     } else if (softc->delete_method == DA_DELETE_ZERO ||
 2371                                softc->delete_method == DA_DELETE_WS10 ||
 2372                                softc->delete_method == DA_DELETE_WS16) {
 2373                         /*
 2374                          * We calculate ws_max_blks here based off d_delmaxsize instead
 2375                          * of using softc->ws_max_blks as it is absolute max for the
 2376                          * device not the protocol max which may well be lower
 2377                          */
 2378                         uint64_t ws_max_blks;
 2379                         ws_max_blks = softc->disk->d_delmaxsize / softc->params.secsize;
 2380                         softc->delete_running = 1;
 2381                         lba = bp->bio_pblkno;
 2382                         count = 0;
 2383                         bp1 = bp;
 2384                         do {
 2385                                 bioq_remove(&softc->delete_queue, bp1);
 2386                                 if (bp1 != bp)
 2387                                         bioq_insert_tail(&softc->delete_run_queue, bp1);
 2388                                 count += bp1->bio_bcount / softc->params.secsize;
 2389                                 if (count > ws_max_blks) {
 2390                                         count = min(count, ws_max_blks);
 2391                                         xpt_print(periph->path,
 2392                                           "%s issuing short delete %ld > %ld",
 2393                                           da_delete_method_desc[softc->delete_method],
 2394                                           count, ws_max_blks);
 2395                                         break;
 2396                                 }
 2397                                 bp1 = bioq_first(&softc->delete_queue);
 2398                                 if (bp1 == NULL ||
 2399                                     lba + count != bp1->bio_pblkno ||
 2400                                     count + bp1->bio_bcount /
 2401                                      softc->params.secsize > ws_max_blks)
 2402                                         break;
 2403                         } while (1);
 2404 
 2405                         scsi_write_same(&start_ccb->csio,
 2406                                         /*retries*/da_retry_count,
 2407                                         /*cbfcnp*/dadone,
 2408                                         /*tag_action*/MSG_SIMPLE_Q_TAG,
 2409                                         /*byte2*/softc->delete_method ==
 2410                                             DA_DELETE_ZERO ? 0 : SWS_UNMAP,
 2411                                         softc->delete_method ==
 2412                                             DA_DELETE_WS16 ? 16 : 10,
 2413                                         /*lba*/lba,
 2414                                         /*block_count*/count,
 2415                                         /*data_ptr*/ __DECONST(void *,
 2416                                             zero_region),
 2417                                         /*dxfer_len*/ softc->params.secsize,
 2418                                         /*sense_len*/SSD_FULL_SIZE,
 2419                                         da_default_timeout * 1000);
 2420                         start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
 2421                         goto out;
 2422                     } else {
 2423                         bioq_flush(&softc->delete_queue, NULL, 0);
 2424                         /* FALLTHROUGH */
 2425                     }
 2426                 }
 2427 
 2428                 /* Run regular command. */
 2429                 bp = bioq_takefirst(&softc->bio_queue);
 2430                 if (bp == NULL) {
 2431                         if (softc->tur) {
 2432                                 softc->tur = 0;
 2433                                 scsi_test_unit_ready(&start_ccb->csio,
 2434                                      /*retries*/ da_retry_count,
 2435                                      dadone,
 2436                                      MSG_SIMPLE_Q_TAG,
 2437                                      SSD_FULL_SIZE,
 2438                                      da_default_timeout * 1000);
 2439                                 start_ccb->ccb_h.ccb_bp = NULL;
 2440                                 start_ccb->ccb_h.ccb_state = DA_CCB_TUR;
 2441                                 xpt_action(start_ccb);
 2442                         } else
 2443                                 xpt_release_ccb(start_ccb);
 2444                         break;
 2445                 }
 2446                 if (softc->tur) {
 2447                         softc->tur = 0;
 2448                         cam_periph_release_locked(periph);
 2449                 }
 2450 
 2451                 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
 2452                     (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
 2453                         softc->flags &= ~DA_FLAG_NEED_OTAG;
 2454                         softc->ordered_tag_count++;
 2455                         tag_code = MSG_ORDERED_Q_TAG;
 2456                 } else {
 2457                         tag_code = MSG_SIMPLE_Q_TAG;
 2458                 }
 2459 
 2460                 switch (bp->bio_cmd) {
 2461                 case BIO_READ:
 2462                 case BIO_WRITE:
 2463                         scsi_read_write(&start_ccb->csio,
 2464                                         /*retries*/da_retry_count,
 2465                                         /*cbfcnp*/dadone,
 2466                                         /*tag_action*/tag_code,
 2467                                         /*read_op*/(bp->bio_cmd == BIO_READ ?
 2468                                         SCSI_RW_READ : SCSI_RW_WRITE) |
 2469                                         ((bp->bio_flags & BIO_UNMAPPED) != 0 ?
 2470                                         SCSI_RW_BIO : 0),
 2471                                         /*byte2*/0,
 2472                                         softc->minimum_cmd_size,
 2473                                         /*lba*/bp->bio_pblkno,
 2474                                         /*block_count*/bp->bio_bcount /
 2475                                         softc->params.secsize,
 2476                                         /*data_ptr*/ (bp->bio_flags &
 2477                                         BIO_UNMAPPED) != 0 ? (void *)bp :
 2478                                         bp->bio_data,
 2479                                         /*dxfer_len*/ bp->bio_bcount,
 2480                                         /*sense_len*/SSD_FULL_SIZE,
 2481                                         da_default_timeout * 1000);
 2482                         break;
 2483                 case BIO_FLUSH:
 2484                         /*
 2485                          * BIO_FLUSH doesn't currently communicate
 2486                          * range data, so we synchronize the cache
 2487                          * over the whole disk.  We also force
 2488                          * ordered tag semantics the flush applies
 2489                          * to all previously queued I/O.
 2490                          */
 2491                         scsi_synchronize_cache(&start_ccb->csio,
 2492                                                /*retries*/1,
 2493                                                /*cbfcnp*/dadone,
 2494                                                MSG_ORDERED_Q_TAG,
 2495                                                /*begin_lba*/0,
 2496                                                /*lb_count*/0,
 2497                                                SSD_FULL_SIZE,
 2498                                                da_default_timeout*1000);
 2499                         break;
 2500                 }
 2501                 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
 2502 
 2503 out:
 2504                 /*
 2505                  * Block out any asyncronous callbacks
 2506                  * while we touch the pending ccb list.
 2507                  */
 2508                 LIST_INSERT_HEAD(&softc->pending_ccbs,
 2509                                  &start_ccb->ccb_h, periph_links.le);
 2510                 softc->outstanding_cmds++;
 2511 
 2512                 /* We expect a unit attention from this device */
 2513                 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
 2514                         start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
 2515                         softc->flags &= ~DA_FLAG_RETRY_UA;
 2516                 }
 2517 
 2518                 start_ccb->ccb_h.ccb_bp = bp;
 2519                 xpt_action(start_ccb);
 2520 
 2521                 /* May have more work to do, so ensure we stay scheduled */
 2522                 daschedule(periph);
 2523                 break;
 2524         }
 2525         case DA_STATE_PROBE_RC:
 2526         {
 2527                 struct scsi_read_capacity_data *rcap;
 2528 
 2529                 rcap = (struct scsi_read_capacity_data *)
 2530                     malloc(sizeof(*rcap), M_SCSIDA, M_NOWAIT|M_ZERO);
 2531                 if (rcap == NULL) {
 2532                         printf("dastart: Couldn't malloc read_capacity data\n");
 2533                         /* da_free_periph??? */
 2534                         break;
 2535                 }
 2536                 scsi_read_capacity(&start_ccb->csio,
 2537                                    /*retries*/da_retry_count,
 2538                                    dadone,
 2539                                    MSG_SIMPLE_Q_TAG,
 2540                                    rcap,
 2541                                    SSD_FULL_SIZE,
 2542                                    /*timeout*/5000);
 2543                 start_ccb->ccb_h.ccb_bp = NULL;
 2544                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC;
 2545                 xpt_action(start_ccb);
 2546                 break;
 2547         }
 2548         case DA_STATE_PROBE_RC16:
 2549         {
 2550                 struct scsi_read_capacity_data_long *rcaplong;
 2551 
 2552                 rcaplong = (struct scsi_read_capacity_data_long *)
 2553                         malloc(sizeof(*rcaplong), M_SCSIDA, M_NOWAIT|M_ZERO);
 2554                 if (rcaplong == NULL) {
 2555                         printf("dastart: Couldn't malloc read_capacity data\n");
 2556                         /* da_free_periph??? */
 2557                         break;
 2558                 }
 2559                 scsi_read_capacity_16(&start_ccb->csio,
 2560                                       /*retries*/ da_retry_count,
 2561                                       /*cbfcnp*/ dadone,
 2562                                       /*tag_action*/ MSG_SIMPLE_Q_TAG,
 2563                                       /*lba*/ 0,
 2564                                       /*reladr*/ 0,
 2565                                       /*pmi*/ 0,
 2566                                       rcaplong,
 2567                                       /*sense_len*/ SSD_FULL_SIZE,
 2568                                       /*timeout*/ da_default_timeout * 1000);
 2569                 start_ccb->ccb_h.ccb_bp = NULL;
 2570                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC16;
 2571                 xpt_action(start_ccb);
 2572                 break;
 2573         }
 2574         case DA_STATE_PROBE_LBP:
 2575         {
 2576                 struct scsi_vpd_logical_block_prov *lbp;
 2577 
 2578                 if (!scsi_vpd_supported_page(periph, SVPD_LBP)) {
 2579                         /*
 2580                          * If we get here we don't support any SBC-3 delete
 2581                          * methods with UNMAP as the Logical Block Provisioning
 2582                          * VPD page support is required for devices which
 2583                          * support it according to T10/1799-D Revision 31
 2584                          * however older revisions of the spec don't mandate
 2585                          * this so we currently don't remove these methods
 2586                          * from the available set.
 2587                          */
 2588                         softc->state = DA_STATE_PROBE_BLK_LIMITS;
 2589                         goto skipstate;
 2590                 }
 2591 
 2592                 lbp = (struct scsi_vpd_logical_block_prov *)
 2593                         malloc(sizeof(*lbp), M_SCSIDA, M_NOWAIT|M_ZERO);
 2594 
 2595                 if (lbp == NULL) {
 2596                         printf("dastart: Couldn't malloc lbp data\n");
 2597                         /* da_free_periph??? */
 2598                         break;
 2599                 }
 2600 
 2601                 scsi_inquiry(&start_ccb->csio,
 2602                              /*retries*/da_retry_count,
 2603                              /*cbfcnp*/dadone,
 2604                              /*tag_action*/MSG_SIMPLE_Q_TAG,
 2605                              /*inq_buf*/(u_int8_t *)lbp,
 2606                              /*inq_len*/sizeof(*lbp),
 2607                              /*evpd*/TRUE,
 2608                              /*page_code*/SVPD_LBP,
 2609                              /*sense_len*/SSD_MIN_SIZE,
 2610                              /*timeout*/da_default_timeout * 1000);
 2611                 start_ccb->ccb_h.ccb_bp = NULL;
 2612                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_LBP;
 2613                 xpt_action(start_ccb);
 2614                 break;
 2615         }
 2616         case DA_STATE_PROBE_BLK_LIMITS:
 2617         {
 2618                 struct scsi_vpd_block_limits *block_limits;
 2619 
 2620                 if (!scsi_vpd_supported_page(periph, SVPD_BLOCK_LIMITS)) {
 2621                         /* Not supported skip to next probe */
 2622                         softc->state = DA_STATE_PROBE_BDC;
 2623                         goto skipstate;
 2624                 }
 2625 
 2626                 block_limits = (struct scsi_vpd_block_limits *)
 2627                         malloc(sizeof(*block_limits), M_SCSIDA, M_NOWAIT|M_ZERO);
 2628 
 2629                 if (block_limits == NULL) {
 2630                         printf("dastart: Couldn't malloc block_limits data\n");
 2631                         /* da_free_periph??? */
 2632                         break;
 2633                 }
 2634 
 2635                 scsi_inquiry(&start_ccb->csio,
 2636                              /*retries*/da_retry_count,
 2637                              /*cbfcnp*/dadone,
 2638                              /*tag_action*/MSG_SIMPLE_Q_TAG,
 2639                              /*inq_buf*/(u_int8_t *)block_limits,
 2640                              /*inq_len*/sizeof(*block_limits),
 2641                              /*evpd*/TRUE,
 2642                              /*page_code*/SVPD_BLOCK_LIMITS,
 2643                              /*sense_len*/SSD_MIN_SIZE,
 2644                              /*timeout*/da_default_timeout * 1000);
 2645                 start_ccb->ccb_h.ccb_bp = NULL;
 2646                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BLK_LIMITS;
 2647                 xpt_action(start_ccb);
 2648                 break;
 2649         }
 2650         case DA_STATE_PROBE_BDC:
 2651         {
 2652                 struct scsi_vpd_block_characteristics *bdc;
 2653 
 2654                 if (!scsi_vpd_supported_page(periph, SVPD_BDC)) {
 2655                         softc->state = DA_STATE_PROBE_ATA;
 2656                         goto skipstate;
 2657                 }
 2658 
 2659                 bdc = (struct scsi_vpd_block_characteristics *)
 2660                         malloc(sizeof(*bdc), M_SCSIDA, M_NOWAIT|M_ZERO);
 2661 
 2662                 if (bdc == NULL) {
 2663                         printf("dastart: Couldn't malloc bdc data\n");
 2664                         /* da_free_periph??? */
 2665                         break;
 2666                 }
 2667 
 2668                 scsi_inquiry(&start_ccb->csio,
 2669                              /*retries*/da_retry_count,
 2670                              /*cbfcnp*/dadone,
 2671                              /*tag_action*/MSG_SIMPLE_Q_TAG,
 2672                              /*inq_buf*/(u_int8_t *)bdc,
 2673                              /*inq_len*/sizeof(*bdc),
 2674                              /*evpd*/TRUE,
 2675                              /*page_code*/SVPD_BDC,
 2676                              /*sense_len*/SSD_MIN_SIZE,
 2677                              /*timeout*/da_default_timeout * 1000);
 2678                 start_ccb->ccb_h.ccb_bp = NULL;
 2679                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BDC;
 2680                 xpt_action(start_ccb);
 2681                 break;
 2682         }
 2683         case DA_STATE_PROBE_ATA:
 2684         {
 2685                 struct ata_params *ata_params;
 2686 
 2687                 if (!scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) {
 2688                         daprobedone(periph, start_ccb);
 2689                         break;
 2690                 }
 2691 
 2692                 ata_params = (struct ata_params*)
 2693                         malloc(sizeof(*ata_params), M_SCSIDA, M_NOWAIT|M_ZERO);
 2694 
 2695                 if (ata_params == NULL) {
 2696                         printf("dastart: Couldn't malloc ata_params data\n");
 2697                         /* da_free_periph??? */
 2698                         break;
 2699                 }
 2700 
 2701                 scsi_ata_identify(&start_ccb->csio,
 2702                                   /*retries*/da_retry_count,
 2703                                   /*cbfcnp*/dadone,
 2704                                   /*tag_action*/MSG_SIMPLE_Q_TAG,
 2705                                   /*data_ptr*/(u_int8_t *)ata_params,
 2706                                   /*dxfer_len*/sizeof(*ata_params),
 2707                                   /*sense_len*/SSD_FULL_SIZE,
 2708                                   /*timeout*/da_default_timeout * 1000);
 2709                 start_ccb->ccb_h.ccb_bp = NULL;
 2710                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA;
 2711                 xpt_action(start_ccb);
 2712                 break;
 2713         }
 2714         }
 2715 }
 2716 
 2717 static int
 2718 cmd6workaround(union ccb *ccb)
 2719 {
 2720         struct scsi_rw_6 cmd6;
 2721         struct scsi_rw_10 *cmd10;
 2722         struct da_softc *softc;
 2723         u_int8_t *cdb;
 2724         struct bio *bp;
 2725         int frozen;
 2726 
 2727         cdb = ccb->csio.cdb_io.cdb_bytes;
 2728         softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
 2729 
 2730         if (ccb->ccb_h.ccb_state == DA_CCB_DELETE) {
 2731                 da_delete_methods old_method = softc->delete_method;
 2732 
 2733                 /*
 2734                  * Typically there are two reasons for failure here
 2735                  * 1. Delete method was detected as supported but isn't
 2736                  * 2. Delete failed due to invalid params e.g. too big
 2737                  *
 2738                  * While we will attempt to choose an alternative delete method
 2739                  * this may result in short deletes if the existing delete
 2740                  * requests from geom are big for the new method choosen.
 2741                  *
 2742                  * This method assumes that the error which triggered this
 2743                  * will not retry the io otherwise a panic will occur
 2744                  */
 2745                 dadeleteflag(softc, old_method, 0);
 2746                 dadeletemethodchoose(softc, DA_DELETE_DISABLE);
 2747                 if (softc->delete_method == DA_DELETE_DISABLE)
 2748                         xpt_print(ccb->ccb_h.path,
 2749                                   "%s failed, disabling BIO_DELETE\n",
 2750                                   da_delete_method_desc[old_method]);
 2751                 else
 2752                         xpt_print(ccb->ccb_h.path,
 2753                                   "%s failed, switching to %s BIO_DELETE\n",
 2754                                   da_delete_method_desc[old_method],
 2755                                   da_delete_method_desc[softc->delete_method]);
 2756 
 2757                 if (DA_SIO) {
 2758                         while ((bp = bioq_takefirst(&softc->delete_run_queue))
 2759                             != NULL)
 2760                                 bioq_disksort(&softc->delete_queue, bp);
 2761                 } else {
 2762                         while ((bp = bioq_takefirst(&softc->delete_run_queue))
 2763                             != NULL)
 2764                                 bioq_insert_tail(&softc->delete_queue, bp);
 2765                 }
 2766                 bioq_insert_tail(&softc->delete_queue,
 2767                     (struct bio *)ccb->ccb_h.ccb_bp);
 2768                 ccb->ccb_h.ccb_bp = NULL;
 2769                 return (0);
 2770         }
 2771 
 2772         /* Translation only possible if CDB is an array and cmd is R/W6 */
 2773         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
 2774             (*cdb != READ_6 && *cdb != WRITE_6))
 2775                 return 0;
 2776 
 2777         xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
 2778             "increasing minimum_cmd_size to 10.\n");
 2779         softc->minimum_cmd_size = 10;
 2780 
 2781         bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
 2782         cmd10 = (struct scsi_rw_10 *)cdb;
 2783         cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
 2784         cmd10->byte2 = 0;
 2785         scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
 2786         cmd10->reserved = 0;
 2787         scsi_ulto2b(cmd6.length, cmd10->length);
 2788         cmd10->control = cmd6.control;
 2789         ccb->csio.cdb_len = sizeof(*cmd10);
 2790 
 2791         /* Requeue request, unfreezing queue if necessary */
 2792         frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
 2793         ccb->ccb_h.status = CAM_REQUEUE_REQ;
 2794         xpt_action(ccb);
 2795         if (frozen) {
 2796                 cam_release_devq(ccb->ccb_h.path,
 2797                                  /*relsim_flags*/0,
 2798                                  /*reduction*/0,
 2799                                  /*timeout*/0,
 2800                                  /*getcount_only*/0);
 2801         }
 2802         return (ERESTART);
 2803 }
 2804 
 2805 static void
 2806 dadone(struct cam_periph *periph, union ccb *done_ccb)
 2807 {
 2808         struct da_softc *softc;
 2809         struct ccb_scsiio *csio;
 2810         u_int32_t  priority;
 2811         da_ccb_state state;
 2812 
 2813         softc = (struct da_softc *)periph->softc;
 2814         priority = done_ccb->ccb_h.pinfo.priority;
 2815 
 2816         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
 2817 
 2818         csio = &done_ccb->csio;
 2819         state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK;
 2820         switch (state) {
 2821         case DA_CCB_BUFFER_IO:
 2822         case DA_CCB_DELETE:
 2823         {
 2824                 struct bio *bp, *bp1;
 2825 
 2826                 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 2827                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 2828                         int error;
 2829                         int sf;
 2830 
 2831                         if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
 2832                                 sf = SF_RETRY_UA;
 2833                         else
 2834                                 sf = 0;
 2835 
 2836                         error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
 2837                         if (error == ERESTART) {
 2838                                 /*
 2839                                  * A retry was scheduled, so
 2840                                  * just return.
 2841                                  */
 2842                                 return;
 2843                         }
 2844                         bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 2845                         if (error != 0) {
 2846                                 int queued_error;
 2847 
 2848                                 /*
 2849                                  * return all queued I/O with EIO, so that
 2850                                  * the client can retry these I/Os in the
 2851                                  * proper order should it attempt to recover.
 2852                                  */
 2853                                 queued_error = EIO;
 2854 
 2855                                 if (error == ENXIO
 2856                                  && (softc->flags & DA_FLAG_PACK_INVALID)== 0) {
 2857                                         /*
 2858                                          * Catastrophic error.  Mark our pack as
 2859                                          * invalid.
 2860                                          */
 2861                                         /*
 2862                                          * XXX See if this is really a media
 2863                                          * XXX change first?
 2864                                          */
 2865                                         xpt_print(periph->path,
 2866                                             "Invalidating pack\n");
 2867                                         softc->flags |= DA_FLAG_PACK_INVALID;
 2868                                         queued_error = ENXIO;
 2869                                 }
 2870                                 bioq_flush(&softc->bio_queue, NULL,
 2871                                            queued_error);
 2872                                 if (bp != NULL) {
 2873                                         bp->bio_error = error;
 2874                                         bp->bio_resid = bp->bio_bcount;
 2875                                         bp->bio_flags |= BIO_ERROR;
 2876                                 }
 2877                         } else if (bp != NULL) {
 2878                                 bp->bio_resid = csio->resid;
 2879                                 bp->bio_error = 0;
 2880                                 if (bp->bio_resid != 0)
 2881                                         bp->bio_flags |= BIO_ERROR;
 2882                         }
 2883                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 2884                                 cam_release_devq(done_ccb->ccb_h.path,
 2885                                                  /*relsim_flags*/0,
 2886                                                  /*reduction*/0,
 2887                                                  /*timeout*/0,
 2888                                                  /*getcount_only*/0);
 2889                 } else if (bp != NULL) {
 2890                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 2891                                 panic("REQ_CMP with QFRZN");
 2892                         bp->bio_resid = csio->resid;
 2893                         if (csio->resid > 0)
 2894                                 bp->bio_flags |= BIO_ERROR;
 2895                         if (softc->error_inject != 0) {
 2896                                 bp->bio_error = softc->error_inject;
 2897                                 bp->bio_resid = bp->bio_bcount;
 2898                                 bp->bio_flags |= BIO_ERROR;
 2899                                 softc->error_inject = 0;
 2900                         }
 2901 
 2902                 }
 2903 
 2904                 /*
 2905                  * Block out any asyncronous callbacks
 2906                  * while we touch the pending ccb list.
 2907                  */
 2908                 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
 2909                 softc->outstanding_cmds--;
 2910                 if (softc->outstanding_cmds == 0)
 2911                         softc->flags |= DA_FLAG_WENT_IDLE;
 2912 
 2913                 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
 2914                         xpt_print(periph->path, "oustanding %d\n",
 2915                                   softc->outstanding_cmds);
 2916                 }
 2917 
 2918                 if (state == DA_CCB_DELETE) {
 2919                         while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
 2920                             != NULL) {
 2921                                 bp1->bio_resid = bp->bio_resid;
 2922                                 bp1->bio_error = bp->bio_error;
 2923                                 if (bp->bio_flags & BIO_ERROR)
 2924                                         bp1->bio_flags |= BIO_ERROR;
 2925                                 biodone(bp1);
 2926                         }
 2927                         softc->delete_running = 0;
 2928                         if (bp != NULL)
 2929                                 biodone(bp);
 2930                         daschedule(periph);
 2931                 } else if (bp != NULL)
 2932                         biodone(bp);
 2933                 break;
 2934         }
 2935         case DA_CCB_PROBE_RC:
 2936         case DA_CCB_PROBE_RC16:
 2937         {
 2938                 struct     scsi_read_capacity_data *rdcap;
 2939                 struct     scsi_read_capacity_data_long *rcaplong;
 2940                 char       announce_buf[80];
 2941                 int        lbp;
 2942 
 2943                 lbp = 0;
 2944                 rdcap = NULL;
 2945                 rcaplong = NULL;
 2946                 if (state == DA_CCB_PROBE_RC)
 2947                         rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
 2948                 else
 2949                         rcaplong = (struct scsi_read_capacity_data_long *)
 2950                                 csio->data_ptr;
 2951 
 2952                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 2953                         struct disk_params *dp;
 2954                         uint32_t block_size;
 2955                         uint64_t maxsector;
 2956                         u_int lbppbe;   /* LB per physical block exponent. */
 2957                         u_int lalba;    /* Lowest aligned LBA. */
 2958 
 2959                         if (state == DA_CCB_PROBE_RC) {
 2960                                 block_size = scsi_4btoul(rdcap->length);
 2961                                 maxsector = scsi_4btoul(rdcap->addr);
 2962                                 lbppbe = 0;
 2963                                 lalba = 0;
 2964 
 2965                                 /*
 2966                                  * According to SBC-2, if the standard 10
 2967                                  * byte READ CAPACITY command returns 2^32,
 2968                                  * we should issue the 16 byte version of
 2969                                  * the command, since the device in question
 2970                                  * has more sectors than can be represented
 2971                                  * with the short version of the command.
 2972                                  */
 2973                                 if (maxsector == 0xffffffff) {
 2974                                         free(rdcap, M_SCSIDA);
 2975                                         xpt_release_ccb(done_ccb);
 2976                                         softc->state = DA_STATE_PROBE_RC16;
 2977                                         xpt_schedule(periph, priority);
 2978                                         return;
 2979                                 }
 2980                         } else {
 2981                                 block_size = scsi_4btoul(rcaplong->length);
 2982                                 maxsector = scsi_8btou64(rcaplong->addr);
 2983                                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
 2984                                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
 2985                         }
 2986 
 2987                         /*
 2988                          * Because GEOM code just will panic us if we
 2989                          * give them an 'illegal' value we'll avoid that
 2990                          * here.
 2991                          */
 2992                         if (block_size == 0 && maxsector == 0) {
 2993                                 snprintf(announce_buf, sizeof(announce_buf),
 2994                                         "0MB (no media?)");
 2995                         } else if (block_size >= MAXPHYS || block_size == 0) {
 2996                                 xpt_print(periph->path,
 2997                                     "unsupportable block size %ju\n",
 2998                                     (uintmax_t) block_size);
 2999                                 announce_buf[0] = '\0';
 3000                                 cam_periph_invalidate(periph);
 3001                         } else {
 3002                                 /*
 3003                                  * We pass rcaplong into dasetgeom(),
 3004                                  * because it will only use it if it is
 3005                                  * non-NULL.
 3006                                  */
 3007                                 dasetgeom(periph, block_size, maxsector,
 3008                                           rcaplong, sizeof(*rcaplong));
 3009                                 lbp = (lalba & SRC16_LBPME_A);
 3010                                 dp = &softc->params;
 3011                                 snprintf(announce_buf, sizeof(announce_buf),
 3012                                         "%juMB (%ju %u byte sectors: %dH %dS/T "
 3013                                         "%dC)", (uintmax_t)
 3014                                         (((uintmax_t)dp->secsize *
 3015                                         dp->sectors) / (1024*1024)),
 3016                                         (uintmax_t)dp->sectors,
 3017                                         dp->secsize, dp->heads,
 3018                                         dp->secs_per_track, dp->cylinders);
 3019                         }
 3020                 } else {
 3021                         int     error;
 3022 
 3023                         announce_buf[0] = '\0';
 3024 
 3025                         /*
 3026                          * Retry any UNIT ATTENTION type errors.  They
 3027                          * are expected at boot.
 3028                          */
 3029                         error = daerror(done_ccb, CAM_RETRY_SELTO,
 3030                                         SF_RETRY_UA|SF_NO_PRINT);
 3031                         if (error == ERESTART) {
 3032                                 /*
 3033                                  * A retry was scheuled, so
 3034                                  * just return.
 3035                                  */
 3036                                 return;
 3037                         } else if (error != 0) {
 3038                                 int asc, ascq;
 3039                                 int sense_key, error_code;
 3040                                 int have_sense;
 3041                                 cam_status status;
 3042                                 struct ccb_getdev cgd;
 3043 
 3044                                 /* Don't wedge this device's queue */
 3045                                 status = done_ccb->ccb_h.status;
 3046                                 if ((status & CAM_DEV_QFRZN) != 0)
 3047                                         cam_release_devq(done_ccb->ccb_h.path,
 3048                                                          /*relsim_flags*/0,
 3049                                                          /*reduction*/0,
 3050                                                          /*timeout*/0,
 3051                                                          /*getcount_only*/0);
 3052 
 3053 
 3054                                 xpt_setup_ccb(&cgd.ccb_h, 
 3055                                               done_ccb->ccb_h.path,
 3056                                               CAM_PRIORITY_NORMAL);
 3057                                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 3058                                 xpt_action((union ccb *)&cgd);
 3059 
 3060                                 if (scsi_extract_sense_ccb(done_ccb,
 3061                                     &error_code, &sense_key, &asc, &ascq))
 3062                                         have_sense = TRUE;
 3063                                 else
 3064                                         have_sense = FALSE;
 3065 
 3066                                 /*
 3067                                  * If we tried READ CAPACITY(16) and failed,
 3068                                  * fallback to READ CAPACITY(10).
 3069                                  */
 3070                                 if ((state == DA_CCB_PROBE_RC16) &&
 3071                                     (softc->flags & DA_FLAG_CAN_RC16) &&
 3072                                     (((csio->ccb_h.status & CAM_STATUS_MASK) ==
 3073                                         CAM_REQ_INVALID) ||
 3074                                      ((have_sense) &&
 3075                                       (error_code == SSD_CURRENT_ERROR) &&
 3076                                       (sense_key == SSD_KEY_ILLEGAL_REQUEST)))) {
 3077                                         softc->flags &= ~DA_FLAG_CAN_RC16;
 3078                                         free(rdcap, M_SCSIDA);
 3079                                         xpt_release_ccb(done_ccb);
 3080                                         softc->state = DA_STATE_PROBE_RC;
 3081                                         xpt_schedule(periph, priority);
 3082                                         return;
 3083                                 } else
 3084                                 /*
 3085                                  * Attach to anything that claims to be a
 3086                                  * direct access or optical disk device,
 3087                                  * as long as it doesn't return a "Logical
 3088                                  * unit not supported" (0x25) error.
 3089                                  */
 3090                                 if ((have_sense) && (asc != 0x25)
 3091                                  && (error_code == SSD_CURRENT_ERROR)) {
 3092                                         const char *sense_key_desc;
 3093                                         const char *asc_desc;
 3094 
 3095                                         scsi_sense_desc(sense_key, asc, ascq,
 3096                                                         &cgd.inq_data,
 3097                                                         &sense_key_desc,
 3098                                                         &asc_desc);
 3099                                         snprintf(announce_buf,
 3100                                             sizeof(announce_buf),
 3101                                                 "Attempt to query device "
 3102                                                 "size failed: %s, %s",
 3103                                                 sense_key_desc,
 3104                                                 asc_desc);
 3105                                 } else { 
 3106                                         if (have_sense)
 3107                                                 scsi_sense_print(
 3108                                                         &done_ccb->csio);
 3109                                         else {
 3110                                                 xpt_print(periph->path,
 3111                                                     "got CAM status %#x\n",
 3112                                                     done_ccb->ccb_h.status);
 3113                                         }
 3114 
 3115                                         xpt_print(periph->path, "fatal error, "
 3116                                             "failed to attach to device\n");
 3117 
 3118                                         /*
 3119                                          * Free up resources.
 3120                                          */
 3121                                         cam_periph_invalidate(periph);
 3122                                 } 
 3123                         }
 3124                 }
 3125                 free(csio->data_ptr, M_SCSIDA);
 3126                 if (announce_buf[0] != '\0' && ((softc->flags & DA_FLAG_PROBED) == 0)) {
 3127                         /*
 3128                          * Create our sysctl variables, now that we know
 3129                          * we have successfully attached.
 3130                          */
 3131                         /* increase the refcount */
 3132                         if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
 3133                                 taskqueue_enqueue(taskqueue_thread,
 3134                                                   &softc->sysctl_task);
 3135                                 xpt_announce_periph(periph, announce_buf);
 3136                                 xpt_announce_quirks(periph, softc->quirks,
 3137                                     DA_Q_BIT_STRING);
 3138                         } else {
 3139                                 xpt_print(periph->path, "fatal error, "
 3140                                     "could not acquire reference count\n");
 3141                         }
 3142                 }
 3143 
 3144                 /* Ensure re-probe doesn't see old delete. */
 3145                 softc->delete_available = 0;
 3146                 if (lbp) {
 3147                         /*
 3148                          * Based on older SBC-3 spec revisions
 3149                          * any of the UNMAP methods "may" be
 3150                          * available via LBP given this flag so
 3151                          * we flag all of them as availble and
 3152                          * then remove those which further
 3153                          * probes confirm aren't available
 3154                          * later.
 3155                          *
 3156                          * We could also check readcap(16) p_type
 3157                          * flag to exclude one or more invalid
 3158                          * write same (X) types here
 3159                          */
 3160                         dadeleteflag(softc, DA_DELETE_WS16, 1);
 3161                         dadeleteflag(softc, DA_DELETE_WS10, 1);
 3162                         dadeleteflag(softc, DA_DELETE_ZERO, 1);
 3163                         dadeleteflag(softc, DA_DELETE_UNMAP, 1);
 3164 
 3165                         xpt_release_ccb(done_ccb);
 3166                         softc->state = DA_STATE_PROBE_LBP;
 3167                         xpt_schedule(periph, priority);
 3168                         return;
 3169                 }
 3170 
 3171                 xpt_release_ccb(done_ccb);
 3172                 softc->state = DA_STATE_PROBE_BDC;
 3173                 xpt_schedule(periph, priority);
 3174                 return;
 3175         }
 3176         case DA_CCB_PROBE_LBP:
 3177         {
 3178                 struct scsi_vpd_logical_block_prov *lbp;
 3179 
 3180                 lbp = (struct scsi_vpd_logical_block_prov *)csio->data_ptr;
 3181 
 3182                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3183                         /*
 3184                          * T10/1799-D Revision 31 states at least one of these
 3185                          * must be supported but we don't currently enforce this.
 3186                          */
 3187                         dadeleteflag(softc, DA_DELETE_WS16,
 3188                                      (lbp->flags & SVPD_LBP_WS16));
 3189                         dadeleteflag(softc, DA_DELETE_WS10,
 3190                                      (lbp->flags & SVPD_LBP_WS10));
 3191                         dadeleteflag(softc, DA_DELETE_ZERO,
 3192                                      (lbp->flags & SVPD_LBP_WS10));
 3193                         dadeleteflag(softc, DA_DELETE_UNMAP,
 3194                                      (lbp->flags & SVPD_LBP_UNMAP));
 3195 
 3196                         if (lbp->flags & SVPD_LBP_UNMAP) {
 3197                                 free(lbp, M_SCSIDA);
 3198                                 xpt_release_ccb(done_ccb);
 3199                                 softc->state = DA_STATE_PROBE_BLK_LIMITS;
 3200                                 xpt_schedule(periph, priority);
 3201                                 return;
 3202                         }
 3203                 } else {
 3204                         int error;
 3205                         error = daerror(done_ccb, CAM_RETRY_SELTO,
 3206                                         SF_RETRY_UA|SF_NO_PRINT);
 3207                         if (error == ERESTART)
 3208                                 return;
 3209                         else if (error != 0) {
 3210                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 3211                                         /* Don't wedge this device's queue */
 3212                                         cam_release_devq(done_ccb->ccb_h.path,
 3213                                                          /*relsim_flags*/0,
 3214                                                          /*reduction*/0,
 3215                                                          /*timeout*/0,
 3216                                                          /*getcount_only*/0);
 3217                                 }
 3218 
 3219                                 /*
 3220                                  * Failure indicates we don't support any SBC-3
 3221                                  * delete methods with UNMAP
 3222                                  */
 3223                         }
 3224                 }
 3225 
 3226                 free(lbp, M_SCSIDA);
 3227                 xpt_release_ccb(done_ccb);
 3228                 softc->state = DA_STATE_PROBE_BDC;
 3229                 xpt_schedule(periph, priority);
 3230                 return;
 3231         }
 3232         case DA_CCB_PROBE_BLK_LIMITS:
 3233         {
 3234                 struct scsi_vpd_block_limits *block_limits;
 3235 
 3236                 block_limits = (struct scsi_vpd_block_limits *)csio->data_ptr;
 3237 
 3238                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3239                         uint32_t max_unmap_lba_cnt = scsi_4btoul(
 3240                                 block_limits->max_unmap_lba_cnt);
 3241                         uint32_t max_unmap_blk_cnt = scsi_4btoul(
 3242                                 block_limits->max_unmap_blk_cnt);
 3243                         uint64_t ws_max_blks = scsi_8btou64(
 3244                                 block_limits->max_write_same_length);
 3245                         /*
 3246                          * We should already support UNMAP but we check lba
 3247                          * and block count to be sure
 3248                          */
 3249                         if (max_unmap_lba_cnt != 0x00L &&
 3250                             max_unmap_blk_cnt != 0x00L) {
 3251                                 softc->unmap_max_lba = max_unmap_lba_cnt;
 3252                                 softc->unmap_max_ranges = min(max_unmap_blk_cnt,
 3253                                         UNMAP_MAX_RANGES);
 3254                         } else {
 3255                                 /*
 3256                                  * Unexpected UNMAP limits which means the
 3257                                  * device doesn't actually support UNMAP
 3258                                  */
 3259                                 dadeleteflag(softc, DA_DELETE_UNMAP, 0);
 3260                         }
 3261 
 3262                         if (ws_max_blks != 0x00L)
 3263                                 softc->ws_max_blks = ws_max_blks;
 3264                 } else {
 3265                         int error;
 3266                         error = daerror(done_ccb, CAM_RETRY_SELTO,
 3267                                         SF_RETRY_UA|SF_NO_PRINT);
 3268                         if (error == ERESTART)
 3269                                 return;
 3270                         else if (error != 0) {
 3271                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 3272                                         /* Don't wedge this device's queue */
 3273                                         cam_release_devq(done_ccb->ccb_h.path,
 3274                                                          /*relsim_flags*/0,
 3275                                                          /*reduction*/0,
 3276                                                          /*timeout*/0,
 3277                                                          /*getcount_only*/0);
 3278                                 }
 3279 
 3280                                 /*
 3281                                  * Failure here doesn't mean UNMAP is not
 3282                                  * supported as this is an optional page.
 3283                                  */
 3284                                 softc->unmap_max_lba = 1;
 3285                                 softc->unmap_max_ranges = 1;
 3286                         }
 3287                 }
 3288 
 3289                 free(block_limits, M_SCSIDA);
 3290                 xpt_release_ccb(done_ccb);
 3291                 softc->state = DA_STATE_PROBE_BDC;
 3292                 xpt_schedule(periph, priority);
 3293                 return;
 3294         }
 3295         case DA_CCB_PROBE_BDC:
 3296         {
 3297                 struct scsi_vpd_block_characteristics *bdc;
 3298 
 3299                 bdc = (struct scsi_vpd_block_characteristics *)csio->data_ptr;
 3300 
 3301                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3302                         /*
 3303                          * Disable queue sorting for non-rotational media
 3304                          * by default.
 3305                          */
 3306                         if (scsi_2btoul(bdc->medium_rotation_rate) ==
 3307                             SVPD_BDC_RATE_NONE_ROTATING)
 3308                                 softc->sort_io_queue = 0;
 3309                 } else {
 3310                         int error;
 3311                         error = daerror(done_ccb, CAM_RETRY_SELTO,
 3312                                         SF_RETRY_UA|SF_NO_PRINT);
 3313                         if (error == ERESTART)
 3314                                 return;
 3315                         else if (error != 0) {
 3316                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 3317                                         /* Don't wedge this device's queue */
 3318                                         cam_release_devq(done_ccb->ccb_h.path,
 3319                                                          /*relsim_flags*/0,
 3320                                                          /*reduction*/0,
 3321                                                          /*timeout*/0,
 3322                                                          /*getcount_only*/0);
 3323                                 }
 3324                         }
 3325                 }
 3326 
 3327                 free(bdc, M_SCSIDA);
 3328                 xpt_release_ccb(done_ccb);
 3329                 softc->state = DA_STATE_PROBE_ATA;
 3330                 xpt_schedule(periph, priority);
 3331                 return;
 3332         }
 3333         case DA_CCB_PROBE_ATA:
 3334         {
 3335                 int i;
 3336                 struct ata_params *ata_params;
 3337                 int16_t *ptr;
 3338 
 3339                 ata_params = (struct ata_params *)csio->data_ptr;
 3340                 ptr = (uint16_t *)ata_params;
 3341 
 3342                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3343                         for (i = 0; i < sizeof(*ata_params) / 2; i++)
 3344                                 ptr[i] = le16toh(ptr[i]);
 3345                         if (ata_params->support_dsm & ATA_SUPPORT_DSM_TRIM) {
 3346                                 dadeleteflag(softc, DA_DELETE_ATA_TRIM, 1);
 3347                                 if (ata_params->max_dsm_blocks != 0)
 3348                                         softc->trim_max_ranges = min(
 3349                                           softc->trim_max_ranges,
 3350                                           ata_params->max_dsm_blocks *
 3351                                           ATA_DSM_BLK_RANGES);
 3352                         }
 3353                         /*
 3354                          * Disable queue sorting for non-rotational media
 3355                          * by default.
 3356                          */
 3357                         if (ata_params->media_rotation_rate == 1)
 3358                                 softc->sort_io_queue = 0;
 3359                 } else {
 3360                         int error;
 3361                         error = daerror(done_ccb, CAM_RETRY_SELTO,
 3362                                         SF_RETRY_UA|SF_NO_PRINT);
 3363                         if (error == ERESTART)
 3364                                 return;
 3365                         else if (error != 0) {
 3366                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 3367                                         /* Don't wedge this device's queue */
 3368                                         cam_release_devq(done_ccb->ccb_h.path,
 3369                                                          /*relsim_flags*/0,
 3370                                                          /*reduction*/0,
 3371                                                          /*timeout*/0,
 3372                                                          /*getcount_only*/0);
 3373                                 }
 3374                         }
 3375                 }
 3376 
 3377                 free(ata_params, M_SCSIDA);
 3378                 daprobedone(periph, done_ccb);
 3379                 return;
 3380         }
 3381         case DA_CCB_WAITING:
 3382         {
 3383                 /* Caller will release the CCB */
 3384                 wakeup(&done_ccb->ccb_h.cbfcnp);
 3385                 return;
 3386         }
 3387         case DA_CCB_DUMP:
 3388                 /* No-op.  We're polling */
 3389                 return;
 3390         case DA_CCB_TUR:
 3391         {
 3392                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 3393 
 3394                         if (daerror(done_ccb, CAM_RETRY_SELTO,
 3395                             SF_RETRY_UA | SF_NO_RECOVERY | SF_NO_PRINT) ==
 3396                             ERESTART)
 3397                                 return;
 3398                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 3399                                 cam_release_devq(done_ccb->ccb_h.path,
 3400                                                  /*relsim_flags*/0,
 3401                                                  /*reduction*/0,
 3402                                                  /*timeout*/0,
 3403                                                  /*getcount_only*/0);
 3404                 }
 3405                 xpt_release_ccb(done_ccb);
 3406                 cam_periph_release_locked(periph);
 3407                 return;
 3408         }
 3409         default:
 3410                 break;
 3411         }
 3412         xpt_release_ccb(done_ccb);
 3413 }
 3414 
 3415 static void
 3416 dareprobe(struct cam_periph *periph)
 3417 {
 3418         struct da_softc   *softc;
 3419         cam_status status;
 3420 
 3421         softc = (struct da_softc *)periph->softc;
 3422 
 3423         /* Probe in progress; don't interfere. */
 3424         if (softc->state != DA_STATE_NORMAL)
 3425                 return;
 3426 
 3427         status = cam_periph_acquire(periph);
 3428         KASSERT(status == CAM_REQ_CMP,
 3429             ("dareprobe: cam_periph_acquire failed"));
 3430 
 3431         if (softc->flags & DA_FLAG_CAN_RC16)
 3432                 softc->state = DA_STATE_PROBE_RC16;
 3433         else
 3434                 softc->state = DA_STATE_PROBE_RC;
 3435 
 3436         xpt_schedule(periph, CAM_PRIORITY_DEV);
 3437 }
 3438 
 3439 static int
 3440 daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
 3441 {
 3442         struct da_softc   *softc;
 3443         struct cam_periph *periph;
 3444         int error, error_code, sense_key, asc, ascq;
 3445 
 3446         periph = xpt_path_periph(ccb->ccb_h.path);
 3447         softc = (struct da_softc *)periph->softc;
 3448 
 3449         /*
 3450          * Automatically detect devices that do not support
 3451          * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
 3452          */
 3453         error = 0;
 3454         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
 3455                 error = cmd6workaround(ccb);
 3456         } else if (scsi_extract_sense_ccb(ccb,
 3457             &error_code, &sense_key, &asc, &ascq)) {
 3458                 if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
 3459                         error = cmd6workaround(ccb);
 3460                 /*
 3461                  * If the target replied with CAPACITY DATA HAS CHANGED UA,
 3462                  * query the capacity and notify upper layers.
 3463                  */
 3464                 else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
 3465                     asc == 0x2A && ascq == 0x09) {
 3466                         xpt_print(periph->path, "capacity data has changed\n");
 3467                         dareprobe(periph);
 3468                         sense_flags |= SF_NO_PRINT;
 3469                 } else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
 3470                     asc == 0x28 && ascq == 0x00)
 3471                         disk_media_changed(softc->disk, M_NOWAIT);
 3472                 else if (sense_key == SSD_KEY_NOT_READY &&
 3473                     asc == 0x3a && (softc->flags & DA_FLAG_SAW_MEDIA)) {
 3474                         softc->flags &= ~DA_FLAG_SAW_MEDIA;
 3475                         disk_media_gone(softc->disk, M_NOWAIT);
 3476                 }
 3477         }
 3478         if (error == ERESTART)
 3479                 return (ERESTART);
 3480 
 3481         /*
 3482          * XXX
 3483          * Until we have a better way of doing pack validation,
 3484          * don't treat UAs as errors.
 3485          */
 3486         sense_flags |= SF_RETRY_UA;
 3487         return(cam_periph_error(ccb, cam_flags, sense_flags,
 3488                                 &softc->saved_ccb));
 3489 }
 3490 
 3491 static void
 3492 damediapoll(void *arg)
 3493 {
 3494         struct cam_periph *periph = arg;
 3495         struct da_softc *softc = periph->softc;
 3496 
 3497         if (!softc->tur && softc->outstanding_cmds == 0) {
 3498                 if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
 3499                         softc->tur = 1;
 3500                         daschedule(periph);
 3501                 }
 3502         }
 3503         /* Queue us up again */
 3504         if (da_poll_period != 0)
 3505                 callout_schedule(&softc->mediapoll_c, da_poll_period * hz);
 3506 }
 3507 
 3508 static void
 3509 daprevent(struct cam_periph *periph, int action)
 3510 {
 3511         struct  da_softc *softc;
 3512         union   ccb *ccb;               
 3513         int     error;
 3514                 
 3515         softc = (struct da_softc *)periph->softc;
 3516 
 3517         if (((action == PR_ALLOW)
 3518           && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
 3519          || ((action == PR_PREVENT)
 3520           && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
 3521                 return;
 3522         }
 3523 
 3524         ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 3525 
 3526         scsi_prevent(&ccb->csio,
 3527                      /*retries*/1,
 3528                      /*cbcfp*/dadone,
 3529                      MSG_SIMPLE_Q_TAG,
 3530                      action,
 3531                      SSD_FULL_SIZE,
 3532                      5000);
 3533 
 3534         error = cam_periph_runccb(ccb, daerror, CAM_RETRY_SELTO,
 3535             SF_RETRY_UA | SF_QUIET_IR, softc->disk->d_devstat);
 3536 
 3537         if (error == 0) {
 3538                 if (action == PR_ALLOW)
 3539                         softc->flags &= ~DA_FLAG_PACK_LOCKED;
 3540                 else
 3541                         softc->flags |= DA_FLAG_PACK_LOCKED;
 3542         }
 3543 
 3544         xpt_release_ccb(ccb);
 3545 }
 3546 
 3547 static void
 3548 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
 3549           struct scsi_read_capacity_data_long *rcaplong, size_t rcap_len)
 3550 {
 3551         struct ccb_calc_geometry ccg;
 3552         struct da_softc *softc;
 3553         struct disk_params *dp;
 3554         u_int lbppbe, lalba;
 3555 
 3556         softc = (struct da_softc *)periph->softc;
 3557 
 3558         dp = &softc->params;
 3559         dp->secsize = block_len;
 3560         dp->sectors = maxsector + 1;
 3561         if (rcaplong != NULL) {
 3562                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
 3563                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
 3564                 lalba &= SRC16_LALBA_A;
 3565         } else {
 3566                 lbppbe = 0;
 3567                 lalba = 0;
 3568         }
 3569 
 3570         if (lbppbe > 0) {
 3571                 dp->stripesize = block_len << lbppbe;
 3572                 dp->stripeoffset = (dp->stripesize - block_len * lalba) %
 3573                     dp->stripesize;
 3574         } else if (softc->quirks & DA_Q_4K) {
 3575                 dp->stripesize = 4096;
 3576                 dp->stripeoffset = 0;
 3577         } else {
 3578                 dp->stripesize = 0;
 3579                 dp->stripeoffset = 0;
 3580         }
 3581         /*
 3582          * Have the controller provide us with a geometry
 3583          * for this disk.  The only time the geometry
 3584          * matters is when we boot and the controller
 3585          * is the only one knowledgeable enough to come
 3586          * up with something that will make this a bootable
 3587          * device.
 3588          */
 3589         xpt_setup_ccb(&ccg.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 3590         ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
 3591         ccg.block_size = dp->secsize;
 3592         ccg.volume_size = dp->sectors;
 3593         ccg.heads = 0;
 3594         ccg.secs_per_track = 0;
 3595         ccg.cylinders = 0;
 3596         xpt_action((union ccb*)&ccg);
 3597         if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 3598                 /*
 3599                  * We don't know what went wrong here- but just pick
 3600                  * a geometry so we don't have nasty things like divide
 3601                  * by zero.
 3602                  */
 3603                 dp->heads = 255;
 3604                 dp->secs_per_track = 255;
 3605                 dp->cylinders = dp->sectors / (255 * 255);
 3606                 if (dp->cylinders == 0) {
 3607                         dp->cylinders = 1;
 3608                 }
 3609         } else {
 3610                 dp->heads = ccg.heads;
 3611                 dp->secs_per_track = ccg.secs_per_track;
 3612                 dp->cylinders = ccg.cylinders;
 3613         }
 3614 
 3615         /*
 3616          * If the user supplied a read capacity buffer, and if it is
 3617          * different than the previous buffer, update the data in the EDT.
 3618          * If it's the same, we don't bother.  This avoids sending an
 3619          * update every time someone opens this device.
 3620          */
 3621         if ((rcaplong != NULL)
 3622          && (bcmp(rcaplong, &softc->rcaplong,
 3623                   min(sizeof(softc->rcaplong), rcap_len)) != 0)) {
 3624                 struct ccb_dev_advinfo cdai;
 3625 
 3626                 xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 3627                 cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
 3628                 cdai.buftype = CDAI_TYPE_RCAPLONG;
 3629                 cdai.flags |= CDAI_FLAG_STORE;
 3630                 cdai.bufsiz = rcap_len;
 3631                 cdai.buf = (uint8_t *)rcaplong;
 3632                 xpt_action((union ccb *)&cdai);
 3633                 if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
 3634                         cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
 3635                 if (cdai.ccb_h.status != CAM_REQ_CMP) {
 3636                         xpt_print(periph->path, "%s: failed to set read "
 3637                                   "capacity advinfo\n", __func__);
 3638                         /* Use cam_error_print() to decode the status */
 3639                         cam_error_print((union ccb *)&cdai, CAM_ESF_CAM_STATUS,
 3640                                         CAM_EPF_ALL);
 3641                 } else {
 3642                         bcopy(rcaplong, &softc->rcaplong,
 3643                               min(sizeof(softc->rcaplong), rcap_len));
 3644                 }
 3645         }
 3646 
 3647         softc->disk->d_sectorsize = softc->params.secsize;
 3648         softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
 3649         softc->disk->d_stripesize = softc->params.stripesize;
 3650         softc->disk->d_stripeoffset = softc->params.stripeoffset;
 3651         /* XXX: these are not actually "firmware" values, so they may be wrong */
 3652         softc->disk->d_fwsectors = softc->params.secs_per_track;
 3653         softc->disk->d_fwheads = softc->params.heads;
 3654         softc->disk->d_devstat->block_size = softc->params.secsize;
 3655         softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
 3656 }
 3657 
 3658 static void
 3659 dasendorderedtag(void *arg)
 3660 {
 3661         struct da_softc *softc = arg;
 3662 
 3663         if (da_send_ordered) {
 3664                 if ((softc->ordered_tag_count == 0) 
 3665                  && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
 3666                         softc->flags |= DA_FLAG_NEED_OTAG;
 3667                 }
 3668                 if (softc->outstanding_cmds > 0)
 3669                         softc->flags &= ~DA_FLAG_WENT_IDLE;
 3670 
 3671                 softc->ordered_tag_count = 0;
 3672         }
 3673         /* Queue us up again */
 3674         callout_reset(&softc->sendordered_c,
 3675             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
 3676             dasendorderedtag, softc);
 3677 }
 3678 
 3679 /*
 3680  * Step through all DA peripheral drivers, and if the device is still open,
 3681  * sync the disk cache to physical media.
 3682  */
 3683 static void
 3684 dashutdown(void * arg, int howto)
 3685 {
 3686         struct cam_periph *periph;
 3687         struct da_softc *softc;
 3688         union ccb *ccb;
 3689         int error;
 3690 
 3691         CAM_PERIPH_FOREACH(periph, &dadriver) {
 3692                 softc = (struct da_softc *)periph->softc;
 3693                 if (SCHEDULER_STOPPED()) {
 3694                         /* If we paniced with the lock held, do not recurse. */
 3695                         if (!cam_periph_owned(periph) &&
 3696                             (softc->flags & DA_FLAG_OPEN)) {
 3697                                 dadump(softc->disk, NULL, 0, 0, 0);
 3698                         }
 3699                         continue;
 3700                 }
 3701                 cam_periph_lock(periph);
 3702 
 3703                 /*
 3704                  * We only sync the cache if the drive is still open, and
 3705                  * if the drive is capable of it..
 3706                  */
 3707                 if (((softc->flags & DA_FLAG_OPEN) == 0)
 3708                  || (softc->quirks & DA_Q_NO_SYNC_CACHE)) {
 3709                         cam_periph_unlock(periph);
 3710                         continue;
 3711                 }
 3712 
 3713                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 3714                 scsi_synchronize_cache(&ccb->csio,
 3715                                        /*retries*/0,
 3716                                        /*cbfcnp*/dadone,
 3717                                        MSG_SIMPLE_Q_TAG,
 3718                                        /*begin_lba*/0, /* whole disk */
 3719                                        /*lb_count*/0,
 3720                                        SSD_FULL_SIZE,
 3721                                        60 * 60 * 1000);
 3722 
 3723                 error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
 3724                     /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR,
 3725                     softc->disk->d_devstat);
 3726                 if (error != 0)
 3727                         xpt_print(periph->path, "Synchronize cache failed\n");
 3728                 xpt_release_ccb(ccb);
 3729                 cam_periph_unlock(periph);
 3730         }
 3731 }
 3732 
 3733 #else /* !_KERNEL */
 3734 
 3735 /*
 3736  * XXX This is only left out of the kernel build to silence warnings.  If,
 3737  * for some reason this function is used in the kernel, the ifdefs should
 3738  * be moved so it is included both in the kernel and userland.
 3739  */
 3740 void
 3741 scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
 3742                  void (*cbfcnp)(struct cam_periph *, union ccb *),
 3743                  u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
 3744                  u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
 3745                  u_int32_t timeout)
 3746 {
 3747         struct scsi_format_unit *scsi_cmd;
 3748 
 3749         scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
 3750         scsi_cmd->opcode = FORMAT_UNIT;
 3751         scsi_cmd->byte2 = byte2;
 3752         scsi_ulto2b(ileave, scsi_cmd->interleave);
 3753 
 3754         cam_fill_csio(csio,
 3755                       retries,
 3756                       cbfcnp,
 3757                       /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
 3758                       tag_action,
 3759                       data_ptr,
 3760                       dxfer_len,
 3761                       sense_len,
 3762                       sizeof(*scsi_cmd),
 3763                       timeout);
 3764 }
 3765 
 3766 #endif /* _KERNEL */

Cache object: a4e53f4c5313a1ace64cc190aed9defd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.