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/ata/ata_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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
    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. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_ada.h"
   33 
   34 #include <sys/param.h>
   35 
   36 #ifdef _KERNEL
   37 #include <sys/systm.h>
   38 #include <sys/kernel.h>
   39 #include <sys/bio.h>
   40 #include <sys/sysctl.h>
   41 #include <sys/taskqueue.h>
   42 #include <sys/lock.h>
   43 #include <sys/mutex.h>
   44 #include <sys/conf.h>
   45 #include <sys/devicestat.h>
   46 #include <sys/eventhandler.h>
   47 #include <sys/malloc.h>
   48 #include <sys/endian.h>
   49 #include <sys/cons.h>
   50 #include <sys/proc.h>
   51 #include <sys/reboot.h>
   52 #include <sys/sbuf.h>
   53 #include <geom/geom.h>
   54 #include <geom/geom_disk.h>
   55 #endif /* _KERNEL */
   56 
   57 #ifndef _KERNEL
   58 #include <stdio.h>
   59 #include <string.h>
   60 #endif /* _KERNEL */
   61 
   62 #include <cam/cam.h>
   63 #include <cam/cam_ccb.h>
   64 #include <cam/cam_periph.h>
   65 #include <cam/cam_xpt_periph.h>
   66 #include <cam/scsi/scsi_all.h>
   67 #include <cam/scsi/scsi_da.h>
   68 #include <cam/cam_sim.h>
   69 #include <cam/cam_iosched.h>
   70 
   71 #include <cam/ata/ata_all.h>
   72 
   73 #ifdef _KERNEL
   74 
   75 #define ATA_MAX_28BIT_LBA               268435455UL
   76 
   77 extern int iosched_debug;
   78 
   79 typedef enum {
   80         ADA_STATE_RAHEAD,
   81         ADA_STATE_WCACHE,
   82         ADA_STATE_LOGDIR,
   83         ADA_STATE_IDDIR,
   84         ADA_STATE_SUP_CAP,
   85         ADA_STATE_ZONE,
   86         ADA_STATE_NORMAL
   87 } ada_state;
   88 
   89 typedef enum {
   90         ADA_FLAG_CAN_48BIT      = 0x00000002,
   91         ADA_FLAG_CAN_FLUSHCACHE = 0x00000004,
   92         ADA_FLAG_CAN_NCQ        = 0x00000008,
   93         ADA_FLAG_CAN_DMA        = 0x00000010,
   94         ADA_FLAG_NEED_OTAG      = 0x00000020,
   95         ADA_FLAG_WAS_OTAG       = 0x00000040,
   96         ADA_FLAG_CAN_TRIM       = 0x00000080,
   97         ADA_FLAG_OPEN           = 0x00000100,
   98         ADA_FLAG_SCTX_INIT      = 0x00000200,
   99         ADA_FLAG_CAN_CFA        = 0x00000400,
  100         ADA_FLAG_CAN_POWERMGT   = 0x00000800,
  101         ADA_FLAG_CAN_DMA48      = 0x00001000,
  102         ADA_FLAG_CAN_LOG        = 0x00002000,
  103         ADA_FLAG_CAN_IDLOG      = 0x00004000,
  104         ADA_FLAG_CAN_SUPCAP     = 0x00008000,
  105         ADA_FLAG_CAN_ZONE       = 0x00010000,
  106         ADA_FLAG_CAN_WCACHE     = 0x00020000,
  107         ADA_FLAG_CAN_RAHEAD     = 0x00040000,
  108         ADA_FLAG_PROBED         = 0x00080000,
  109         ADA_FLAG_ANNOUNCED      = 0x00100000,
  110         ADA_FLAG_DIRTY          = 0x00200000,
  111         ADA_FLAG_CAN_NCQ_TRIM   = 0x00400000,   /* CAN_TRIM also set */
  112         ADA_FLAG_PIM_ATA_EXT    = 0x00800000,
  113         ADA_FLAG_UNMAPPEDIO     = 0x01000000,
  114         ADA_FLAG_ROTATING       = 0x02000000
  115 } ada_flags;
  116 #define ADA_FLAG_STRING         \
  117         "\020"                  \
  118         "\002CAN_48BIT"         \
  119         "\003CAN_FLUSHCACHE"    \
  120         "\004CAN_NCQ"           \
  121         "\005CAN_DMA"           \
  122         "\006NEED_OTAG"         \
  123         "\007WAS_OTAG"          \
  124         "\010CAN_TRIM"          \
  125         "\011OPEN"              \
  126         "\012SCTX_INIT"         \
  127         "\013CAN_CFA"           \
  128         "\014CAN_POWERMGT"      \
  129         "\015CAN_DMA48"         \
  130         "\016CAN_LOG"           \
  131         "\017CAN_IDLOG"         \
  132         "\020CAN_SUPCAP"        \
  133         "\021CAN_ZONE"          \
  134         "\022CAN_WCACHE"        \
  135         "\023CAN_RAHEAD"        \
  136         "\024PROBED"            \
  137         "\025ANNOUNCED"         \
  138         "\026DIRTY"             \
  139         "\027CAN_NCQ_TRIM"      \
  140         "\030PIM_ATA_EXT"       \
  141         "\031UNMAPPEDIO"        \
  142         "\032ROTATING"
  143 
  144 typedef enum {
  145         ADA_Q_NONE              = 0x00,
  146         ADA_Q_4K                = 0x01,
  147         ADA_Q_NCQ_TRIM_BROKEN   = 0x02,
  148         ADA_Q_LOG_BROKEN        = 0x04,
  149         ADA_Q_SMR_DM            = 0x08,
  150         ADA_Q_NO_TRIM           = 0x10,
  151         ADA_Q_128KB             = 0x20
  152 } ada_quirks;
  153 
  154 #define ADA_Q_BIT_STRING        \
  155         "\020"                  \
  156         "\0014K"                \
  157         "\002NCQ_TRIM_BROKEN"   \
  158         "\003LOG_BROKEN"        \
  159         "\004SMR_DM"            \
  160         "\005NO_TRIM"           \
  161         "\006128KB"
  162 
  163 typedef enum {
  164         ADA_CCB_RAHEAD          = 0x01,
  165         ADA_CCB_WCACHE          = 0x02,
  166         ADA_CCB_BUFFER_IO       = 0x03,
  167         ADA_CCB_DUMP            = 0x05,
  168         ADA_CCB_TRIM            = 0x06,
  169         ADA_CCB_LOGDIR          = 0x07,
  170         ADA_CCB_IDDIR           = 0x08,
  171         ADA_CCB_SUP_CAP         = 0x09,
  172         ADA_CCB_ZONE            = 0x0a,
  173         ADA_CCB_TYPE_MASK       = 0x0F,
  174 } ada_ccb_state;
  175 
  176 typedef enum {
  177         ADA_ZONE_NONE           = 0x00,
  178         ADA_ZONE_DRIVE_MANAGED  = 0x01,
  179         ADA_ZONE_HOST_AWARE     = 0x02,
  180         ADA_ZONE_HOST_MANAGED   = 0x03
  181 } ada_zone_mode;
  182 
  183 typedef enum {
  184         ADA_ZONE_FLAG_RZ_SUP            = 0x0001,
  185         ADA_ZONE_FLAG_OPEN_SUP          = 0x0002,
  186         ADA_ZONE_FLAG_CLOSE_SUP         = 0x0004,
  187         ADA_ZONE_FLAG_FINISH_SUP        = 0x0008,
  188         ADA_ZONE_FLAG_RWP_SUP           = 0x0010,
  189         ADA_ZONE_FLAG_SUP_MASK          = (ADA_ZONE_FLAG_RZ_SUP |
  190                                            ADA_ZONE_FLAG_OPEN_SUP |
  191                                            ADA_ZONE_FLAG_CLOSE_SUP |
  192                                            ADA_ZONE_FLAG_FINISH_SUP |
  193                                            ADA_ZONE_FLAG_RWP_SUP),
  194         ADA_ZONE_FLAG_URSWRZ            = 0x0020,
  195         ADA_ZONE_FLAG_OPT_SEQ_SET       = 0x0040,
  196         ADA_ZONE_FLAG_OPT_NONSEQ_SET    = 0x0080,
  197         ADA_ZONE_FLAG_MAX_SEQ_SET       = 0x0100,
  198         ADA_ZONE_FLAG_SET_MASK          = (ADA_ZONE_FLAG_OPT_SEQ_SET |
  199                                            ADA_ZONE_FLAG_OPT_NONSEQ_SET |
  200                                            ADA_ZONE_FLAG_MAX_SEQ_SET)
  201 } ada_zone_flags;
  202 
  203 static struct ada_zone_desc {
  204         ada_zone_flags value;
  205         const char *desc;
  206 } ada_zone_desc_table[] = {
  207         {ADA_ZONE_FLAG_RZ_SUP, "Report Zones" },
  208         {ADA_ZONE_FLAG_OPEN_SUP, "Open" },
  209         {ADA_ZONE_FLAG_CLOSE_SUP, "Close" },
  210         {ADA_ZONE_FLAG_FINISH_SUP, "Finish" },
  211         {ADA_ZONE_FLAG_RWP_SUP, "Reset Write Pointer" },
  212 };
  213 
  214 /* Offsets into our private area for storing information */
  215 #define ccb_state       ppriv_field0
  216 #define ccb_bp          ppriv_ptr1
  217 
  218 typedef enum {
  219         ADA_DELETE_NONE,
  220         ADA_DELETE_DISABLE,
  221         ADA_DELETE_CFA_ERASE,
  222         ADA_DELETE_DSM_TRIM,
  223         ADA_DELETE_NCQ_DSM_TRIM,
  224         ADA_DELETE_MIN = ADA_DELETE_CFA_ERASE,
  225         ADA_DELETE_MAX = ADA_DELETE_NCQ_DSM_TRIM,
  226 } ada_delete_methods;
  227 
  228 static const char *ada_delete_method_names[] =
  229     { "NONE", "DISABLE", "CFA_ERASE", "DSM_TRIM", "NCQ_DSM_TRIM" };
  230 #if 0
  231 static const char *ada_delete_method_desc[] =
  232     { "NONE", "DISABLED", "CFA Erase", "DSM Trim", "DSM Trim via NCQ" };
  233 #endif
  234 
  235 struct disk_params {
  236         u_int8_t  heads;
  237         u_int8_t  secs_per_track;
  238         u_int32_t cylinders;
  239         u_int32_t secsize;      /* Number of bytes/logical sector */
  240         u_int64_t sectors;      /* Total number sectors */
  241 };
  242 
  243 #define TRIM_MAX_BLOCKS 8
  244 #define TRIM_MAX_RANGES (TRIM_MAX_BLOCKS * ATA_DSM_BLK_RANGES)
  245 struct trim_request {
  246         uint8_t         data[TRIM_MAX_RANGES * ATA_DSM_RANGE_SIZE];
  247         TAILQ_HEAD(, bio) bps;
  248 };
  249 
  250 struct ada_softc {
  251         struct   cam_iosched_softc *cam_iosched;
  252         int      outstanding_cmds;      /* Number of active commands */
  253         int      refcount;              /* Active xpt_action() calls */
  254         ada_state state;
  255         ada_flags flags;
  256         ada_zone_mode zone_mode;
  257         ada_zone_flags zone_flags;
  258         struct ata_gp_log_dir ata_logdir;
  259         int valid_logdir_len;
  260         struct ata_identify_log_pages ata_iddir;
  261         int valid_iddir_len;
  262         uint64_t optimal_seq_zones;
  263         uint64_t optimal_nonseq_zones;
  264         uint64_t max_seq_zones;
  265         ada_quirks quirks;
  266         ada_delete_methods delete_method;
  267         int      trim_max_ranges;
  268         int      read_ahead;
  269         int      write_cache;
  270 #ifdef CAM_TEST_FAILURE
  271         int      force_read_error;
  272         int      force_write_error;
  273         int      periodic_read_error;
  274         int      periodic_read_count;
  275 #endif
  276         struct ccb_pathinq      cpi;
  277         struct disk_params      params;
  278         struct disk             *disk;
  279         struct task             sysctl_task;
  280         struct sysctl_ctx_list  sysctl_ctx;
  281         struct sysctl_oid       *sysctl_tree;
  282         struct callout          sendordered_c;
  283         struct trim_request     trim_req;
  284         uint64_t                trim_count;
  285         uint64_t                trim_ranges;
  286         uint64_t                trim_lbas;
  287 #ifdef CAM_IO_STATS
  288         struct sysctl_ctx_list  sysctl_stats_ctx;
  289         struct sysctl_oid       *sysctl_stats_tree;
  290         u_int   timeouts;
  291         u_int   errors;
  292         u_int   invalidations;
  293 #endif
  294 #define ADA_ANNOUNCETMP_SZ 80
  295         char    announce_temp[ADA_ANNOUNCETMP_SZ];
  296 #define ADA_ANNOUNCE_SZ 400
  297         char    announce_buffer[ADA_ANNOUNCE_SZ];
  298 };
  299 
  300 static uma_zone_t ada_ccb_zone;
  301 
  302 struct ada_quirk_entry {
  303         struct scsi_inquiry_pattern inq_pat;
  304         ada_quirks quirks;
  305 };
  306 
  307 static struct ada_quirk_entry ada_quirk_table[] =
  308 {
  309         {
  310                 /* Sandisk X400 */
  311                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SanDisk?SD8SB8U1T00*", "X4162000*" },
  312                 /*quirks*/ADA_Q_128KB
  313         },
  314         {
  315                 /* Hitachi Advanced Format (4k) drives */
  316                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Hitachi H??????????E3*", "*" },
  317                 /*quirks*/ADA_Q_4K
  318         },
  319         {
  320                 /* Samsung Advanced Format (4k) drives */
  321                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD155UI*", "*" },
  322                 /*quirks*/ADA_Q_4K
  323         },
  324         {
  325                 /* Samsung Advanced Format (4k) drives */
  326                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD204UI*", "*" },
  327                 /*quirks*/ADA_Q_4K
  328         },
  329         {
  330                 /* Seagate Barracuda Green Advanced Format (4k) drives */
  331                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DL*", "*" },
  332                 /*quirks*/ADA_Q_4K
  333         },
  334         {
  335                 /* Seagate Barracuda Advanced Format (4k) drives */
  336                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???DM*", "*" },
  337                 /*quirks*/ADA_Q_4K
  338         },
  339         {
  340                 /* Seagate Barracuda Advanced Format (4k) drives */
  341                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DM*", "*" },
  342                 /*quirks*/ADA_Q_4K
  343         },
  344         {
  345                 /* Seagate Momentus Advanced Format (4k) drives */
  346                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500423AS*", "*" },
  347                 /*quirks*/ADA_Q_4K
  348         },
  349         {
  350                 /* Seagate Momentus Advanced Format (4k) drives */
  351                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500424AS*", "*" },
  352                 /*quirks*/ADA_Q_4K
  353         },
  354         {
  355                 /* Seagate Momentus Advanced Format (4k) drives */
  356                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640423AS*", "*" },
  357                 /*quirks*/ADA_Q_4K
  358         },
  359         {
  360                 /* Seagate Momentus Advanced Format (4k) drives */
  361                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640424AS*", "*" },
  362                 /*quirks*/ADA_Q_4K
  363         },
  364         {
  365                 /* Seagate Momentus Advanced Format (4k) drives */
  366                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750420AS*", "*" },
  367                 /*quirks*/ADA_Q_4K
  368         },
  369         {
  370                 /* Seagate Momentus Advanced Format (4k) drives */
  371                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750422AS*", "*" },
  372                 /*quirks*/ADA_Q_4K
  373         },
  374         {
  375                 /* Seagate Momentus Advanced Format (4k) drives */
  376                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750423AS*", "*" },
  377                 /*quirks*/ADA_Q_4K
  378         },
  379         {
  380                 /* Seagate Momentus Thin Advanced Format (4k) drives */
  381                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???LT*", "*" },
  382                 /*quirks*/ADA_Q_4K
  383         },
  384         {
  385                 /* WDC Caviar Red Advanced Format (4k) drives */
  386                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????CX*", "*" },
  387                 /*quirks*/ADA_Q_4K
  388         },
  389         {
  390                 /* WDC Caviar Green Advanced Format (4k) drives */
  391                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RS*", "*" },
  392                 /*quirks*/ADA_Q_4K
  393         },
  394         {
  395                 /* WDC Caviar Green/Red Advanced Format (4k) drives */
  396                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RX*", "*" },
  397                 /*quirks*/ADA_Q_4K
  398         },
  399         {
  400                 /* WDC Caviar Red Advanced Format (4k) drives */
  401                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????CX*", "*" },
  402                 /*quirks*/ADA_Q_4K
  403         },
  404         {
  405                 /* WDC Caviar Black Advanced Format (4k) drives */
  406                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????AZEX*", "*" },
  407                 /*quirks*/ADA_Q_4K
  408         },
  409         {
  410                 /* WDC Caviar Black Advanced Format (4k) drives */
  411                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????FZEX*", "*" },
  412                 /*quirks*/ADA_Q_4K
  413         },
  414         {
  415                 /* WDC Caviar Green Advanced Format (4k) drives */
  416                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RS*", "*" },
  417                 /*quirks*/ADA_Q_4K
  418         },
  419         {
  420                 /* WDC Caviar Green Advanced Format (4k) drives */
  421                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RX*", "*" },
  422                 /*quirks*/ADA_Q_4K
  423         },
  424         {
  425                 /* WDC Scorpio Black Advanced Format (4k) drives */
  426                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PKT*", "*" },
  427                 /*quirks*/ADA_Q_4K
  428         },
  429         {
  430                 /* WDC Scorpio Black Advanced Format (4k) drives */
  431                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PKT*", "*" },
  432                 /*quirks*/ADA_Q_4K
  433         },
  434         {
  435                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  436                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PVT*", "*" },
  437                 /*quirks*/ADA_Q_4K
  438         },
  439         {
  440                 /* WDC Scorpio Blue Advanced Format (4k) drives */
  441                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PVT*", "*" },
  442                 /*quirks*/ADA_Q_4K
  443         },
  444         /* SSDs */
  445         {
  446                 /*
  447                  * Corsair Force 2 SSDs
  448                  * 4k optimised & trim only works in 4k requests + 4k aligned
  449                  */
  450                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair CSSD-F*", "*" },
  451                 /*quirks*/ADA_Q_4K
  452         },
  453         {
  454                 /*
  455                  * Corsair Force 3 SSDs
  456                  * 4k optimised & trim only works in 4k requests + 4k aligned
  457                  */
  458                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Force 3*", "*" },
  459                 /*quirks*/ADA_Q_4K
  460         },
  461         {
  462                 /*
  463                  * Corsair Neutron GTX SSDs
  464                  * 4k optimised & trim only works in 4k requests + 4k aligned
  465                  */
  466                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Neutron GTX*", "*" },
  467                 /*quirks*/ADA_Q_4K
  468         },
  469         {
  470                 /*
  471                  * Corsair Force GT & GS SSDs
  472                  * 4k optimised & trim only works in 4k requests + 4k aligned
  473                  */
  474                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Force G*", "*" },
  475                 /*quirks*/ADA_Q_4K
  476         },
  477         {
  478                 /*
  479                  * Crucial M4 SSDs
  480                  * 4k optimised & trim only works in 4k requests + 4k aligned
  481                  */
  482                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "M4-CT???M4SSD2*", "*" },
  483                 /*quirks*/ADA_Q_4K
  484         },
  485         {
  486                 /*
  487                  * Crucial M500 SSDs MU07 firmware
  488                  * NCQ Trim works
  489                  */
  490                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M500*", "MU07" },
  491                 /*quirks*/
  492         },
  493         {
  494                 /*
  495                  * Crucial M500 SSDs all other firmware
  496                  * NCQ Trim doesn't work
  497                  */
  498                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M500*", "*" },
  499                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  500         },
  501         {
  502                 /*
  503                  * Crucial M550 SSDs
  504                  * NCQ Trim doesn't work, but only on MU01 firmware
  505                  */
  506                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M550*", "MU01" },
  507                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  508         },
  509         {
  510                 /*
  511                  * Crucial MX100 SSDs
  512                  * NCQ Trim doesn't work, but only on MU01 firmware
  513                  */
  514                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*MX100*", "MU01" },
  515                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  516         },
  517         {
  518                 /*
  519                  * Crucial RealSSD C300 SSDs
  520                  * 4k optimised
  521                  */
  522                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "C300-CTFDDAC???MAG*",
  523                 "*" }, /*quirks*/ADA_Q_4K
  524         },
  525         {
  526                 /*
  527                  * FCCT M500 SSDs
  528                  * NCQ Trim doesn't work
  529                  */
  530                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "FCCT*M500*", "*" },
  531                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  532         },
  533         {
  534                 /*
  535                  * Intel 320 Series SSDs
  536                  * 4k optimised & trim only works in 4k requests + 4k aligned
  537                  */
  538                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSA2CW*", "*" },
  539                 /*quirks*/ADA_Q_4K
  540         },
  541         {
  542                 /*
  543                  * Intel 330 Series SSDs
  544                  * 4k optimised & trim only works in 4k requests + 4k aligned
  545                  */
  546                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2CT*", "*" },
  547                 /*quirks*/ADA_Q_4K
  548         },
  549         {
  550                 /*
  551                  * Intel 510 Series SSDs
  552                  * 4k optimised & trim only works in 4k requests + 4k aligned
  553                  */
  554                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2MH*", "*" },
  555                 /*quirks*/ADA_Q_4K
  556         },
  557         {
  558                 /*
  559                  * Intel 520 Series SSDs
  560                  * 4k optimised & trim only works in 4k requests + 4k aligned
  561                  */
  562                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BW*", "*" },
  563                 /*quirks*/ADA_Q_4K
  564         },
  565         {
  566                 /*
  567                  * Intel S3610 Series SSDs
  568                  * 4k optimised & trim only works in 4k requests + 4k aligned
  569                  */
  570                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BX*", "*" },
  571                 /*quirks*/ADA_Q_4K
  572         },
  573         {
  574                 /*
  575                  * Intel X25-M Series SSDs
  576                  * 4k optimised & trim only works in 4k requests + 4k aligned
  577                  */
  578                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSA2M*", "*" },
  579                 /*quirks*/ADA_Q_4K
  580         },
  581         {
  582                 /*
  583                  * KingDian S200 60GB P0921B
  584                  * Trimming crash the SSD
  585                  */
  586                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KingDian S200 *", "*" },
  587                 /*quirks*/ADA_Q_NO_TRIM
  588         },
  589         {
  590                 /*
  591                  * Kingston E100 Series SSDs
  592                  * 4k optimised & trim only works in 4k requests + 4k aligned
  593                  */
  594                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KINGSTON SE100S3*", "*" },
  595                 /*quirks*/ADA_Q_4K
  596         },
  597         {
  598                 /*
  599                  * Kingston HyperX 3k SSDs
  600                  * 4k optimised & trim only works in 4k requests + 4k aligned
  601                  */
  602                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KINGSTON SH103S3*", "*" },
  603                 /*quirks*/ADA_Q_4K
  604         },
  605         {
  606                 /*
  607                  * Marvell SSDs (entry taken from OpenSolaris)
  608                  * 4k optimised & trim only works in 4k requests + 4k aligned
  609                  */
  610                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "MARVELL SD88SA02*", "*" },
  611                 /*quirks*/ADA_Q_4K
  612         },
  613         {
  614                 /*
  615                  * Micron M500 SSDs firmware MU07
  616                  * NCQ Trim works?
  617                  */
  618                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M500*", "MU07" },
  619                 /*quirks*/
  620         },
  621         {
  622                 /*
  623                  * Micron M500 SSDs all other firmware
  624                  * NCQ Trim doesn't work
  625                  */
  626                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M500*", "*" },
  627                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  628         },
  629         {
  630                 /*
  631                  * Micron M5[15]0 SSDs
  632                  * NCQ Trim doesn't work, but only MU01 firmware
  633                  */
  634                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M5[15]0*", "MU01" },
  635                 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
  636         },
  637         {
  638                 /*
  639                  * Micron 5100 SSDs
  640                  * 4k optimised & trim only works in 4k requests + 4k aligned
  641                  */
  642                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron 5100 MTFDDAK*", "*" },
  643                 /*quirks*/ADA_Q_4K
  644         },
  645         {
  646                 /*
  647                  * OCZ Agility 2 SSDs
  648                  * 4k optimised & trim only works in 4k requests + 4k aligned
  649                  */
  650                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY2*", "*" },
  651                 /*quirks*/ADA_Q_4K
  652         },
  653         {
  654                 /*
  655                  * OCZ Agility 3 SSDs
  656                  * 4k optimised & trim only works in 4k requests + 4k aligned
  657                  */
  658                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY3*", "*" },
  659                 /*quirks*/ADA_Q_4K
  660         },
  661         {
  662                 /*
  663                  * OCZ Deneva R Series SSDs
  664                  * 4k optimised & trim only works in 4k requests + 4k aligned
  665                  */
  666                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "DENRSTE251M45*", "*" },
  667                 /*quirks*/ADA_Q_4K
  668         },
  669         {
  670                 /*
  671                  * OCZ Vertex 2 SSDs (inc pro series)
  672                  * 4k optimised & trim only works in 4k requests + 4k aligned
  673                  */
  674                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ?VERTEX2*", "*" },
  675                 /*quirks*/ADA_Q_4K
  676         },
  677         {
  678                 /*
  679                  * OCZ Vertex 3 SSDs
  680                  * 4k optimised & trim only works in 4k requests + 4k aligned
  681                  */
  682                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX3*", "*" },
  683                 /*quirks*/ADA_Q_4K
  684         },
  685         {
  686                 /*
  687                  * OCZ Vertex 4 SSDs
  688                  * 4k optimised & trim only works in 4k requests + 4k aligned
  689                  */
  690                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX4*", "*" },
  691                 /*quirks*/ADA_Q_4K
  692         },
  693         {
  694                 /*
  695                  * Samsung 750 SSDs
  696                  * 4k optimised, NCQ TRIM seems to work
  697                  */
  698                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 750*", "*" },
  699                 /*quirks*/ADA_Q_4K
  700         },
  701         {
  702                 /*
  703                  * Samsung 830 Series SSDs
  704                  * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
  705                  */
  706                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG SSD 830 Series*", "*" },
  707                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  708         },
  709         {
  710                 /*
  711                  * Samsung 840 SSDs
  712                  * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
  713                  */
  714                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 840*", "*" },
  715                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  716         },
  717         {
  718                 /*
  719                  * Samsung 845 SSDs
  720                  * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
  721                  */
  722                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 845*", "*" },
  723                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  724         },
  725         {
  726                 /*
  727                  * Samsung 850 SSDs
  728                  * 4k optimised, NCQ TRIM broken (normal TRIM fine)
  729                  */
  730                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 850*", "*" },
  731                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  732         },
  733         {
  734                 /*
  735                  * Samsung SM863 Series SSDs (MZ7KM*)
  736                  * 4k optimised, NCQ believed to be working
  737                  */
  738                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG MZ7KM*", "*" },
  739                 /*quirks*/ADA_Q_4K
  740         },
  741         {
  742                 /*
  743                  * Samsung 843T Series SSDs (MZ7WD*)
  744                  * Samsung PM851 Series SSDs (MZ7TE*)
  745                  * Samsung PM853T Series SSDs (MZ7GE*)
  746                  * 4k optimised, NCQ believed to be broken since these are
  747                  * appear to be built with the same controllers as the 840/850.
  748                  */
  749                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG MZ7*", "*" },
  750                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  751         },
  752         {
  753                 /*
  754                  * Same as for SAMSUNG MZ7* but enable the quirks for SSD
  755                  * starting with MZ7* too
  756                  */
  757                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "MZ7*", "*" },
  758                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  759         },
  760         {
  761                 /*
  762                  * Samsung PM851 Series SSDs Dell OEM
  763                  * device model          "SAMSUNG SSD PM851 mSATA 256GB"
  764                  * 4k optimised, NCQ broken
  765                  */
  766                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG SSD PM851*", "*" },
  767                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  768         },
  769         {
  770                 /*
  771                  * SuperTalent TeraDrive CT SSDs
  772                  * 4k optimised & trim only works in 4k requests + 4k aligned
  773                  */
  774                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "FTM??CT25H*", "*" },
  775                 /*quirks*/ADA_Q_4K
  776         },
  777         {
  778                 /*
  779                  * XceedIOPS SATA SSDs
  780                  * 4k optimised
  781                  */
  782                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SG9XCS2D*", "*" },
  783                 /*quirks*/ADA_Q_4K
  784         },
  785         {
  786                 /*
  787                  * Samsung drive that doesn't support READ LOG EXT or
  788                  * READ LOG DMA EXT, despite reporting that it does in
  789                  * ATA identify data:
  790                  * SAMSUNG HD200HJ KF100-06
  791                  */
  792                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD200*", "*" },
  793                 /*quirks*/ADA_Q_LOG_BROKEN
  794         },
  795         {
  796                 /*
  797                  * Samsung drive that doesn't support READ LOG EXT or
  798                  * READ LOG DMA EXT, despite reporting that it does in
  799                  * ATA identify data:
  800                  * SAMSUNG HD501LJ CR100-10
  801                  */
  802                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD501*", "*" },
  803                 /*quirks*/ADA_Q_LOG_BROKEN
  804         },
  805         {
  806                 /*
  807                  * Seagate Lamarr 8TB Shingled Magnetic Recording (SMR)
  808                  * Drive Managed SATA hard drive.  This drive doesn't report
  809                  * in firmware that it is a drive managed SMR drive.
  810                  */
  811                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST8000AS000[23]*", "*" },
  812                 /*quirks*/ADA_Q_SMR_DM
  813         },
  814         {
  815                 /* WD Green SSD */
  816                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WDS?????G0*", "*" },
  817                 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
  818         },
  819         {
  820                 /* Default */
  821                 {
  822                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  823                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
  824                 },
  825                 /*quirks*/
  826         },
  827 };
  828 
  829 static  disk_strategy_t adastrategy;
  830 static  dumper_t        adadump;
  831 static  periph_init_t   adainit;
  832 static  void            adadiskgonecb(struct disk *dp);
  833 static  periph_oninv_t  adaoninvalidate;
  834 static  periph_dtor_t   adacleanup;
  835 static  void            adaasync(void *callback_arg, u_int32_t code,
  836                                 struct cam_path *path, void *arg);
  837 static  int             adabitsysctl(SYSCTL_HANDLER_ARGS);
  838 static  int             adaflagssysctl(SYSCTL_HANDLER_ARGS);
  839 static  int             adazonesupsysctl(SYSCTL_HANDLER_ARGS);
  840 static  void            adasysctlinit(void *context, int pending);
  841 static  int             adagetattr(struct bio *bp);
  842 static  void            adasetflags(struct ada_softc *softc,
  843                                     struct ccb_getdev *cgd);
  844 static void             adasetgeom(struct ada_softc *softc,
  845                                    struct ccb_getdev *cgd);
  846 static  periph_ctor_t   adaregister;
  847 static  void            ada_dsmtrim(struct ada_softc *softc, struct bio *bp,
  848                                     struct ccb_ataio *ataio);
  849 static  void            ada_cfaerase(struct ada_softc *softc, struct bio *bp,
  850                                      struct ccb_ataio *ataio);
  851 static  int             ada_zone_bio_to_ata(int disk_zone_cmd);
  852 static  int             ada_zone_cmd(struct cam_periph *periph, union ccb *ccb,
  853                                      struct bio *bp, int *queue_ccb);
  854 static  periph_start_t  adastart;
  855 static  void            adaprobedone(struct cam_periph *periph, union ccb *ccb);
  856 static  void            adazonedone(struct cam_periph *periph, union ccb *ccb);
  857 static  void            adadone(struct cam_periph *periph,
  858                                union ccb *done_ccb);
  859 static  int             adaerror(union ccb *ccb, u_int32_t cam_flags,
  860                                 u_int32_t sense_flags);
  861 static callout_func_t   adasendorderedtag;
  862 static void             adashutdown(void *arg, int howto);
  863 static void             adasuspend(void *arg);
  864 static void             adaresume(void *arg);
  865 
  866 #ifndef ADA_DEFAULT_TIMEOUT
  867 #define ADA_DEFAULT_TIMEOUT 30  /* Timeout in seconds */
  868 #endif
  869 
  870 #ifndef ADA_DEFAULT_RETRY
  871 #define ADA_DEFAULT_RETRY       4
  872 #endif
  873 
  874 #ifndef ADA_DEFAULT_SEND_ORDERED
  875 #define ADA_DEFAULT_SEND_ORDERED        1
  876 #endif
  877 
  878 #ifndef ADA_DEFAULT_SPINDOWN_SHUTDOWN
  879 #define ADA_DEFAULT_SPINDOWN_SHUTDOWN   1
  880 #endif
  881 
  882 #ifndef ADA_DEFAULT_SPINDOWN_SUSPEND
  883 #define ADA_DEFAULT_SPINDOWN_SUSPEND    1
  884 #endif
  885 
  886 #ifndef ADA_DEFAULT_READ_AHEAD
  887 #define ADA_DEFAULT_READ_AHEAD  1
  888 #endif
  889 
  890 #ifndef ADA_DEFAULT_WRITE_CACHE
  891 #define ADA_DEFAULT_WRITE_CACHE 1
  892 #endif
  893 
  894 #define ADA_RA  (softc->read_ahead >= 0 ? \
  895                  softc->read_ahead : ada_read_ahead)
  896 #define ADA_WC  (softc->write_cache >= 0 ? \
  897                  softc->write_cache : ada_write_cache)
  898 
  899 static int ada_retry_count = ADA_DEFAULT_RETRY;
  900 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT;
  901 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED;
  902 static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN;
  903 static int ada_spindown_suspend = ADA_DEFAULT_SPINDOWN_SUSPEND;
  904 static int ada_read_ahead = ADA_DEFAULT_READ_AHEAD;
  905 static int ada_write_cache = ADA_DEFAULT_WRITE_CACHE;
  906 static int ada_enable_biospeedup = 1;
  907 static int ada_enable_uma_ccbs = 1;
  908 
  909 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
  910     "CAM Direct Access Disk driver");
  911 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RWTUN,
  912            &ada_retry_count, 0, "Normal I/O retry count");
  913 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RWTUN,
  914            &ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
  915 SYSCTL_INT(_kern_cam_ada, OID_AUTO, send_ordered, CTLFLAG_RWTUN,
  916            &ada_send_ordered, 0, "Send Ordered Tags");
  917 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RWTUN,
  918            &ada_spindown_shutdown, 0, "Spin down upon shutdown");
  919 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_suspend, CTLFLAG_RWTUN,
  920            &ada_spindown_suspend, 0, "Spin down upon suspend");
  921 SYSCTL_INT(_kern_cam_ada, OID_AUTO, read_ahead, CTLFLAG_RWTUN,
  922            &ada_read_ahead, 0, "Enable disk read-ahead");
  923 SYSCTL_INT(_kern_cam_ada, OID_AUTO, write_cache, CTLFLAG_RWTUN,
  924            &ada_write_cache, 0, "Enable disk write cache");
  925 SYSCTL_INT(_kern_cam_ada, OID_AUTO, enable_biospeedup, CTLFLAG_RDTUN,
  926            &ada_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
  927 SYSCTL_INT(_kern_cam_ada, OID_AUTO, enable_uma_ccbs, CTLFLAG_RWTUN,
  928             &ada_enable_uma_ccbs, 0, "Use UMA for CCBs");
  929 
  930 /*
  931  * ADA_ORDEREDTAG_INTERVAL determines how often, relative
  932  * to the default timeout, we check to see whether an ordered
  933  * tagged transaction is appropriate to prevent simple tag
  934  * starvation.  Since we'd like to ensure that there is at least
  935  * 1/2 of the timeout length left for a starved transaction to
  936  * complete after we've sent an ordered tag, we must poll at least
  937  * four times in every timeout period.  This takes care of the worst
  938  * case where a starved transaction starts during an interval that
  939  * meets the requirement "don't send an ordered tag" test so it takes
  940  * us two intervals to determine that a tag must be sent.
  941  */
  942 #ifndef ADA_ORDEREDTAG_INTERVAL
  943 #define ADA_ORDEREDTAG_INTERVAL 4
  944 #endif
  945 
  946 static struct periph_driver adadriver =
  947 {
  948         adainit, "ada",
  949         TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0
  950 };
  951 
  952 static int adadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
  953 
  954 PERIPHDRIVER_DECLARE(ada, adadriver);
  955 
  956 static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers");
  957 
  958 static int
  959 adaopen(struct disk *dp)
  960 {
  961         struct cam_periph *periph;
  962         struct ada_softc *softc;
  963         int error;
  964 
  965         periph = (struct cam_periph *)dp->d_drv1;
  966         if (cam_periph_acquire(periph) != 0) {
  967                 return(ENXIO);
  968         }
  969 
  970         cam_periph_lock(periph);
  971         if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
  972                 cam_periph_unlock(periph);
  973                 cam_periph_release(periph);
  974                 return (error);
  975         }
  976 
  977         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
  978             ("adaopen\n"));
  979 
  980         softc = (struct ada_softc *)periph->softc;
  981         softc->flags |= ADA_FLAG_OPEN;
  982 
  983         cam_periph_unhold(periph);
  984         cam_periph_unlock(periph);
  985         return (0);
  986 }
  987 
  988 static int
  989 adaclose(struct disk *dp)
  990 {
  991         struct  cam_periph *periph;
  992         struct  ada_softc *softc;
  993         union ccb *ccb;
  994         int error;
  995 
  996         periph = (struct cam_periph *)dp->d_drv1;
  997         softc = (struct ada_softc *)periph->softc;
  998         cam_periph_lock(periph);
  999 
 1000         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
 1001             ("adaclose\n"));
 1002 
 1003         /* We only sync the cache if the drive is capable of it. */
 1004         if ((softc->flags & ADA_FLAG_DIRTY) != 0 &&
 1005             (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
 1006             (periph->flags & CAM_PERIPH_INVALID) == 0 &&
 1007             cam_periph_hold(periph, PRIBIO) == 0) {
 1008                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 1009                 cam_fill_ataio(&ccb->ataio,
 1010                                     1,
 1011                                     NULL,
 1012                                     CAM_DIR_NONE,
 1013                                     0,
 1014                                     NULL,
 1015                                     0,
 1016                                     ada_default_timeout*1000);
 1017 
 1018                 if (softc->flags & ADA_FLAG_CAN_48BIT)
 1019                         ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
 1020                 else
 1021                         ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
 1022                 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
 1023                     /*sense_flags*/0, softc->disk->d_devstat);
 1024 
 1025                 if (error != 0)
 1026                         xpt_print(periph->path, "Synchronize cache failed\n");
 1027                 softc->flags &= ~ADA_FLAG_DIRTY;
 1028                 xpt_release_ccb(ccb);
 1029                 cam_periph_unhold(periph);
 1030         }
 1031 
 1032         softc->flags &= ~ADA_FLAG_OPEN;
 1033 
 1034         while (softc->refcount != 0)
 1035                 cam_periph_sleep(periph, &softc->refcount, PRIBIO, "adaclose", 1);
 1036         cam_periph_unlock(periph);
 1037         cam_periph_release(periph);
 1038         return (0);
 1039 }
 1040 
 1041 static void
 1042 adaschedule(struct cam_periph *periph)
 1043 {
 1044         struct ada_softc *softc = (struct ada_softc *)periph->softc;
 1045 
 1046         if (softc->state != ADA_STATE_NORMAL)
 1047                 return;
 1048 
 1049         cam_iosched_schedule(softc->cam_iosched, periph);
 1050 }
 1051 
 1052 /*
 1053  * Actually translate the requested transfer into one the physical driver
 1054  * can understand.  The transfer is described by a buf and will include
 1055  * only one physical transfer.
 1056  */
 1057 static void
 1058 adastrategy(struct bio *bp)
 1059 {
 1060         struct cam_periph *periph;
 1061         struct ada_softc *softc;
 1062 
 1063         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 1064         softc = (struct ada_softc *)periph->softc;
 1065 
 1066         cam_periph_lock(periph);
 1067 
 1068         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastrategy(%p)\n", bp));
 1069 
 1070         /*
 1071          * If the device has been made invalid, error out
 1072          */
 1073         if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
 1074                 cam_periph_unlock(periph);
 1075                 biofinish(bp, NULL, ENXIO);
 1076                 return;
 1077         }
 1078 
 1079         /*
 1080          * Zone commands must be ordered, because they can depend on the
 1081          * effects of previously issued commands, and they may affect
 1082          * commands after them.
 1083          */
 1084         if (bp->bio_cmd == BIO_ZONE)
 1085                 bp->bio_flags |= BIO_ORDERED;
 1086 
 1087         /*
 1088          * Place it in the queue of disk activities for this disk
 1089          */
 1090         cam_iosched_queue_work(softc->cam_iosched, bp);
 1091 
 1092         /*
 1093          * Schedule ourselves for performing the work.
 1094          */
 1095         adaschedule(periph);
 1096         cam_periph_unlock(periph);
 1097 
 1098         return;
 1099 }
 1100 
 1101 static int
 1102 adadump(void *arg, void *virtual, off_t offset, size_t length)
 1103 {
 1104         struct      cam_periph *periph;
 1105         struct      ada_softc *softc;
 1106         u_int       secsize;
 1107         struct      ccb_ataio ataio;
 1108         struct      disk *dp;
 1109         uint64_t    lba;
 1110         uint16_t    count;
 1111         int         error = 0;
 1112 
 1113         dp = arg;
 1114         periph = dp->d_drv1;
 1115         softc = (struct ada_softc *)periph->softc;
 1116         secsize = softc->params.secsize;
 1117         lba = offset / secsize;
 1118         count = length / secsize;
 1119         if ((periph->flags & CAM_PERIPH_INVALID) != 0)
 1120                 return (ENXIO);
 1121 
 1122         memset(&ataio, 0, sizeof(ataio));
 1123         if (length > 0) {
 1124                 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 1125                 ataio.ccb_h.ccb_state = ADA_CCB_DUMP;
 1126                 cam_fill_ataio(&ataio,
 1127                     0,
 1128                     NULL,
 1129                     CAM_DIR_OUT,
 1130                     0,
 1131                     (u_int8_t *) virtual,
 1132                     length,
 1133                     ada_default_timeout*1000);
 1134                 if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
 1135                     (lba + count >= ATA_MAX_28BIT_LBA ||
 1136                     count >= 256)) {
 1137                         ata_48bit_cmd(&ataio, ATA_WRITE_DMA48,
 1138                             0, lba, count);
 1139                 } else {
 1140                         ata_28bit_cmd(&ataio, ATA_WRITE_DMA,
 1141                             0, lba, count);
 1142                 }
 1143                 error = cam_periph_runccb((union ccb *)&ataio, adaerror,
 1144                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
 1145                 if (error != 0)
 1146                         printf("Aborting dump due to I/O error.\n");
 1147 
 1148                 return (error);
 1149         }
 1150 
 1151         if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
 1152                 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 1153 
 1154                 /*
 1155                  * Tell the drive to flush its internal cache. if we
 1156                  * can't flush in 5s we have big problems. No need to
 1157                  * wait the default 60s to detect problems.
 1158                  */
 1159                 ataio.ccb_h.ccb_state = ADA_CCB_DUMP;
 1160                 cam_fill_ataio(&ataio,
 1161                                     0,
 1162                                     NULL,
 1163                                     CAM_DIR_NONE,
 1164                                     0,
 1165                                     NULL,
 1166                                     0,
 1167                                     5*1000);
 1168 
 1169                 if (softc->flags & ADA_FLAG_CAN_48BIT)
 1170                         ata_48bit_cmd(&ataio, ATA_FLUSHCACHE48, 0, 0, 0);
 1171                 else
 1172                         ata_28bit_cmd(&ataio, ATA_FLUSHCACHE, 0, 0, 0);
 1173                 error = cam_periph_runccb((union ccb *)&ataio, adaerror,
 1174                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
 1175                 if (error != 0)
 1176                         xpt_print(periph->path, "Synchronize cache failed\n");
 1177         }
 1178         return (error);
 1179 }
 1180 
 1181 static void
 1182 adainit(void)
 1183 {
 1184         cam_status status;
 1185 
 1186         ada_ccb_zone = uma_zcreate("ada_ccb",
 1187             sizeof(struct ccb_ataio), NULL, NULL, NULL, NULL,
 1188             UMA_ALIGN_PTR, 0);
 1189 
 1190         /*
 1191          * Install a global async callback.  This callback will
 1192          * receive async callbacks like "new device found".
 1193          */
 1194         status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL);
 1195 
 1196         if (status != CAM_REQ_CMP) {
 1197                 printf("ada: Failed to attach master async callback "
 1198                        "due to status 0x%x!\n", status);
 1199         } else if (ada_send_ordered) {
 1200                 /* Register our event handlers */
 1201                 if ((EVENTHANDLER_REGISTER(power_suspend, adasuspend,
 1202                                            NULL, EVENTHANDLER_PRI_LAST)) == NULL)
 1203                     printf("adainit: power event registration failed!\n");
 1204                 if ((EVENTHANDLER_REGISTER(power_resume, adaresume,
 1205                                            NULL, EVENTHANDLER_PRI_LAST)) == NULL)
 1206                     printf("adainit: power event registration failed!\n");
 1207                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown,
 1208                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
 1209                     printf("adainit: shutdown event registration failed!\n");
 1210         }
 1211 }
 1212 
 1213 /*
 1214  * Callback from GEOM, called when it has finished cleaning up its
 1215  * resources.
 1216  */
 1217 static void
 1218 adadiskgonecb(struct disk *dp)
 1219 {
 1220         struct cam_periph *periph;
 1221 
 1222         periph = (struct cam_periph *)dp->d_drv1;
 1223 
 1224         cam_periph_release(periph);
 1225 }
 1226 
 1227 static void
 1228 adaoninvalidate(struct cam_periph *periph)
 1229 {
 1230         struct ada_softc *softc;
 1231 
 1232         softc = (struct ada_softc *)periph->softc;
 1233 
 1234         /*
 1235          * De-register any async callbacks.
 1236          */
 1237         xpt_register_async(0, adaasync, periph, periph->path);
 1238 #ifdef CAM_IO_STATS
 1239         softc->invalidations++;
 1240 #endif
 1241 
 1242         /*
 1243          * Return all queued I/O with ENXIO. Transactions may be queued up here
 1244          * for retry (since we are called while there's other transactions
 1245          * pending). Any requests in the hardware will drain before ndacleanup
 1246          * is called.
 1247          */
 1248         cam_iosched_flush(softc->cam_iosched, NULL, ENXIO);
 1249 
 1250         /*
 1251          * Tell GEOM that we've gone away, we'll get a callback when it is
 1252          * done cleaning up its resources.
 1253          */
 1254         disk_gone(softc->disk);
 1255 }
 1256 
 1257 static void
 1258 adacleanup(struct cam_periph *periph)
 1259 {
 1260         struct ada_softc *softc;
 1261 
 1262         softc = (struct ada_softc *)periph->softc;
 1263 
 1264         cam_periph_unlock(periph);
 1265 
 1266         cam_iosched_fini(softc->cam_iosched);
 1267 
 1268         /*
 1269          * If we can't free the sysctl tree, oh well...
 1270          */
 1271         if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0) {
 1272 #ifdef CAM_IO_STATS
 1273                 if (sysctl_ctx_free(&softc->sysctl_stats_ctx) != 0)
 1274                         xpt_print(periph->path,
 1275                             "can't remove sysctl stats context\n");
 1276 #endif
 1277                 if (sysctl_ctx_free(&softc->sysctl_ctx) != 0)
 1278                         xpt_print(periph->path,
 1279                             "can't remove sysctl context\n");
 1280         }
 1281 
 1282         disk_destroy(softc->disk);
 1283         callout_drain(&softc->sendordered_c);
 1284         free(softc, M_DEVBUF);
 1285         cam_periph_lock(periph);
 1286 }
 1287 
 1288 static void
 1289 adasetdeletemethod(struct ada_softc *softc)
 1290 {
 1291 
 1292         if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
 1293                 softc->delete_method = ADA_DELETE_NCQ_DSM_TRIM;
 1294         else if (softc->flags & ADA_FLAG_CAN_TRIM)
 1295                 softc->delete_method = ADA_DELETE_DSM_TRIM;
 1296         else if ((softc->flags & ADA_FLAG_CAN_CFA) && !(softc->flags & ADA_FLAG_CAN_48BIT))
 1297                 softc->delete_method = ADA_DELETE_CFA_ERASE;
 1298         else
 1299                 softc->delete_method = ADA_DELETE_NONE;
 1300 }
 1301 
 1302 static void
 1303 adaasync(void *callback_arg, u_int32_t code,
 1304         struct cam_path *path, void *arg)
 1305 {
 1306         struct ccb_getdev cgd;
 1307         struct cam_periph *periph;
 1308         struct ada_softc *softc;
 1309 
 1310         periph = (struct cam_periph *)callback_arg;
 1311         switch (code) {
 1312         case AC_FOUND_DEVICE:
 1313         {
 1314                 struct ccb_getdev *cgd;
 1315                 cam_status status;
 1316 
 1317                 cgd = (struct ccb_getdev *)arg;
 1318                 if (cgd == NULL)
 1319                         break;
 1320 
 1321                 if (cgd->protocol != PROTO_ATA)
 1322                         break;
 1323 
 1324                 /*
 1325                  * Allocate a peripheral instance for
 1326                  * this device and start the probe
 1327                  * process.
 1328                  */
 1329                 status = cam_periph_alloc(adaregister, adaoninvalidate,
 1330                                           adacleanup, adastart,
 1331                                           "ada", CAM_PERIPH_BIO,
 1332                                           path, adaasync,
 1333                                           AC_FOUND_DEVICE, cgd);
 1334 
 1335                 if (status != CAM_REQ_CMP
 1336                  && status != CAM_REQ_INPROG)
 1337                         printf("adaasync: Unable to attach to new device "
 1338                                 "due to status 0x%x\n", status);
 1339                 break;
 1340         }
 1341         case AC_GETDEV_CHANGED:
 1342         {
 1343                 softc = (struct ada_softc *)periph->softc;
 1344                 memset(&cgd, 0, sizeof(cgd));
 1345                 xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 1346                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 1347                 xpt_action((union ccb *)&cgd);
 1348 
 1349                 /*
 1350                  * Update our information based on the new Identify data.
 1351                  */
 1352                 adasetflags(softc, &cgd);
 1353                 adasetgeom(softc, &cgd);
 1354                 disk_resize(softc->disk, M_NOWAIT);
 1355                 break;
 1356         }
 1357         case AC_ADVINFO_CHANGED:
 1358         {
 1359                 uintptr_t buftype;
 1360 
 1361                 buftype = (uintptr_t)arg;
 1362                 if (buftype == CDAI_TYPE_PHYS_PATH) {
 1363                         struct ada_softc *softc;
 1364 
 1365                         softc = periph->softc;
 1366                         disk_attr_changed(softc->disk, "GEOM::physpath",
 1367                                           M_NOWAIT);
 1368                 }
 1369                 break;
 1370         }
 1371         case AC_SENT_BDR:
 1372         case AC_BUS_RESET:
 1373         {
 1374                 softc = (struct ada_softc *)periph->softc;
 1375                 if (softc->state != ADA_STATE_NORMAL)
 1376                         break;
 1377                 if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD)
 1378                         softc->state = ADA_STATE_RAHEAD;
 1379                 else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE)
 1380                         softc->state = ADA_STATE_WCACHE;
 1381                 else if ((softc->flags & ADA_FLAG_CAN_LOG)
 1382                       && (softc->zone_mode != ADA_ZONE_NONE))
 1383                         softc->state = ADA_STATE_LOGDIR;
 1384                 else
 1385                         break;
 1386                 if (cam_periph_acquire(periph) != 0)
 1387                         softc->state = ADA_STATE_NORMAL;
 1388                 else
 1389                         xpt_schedule(periph, CAM_PRIORITY_DEV);
 1390                 break;
 1391         }
 1392         default:
 1393                 break;
 1394         }
 1395         cam_periph_async(periph, code, path, arg);
 1396 }
 1397 
 1398 static int
 1399 adazonemodesysctl(SYSCTL_HANDLER_ARGS)
 1400 {
 1401         char tmpbuf[40];
 1402         struct ada_softc *softc;
 1403         int error;
 1404 
 1405         softc = (struct ada_softc *)arg1;
 1406 
 1407         switch (softc->zone_mode) {
 1408         case ADA_ZONE_DRIVE_MANAGED:
 1409                 snprintf(tmpbuf, sizeof(tmpbuf), "Drive Managed");
 1410                 break;
 1411         case ADA_ZONE_HOST_AWARE:
 1412                 snprintf(tmpbuf, sizeof(tmpbuf), "Host Aware");
 1413                 break;
 1414         case ADA_ZONE_HOST_MANAGED:
 1415                 snprintf(tmpbuf, sizeof(tmpbuf), "Host Managed");
 1416                 break;
 1417         case ADA_ZONE_NONE:
 1418         default:
 1419                 snprintf(tmpbuf, sizeof(tmpbuf), "Not Zoned");
 1420                 break;
 1421         }
 1422 
 1423         error = sysctl_handle_string(oidp, tmpbuf, sizeof(tmpbuf), req);
 1424 
 1425         return (error);
 1426 }
 1427 
 1428 static int
 1429 adazonesupsysctl(SYSCTL_HANDLER_ARGS)
 1430 {
 1431         char tmpbuf[180];
 1432         struct ada_softc *softc;
 1433         struct sbuf sb;
 1434         int error, first;
 1435         unsigned int i;
 1436 
 1437         softc = (struct ada_softc *)arg1;
 1438 
 1439         error = 0;
 1440         first = 1;
 1441         sbuf_new(&sb, tmpbuf, sizeof(tmpbuf), 0);
 1442 
 1443         for (i = 0; i < sizeof(ada_zone_desc_table) /
 1444              sizeof(ada_zone_desc_table[0]); i++) {
 1445                 if (softc->zone_flags & ada_zone_desc_table[i].value) {
 1446                         if (first == 0)
 1447                                 sbuf_printf(&sb, ", ");
 1448                         else
 1449                                 first = 0;
 1450                         sbuf_cat(&sb, ada_zone_desc_table[i].desc);
 1451                 }
 1452         }
 1453 
 1454         if (first == 1)
 1455                 sbuf_printf(&sb, "None");
 1456 
 1457         sbuf_finish(&sb);
 1458 
 1459         error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
 1460 
 1461         return (error);
 1462 }
 1463 
 1464 static void
 1465 adasysctlinit(void *context, int pending)
 1466 {
 1467         struct cam_periph *periph;
 1468         struct ada_softc *softc;
 1469         char tmpstr[32], tmpstr2[16];
 1470 
 1471         periph = (struct cam_periph *)context;
 1472 
 1473         /* periph was held for us when this task was enqueued */
 1474         if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
 1475                 cam_periph_release(periph);
 1476                 return;
 1477         }
 1478 
 1479         softc = (struct ada_softc *)periph->softc;
 1480         snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d",periph->unit_number);
 1481         snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
 1482 
 1483         sysctl_ctx_init(&softc->sysctl_ctx);
 1484         softc->flags |= ADA_FLAG_SCTX_INIT;
 1485         softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
 1486                 SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2,
 1487                 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, "device_index");
 1488         if (softc->sysctl_tree == NULL) {
 1489                 printf("adasysctlinit: unable to allocate sysctl tree\n");
 1490                 cam_periph_release(periph);
 1491                 return;
 1492         }
 1493 
 1494         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1495                 OID_AUTO, "delete_method",
 1496                 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
 1497                 softc, 0, adadeletemethodsysctl, "A",
 1498                 "BIO_DELETE execution method");
 1499         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1500                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1501                 "trim_count", CTLFLAG_RD, &softc->trim_count,
 1502                 "Total number of dsm commands sent");
 1503         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1504                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1505                 "trim_ranges", CTLFLAG_RD, &softc->trim_ranges,
 1506                 "Total number of ranges in dsm commands");
 1507         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1508                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1509                 "trim_lbas", CTLFLAG_RD, &softc->trim_lbas,
 1510                 "Total lbas in the dsm commands sent");
 1511         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1512                 OID_AUTO, "read_ahead", CTLFLAG_RW | CTLFLAG_MPSAFE,
 1513                 &softc->read_ahead, 0, "Enable disk read ahead.");
 1514         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1515                 OID_AUTO, "write_cache", CTLFLAG_RW | CTLFLAG_MPSAFE,
 1516                 &softc->write_cache, 0, "Enable disk write cache.");
 1517         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1518                 OID_AUTO, "zone_mode",
 1519                 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
 1520                 softc, 0, adazonemodesysctl, "A",
 1521                 "Zone Mode");
 1522         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1523                 OID_AUTO, "zone_support",
 1524                 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
 1525                 softc, 0, adazonesupsysctl, "A",
 1526                 "Zone Support");
 1527         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1528                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1529                 "optimal_seq_zones", CTLFLAG_RD, &softc->optimal_seq_zones,
 1530                 "Optimal Number of Open Sequential Write Preferred Zones");
 1531         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1532                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1533                 "optimal_nonseq_zones", CTLFLAG_RD,
 1534                 &softc->optimal_nonseq_zones,
 1535                 "Optimal Number of Non-Sequentially Written Sequential Write "
 1536                 "Preferred Zones");
 1537         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
 1538                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
 1539                 "max_seq_zones", CTLFLAG_RD, &softc->max_seq_zones,
 1540                 "Maximum Number of Open Sequential Write Required Zones");
 1541         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1542             OID_AUTO, "flags", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
 1543             softc, 0, adaflagssysctl, "A",
 1544             "Flags for drive");
 1545         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1546             OID_AUTO, "unmapped_io", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
 1547             &softc->flags, (u_int)ADA_FLAG_UNMAPPEDIO, adabitsysctl, "I",
 1548             "Unmapped I/O support *DEPRECATED* gone in FreeBSD 14");
 1549         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1550             OID_AUTO, "rotating", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
 1551             &softc->flags, (u_int)ADA_FLAG_ROTATING, adabitsysctl, "I",
 1552             "Rotating media *DEPRECATED* gone in FreeBSD 14");
 1553 
 1554 #ifdef CAM_TEST_FAILURE
 1555         /*
 1556          * Add a 'door bell' sysctl which allows one to set it from userland
 1557          * and cause something bad to happen.  For the moment, we only allow
 1558          * whacking the next read or write.
 1559          */
 1560         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1561                 OID_AUTO, "force_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
 1562                 &softc->force_read_error, 0,
 1563                 "Force a read error for the next N reads.");
 1564         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1565                 OID_AUTO, "force_write_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
 1566                 &softc->force_write_error, 0,
 1567                 "Force a write error for the next N writes.");
 1568         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1569                 OID_AUTO, "periodic_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
 1570                 &softc->periodic_read_error, 0,
 1571                 "Force a read error every N reads (don't set too low).");
 1572         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
 1573                 OID_AUTO, "invalidate", CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE,
 1574                 periph, 0, cam_periph_invalidate_sysctl, "I",
 1575                 "Write 1 to invalidate the drive immediately");
 1576 #endif
 1577 
 1578 #ifdef CAM_IO_STATS
 1579         softc->sysctl_stats_tree = SYSCTL_ADD_NODE(&softc->sysctl_stats_ctx,
 1580                 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "stats",
 1581                 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Statistics");
 1582         SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
 1583                 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
 1584                 OID_AUTO, "timeouts", CTLFLAG_RD | CTLFLAG_MPSAFE,
 1585                 &softc->timeouts, 0,
 1586                 "Device timeouts reported by the SIM");
 1587         SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
 1588                 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
 1589                 OID_AUTO, "errors", CTLFLAG_RD | CTLFLAG_MPSAFE,
 1590                 &softc->errors, 0,
 1591                 "Transport errors reported by the SIM.");
 1592         SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
 1593                 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
 1594                 OID_AUTO, "pack_invalidations", CTLFLAG_RD | CTLFLAG_MPSAFE,
 1595                 &softc->invalidations, 0,
 1596                 "Device pack invalidations.");
 1597 #endif
 1598 
 1599         cam_iosched_sysctl_init(softc->cam_iosched, &softc->sysctl_ctx,
 1600             softc->sysctl_tree);
 1601 
 1602         cam_periph_release(periph);
 1603 }
 1604 
 1605 static int
 1606 adagetattr(struct bio *bp)
 1607 {
 1608         int ret;
 1609         struct cam_periph *periph;
 1610 
 1611         if (g_handleattr_int(bp, "GEOM::canspeedup", ada_enable_biospeedup))
 1612                 return (EJUSTRETURN);
 1613 
 1614         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 1615         cam_periph_lock(periph);
 1616         ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
 1617             periph->path);
 1618         cam_periph_unlock(periph);
 1619         if (ret == 0)
 1620                 bp->bio_completed = bp->bio_length;
 1621         return ret;
 1622 }
 1623 
 1624 static int
 1625 adadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
 1626 {
 1627         char buf[16];
 1628         const char *p;
 1629         struct ada_softc *softc;
 1630         int i, error, value, methods;
 1631 
 1632         softc = (struct ada_softc *)arg1;
 1633 
 1634         value = softc->delete_method;
 1635         if (value < 0 || value > ADA_DELETE_MAX)
 1636                 p = "UNKNOWN";
 1637         else
 1638                 p = ada_delete_method_names[value];
 1639         strncpy(buf, p, sizeof(buf));
 1640         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
 1641         if (error != 0 || req->newptr == NULL)
 1642                 return (error);
 1643         methods = 1 << ADA_DELETE_DISABLE;
 1644         if ((softc->flags & ADA_FLAG_CAN_CFA) &&
 1645             !(softc->flags & ADA_FLAG_CAN_48BIT))
 1646                 methods |= 1 << ADA_DELETE_CFA_ERASE;
 1647         if (softc->flags & ADA_FLAG_CAN_TRIM)
 1648                 methods |= 1 << ADA_DELETE_DSM_TRIM;
 1649         if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
 1650                 methods |= 1 << ADA_DELETE_NCQ_DSM_TRIM;
 1651         for (i = 0; i <= ADA_DELETE_MAX; i++) {
 1652                 if (!(methods & (1 << i)) ||
 1653                     strcmp(buf, ada_delete_method_names[i]) != 0)
 1654                         continue;
 1655                 softc->delete_method = i;
 1656                 return (0);
 1657         }
 1658         return (EINVAL);
 1659 }
 1660 
 1661 static int
 1662 adabitsysctl(SYSCTL_HANDLER_ARGS)
 1663 {
 1664         u_int *flags = arg1;
 1665         u_int test = arg2;
 1666         int tmpout, error;
 1667 
 1668         tmpout = !!(*flags & test);
 1669         error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
 1670         if (error || !req->newptr)
 1671                 return (error);
 1672 
 1673         return (EPERM);
 1674 }
 1675 
 1676 static int
 1677 adaflagssysctl(SYSCTL_HANDLER_ARGS)
 1678 {
 1679         struct sbuf sbuf;
 1680         struct ada_softc *softc = arg1;
 1681         int error;
 1682 
 1683         sbuf_new_for_sysctl(&sbuf, NULL, 0, req);
 1684         if (softc->flags != 0)
 1685                 sbuf_printf(&sbuf, "0x%b", (unsigned)softc->flags, ADA_FLAG_STRING);
 1686         else
 1687                 sbuf_printf(&sbuf, "");
 1688         error = sbuf_finish(&sbuf);
 1689         sbuf_delete(&sbuf);
 1690 
 1691         return (error);
 1692 }
 1693 
 1694 static void
 1695 adasetflags(struct ada_softc *softc, struct ccb_getdev *cgd)
 1696 {
 1697         if ((cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
 1698             (cgd->inq_flags & SID_DMA))
 1699                 softc->flags |= ADA_FLAG_CAN_DMA;
 1700         else
 1701                 softc->flags &= ~ADA_FLAG_CAN_DMA;
 1702 
 1703         if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) {
 1704                 softc->flags |= ADA_FLAG_CAN_48BIT;
 1705                 if (cgd->inq_flags & SID_DMA48)
 1706                         softc->flags |= ADA_FLAG_CAN_DMA48;
 1707                 else
 1708                         softc->flags &= ~ADA_FLAG_CAN_DMA48;
 1709         } else
 1710                 softc->flags &= ~(ADA_FLAG_CAN_48BIT | ADA_FLAG_CAN_DMA48);
 1711 
 1712         if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
 1713                 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
 1714         else
 1715                 softc->flags &= ~ADA_FLAG_CAN_FLUSHCACHE;
 1716 
 1717         if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
 1718                 softc->flags |= ADA_FLAG_CAN_POWERMGT;
 1719         else
 1720                 softc->flags &= ~ADA_FLAG_CAN_POWERMGT;
 1721 
 1722         if ((cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
 1723             (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
 1724                 softc->flags |= ADA_FLAG_CAN_NCQ;
 1725         else
 1726                 softc->flags &= ~ADA_FLAG_CAN_NCQ;
 1727 
 1728         if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
 1729             (cgd->inq_flags & SID_DMA) &&
 1730             (softc->quirks & ADA_Q_NO_TRIM) == 0) {
 1731                 softc->flags |= ADA_FLAG_CAN_TRIM;
 1732                 softc->trim_max_ranges = TRIM_MAX_RANGES;
 1733                 if (cgd->ident_data.max_dsm_blocks != 0) {
 1734                         softc->trim_max_ranges =
 1735                             min(cgd->ident_data.max_dsm_blocks *
 1736                                 ATA_DSM_BLK_RANGES, softc->trim_max_ranges);
 1737                 }
 1738                 /*
 1739                  * If we can do RCVSND_FPDMA_QUEUED commands, we may be able
 1740                  * to do NCQ trims, if we support trims at all. We also need
 1741                  * support from the SIM to do things properly. Perhaps we
 1742                  * should look at log 13 dword 0 bit 0 and dword 1 bit 0 are
 1743                  * set too...
 1744                  */
 1745                 if ((softc->quirks & ADA_Q_NCQ_TRIM_BROKEN) == 0 &&
 1746                     (softc->flags & ADA_FLAG_PIM_ATA_EXT) != 0 &&
 1747                     (cgd->ident_data.satacapabilities2 &
 1748                      ATA_SUPPORT_RCVSND_FPDMA_QUEUED) != 0 &&
 1749                     (softc->flags & ADA_FLAG_CAN_TRIM) != 0)
 1750                         softc->flags |= ADA_FLAG_CAN_NCQ_TRIM;
 1751                 else
 1752                         softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
 1753         } else
 1754                 softc->flags &= ~(ADA_FLAG_CAN_TRIM | ADA_FLAG_CAN_NCQ_TRIM);
 1755 
 1756         if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
 1757                 softc->flags |= ADA_FLAG_CAN_CFA;
 1758         else
 1759                 softc->flags &= ~ADA_FLAG_CAN_CFA;
 1760 
 1761         /*
 1762          * Now that we've set the appropriate flags, setup the delete
 1763          * method.
 1764          */
 1765         adasetdeletemethod(softc);
 1766 
 1767         if ((cgd->ident_data.support.extension & ATA_SUPPORT_GENLOG)
 1768          && ((softc->quirks & ADA_Q_LOG_BROKEN) == 0))
 1769                 softc->flags |= ADA_FLAG_CAN_LOG;
 1770         else
 1771                 softc->flags &= ~ADA_FLAG_CAN_LOG;
 1772 
 1773         if ((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
 1774              ATA_SUPPORT_ZONE_HOST_AWARE)
 1775                 softc->zone_mode = ADA_ZONE_HOST_AWARE;
 1776         else if (((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
 1777                    ATA_SUPPORT_ZONE_DEV_MANAGED)
 1778               || (softc->quirks & ADA_Q_SMR_DM))
 1779                 softc->zone_mode = ADA_ZONE_DRIVE_MANAGED;
 1780         else
 1781                 softc->zone_mode = ADA_ZONE_NONE;
 1782 
 1783         if (cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD)
 1784                 softc->flags |= ADA_FLAG_CAN_RAHEAD;
 1785         else
 1786                 softc->flags &= ~ADA_FLAG_CAN_RAHEAD;
 1787 
 1788         if (cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE)
 1789                 softc->flags |= ADA_FLAG_CAN_WCACHE;
 1790         else
 1791                 softc->flags &= ~ADA_FLAG_CAN_WCACHE;
 1792 }
 1793 
 1794 static cam_status
 1795 adaregister(struct cam_periph *periph, void *arg)
 1796 {
 1797         struct ada_softc *softc;
 1798         struct ccb_getdev *cgd;
 1799         struct disk_params *dp;
 1800         struct sbuf sb;
 1801         char   *announce_buf;
 1802         caddr_t match;
 1803         int quirks;
 1804 
 1805         cgd = (struct ccb_getdev *)arg;
 1806         if (cgd == NULL) {
 1807                 printf("adaregister: no getdev CCB, can't register device\n");
 1808                 return(CAM_REQ_CMP_ERR);
 1809         }
 1810 
 1811         softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF,
 1812             M_NOWAIT|M_ZERO);
 1813 
 1814         if (softc == NULL) {
 1815                 printf("adaregister: Unable to probe new device. "
 1816                     "Unable to allocate softc\n");
 1817                 return(CAM_REQ_CMP_ERR);
 1818         }
 1819 
 1820         announce_buf = softc->announce_temp;
 1821         bzero(announce_buf, ADA_ANNOUNCETMP_SZ);
 1822 
 1823         if (cam_iosched_init(&softc->cam_iosched, periph) != 0) {
 1824                 printf("adaregister: Unable to probe new device. "
 1825                        "Unable to allocate iosched memory\n");
 1826                 free(softc, M_DEVBUF);
 1827                 return(CAM_REQ_CMP_ERR);
 1828         }
 1829 
 1830         periph->softc = softc;
 1831         xpt_path_inq(&softc->cpi, periph->path);
 1832 
 1833         /*
 1834          * See if this device has any quirks.
 1835          */
 1836         match = cam_quirkmatch((caddr_t)&cgd->ident_data,
 1837                                (caddr_t)ada_quirk_table,
 1838                                nitems(ada_quirk_table),
 1839                                sizeof(*ada_quirk_table), ata_identify_match);
 1840         if (match != NULL)
 1841                 softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
 1842         else
 1843                 softc->quirks = ADA_Q_NONE;
 1844 
 1845         TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
 1846 
 1847         /*
 1848          * Take a reference on the periph while adastart is called to finish
 1849          * the probe.  The reference will be dropped in adaprobedone at the
 1850          * end of probe.
 1851          */
 1852         (void)cam_periph_acquire(periph);
 1853         cam_periph_unlock(periph);
 1854         snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 1855             "kern.cam.ada.%d.quirks", periph->unit_number);
 1856         quirks = softc->quirks;
 1857         TUNABLE_INT_FETCH(announce_buf, &quirks);
 1858         softc->quirks = quirks;
 1859         softc->read_ahead = -1;
 1860         snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 1861             "kern.cam.ada.%d.read_ahead", periph->unit_number);
 1862         TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead);
 1863         softc->write_cache = -1;
 1864         snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 1865             "kern.cam.ada.%d.write_cache", periph->unit_number);
 1866         TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
 1867 
 1868         /*
 1869          * Let XPT know we can use UMA-allocated CCBs.
 1870          */
 1871         if (ada_enable_uma_ccbs) {
 1872                 KASSERT(ada_ccb_zone != NULL,
 1873                     ("%s: NULL ada_ccb_zone", __func__));
 1874                 periph->ccb_zone = ada_ccb_zone;
 1875         }
 1876 
 1877         /*
 1878          * Set support flags based on the Identify data and quirks.
 1879          */
 1880         adasetflags(softc, cgd);
 1881         if (softc->cpi.hba_misc & PIM_ATA_EXT)
 1882                 softc->flags |= ADA_FLAG_PIM_ATA_EXT;
 1883 
 1884         /* Disable queue sorting for non-rotational media by default. */
 1885         if (cgd->ident_data.media_rotation_rate == ATA_RATE_NON_ROTATING) {
 1886                 softc->flags &= ~ADA_FLAG_ROTATING;
 1887         } else {
 1888                 softc->flags |= ADA_FLAG_ROTATING;
 1889         }
 1890         cam_iosched_set_sort_queue(softc->cam_iosched,
 1891             (softc->flags & ADA_FLAG_ROTATING) ? -1 : 0);
 1892         softc->disk = disk_alloc();
 1893         adasetgeom(softc, cgd);
 1894         softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
 1895                           periph->unit_number, softc->params.secsize,
 1896                           DEVSTAT_ALL_SUPPORTED,
 1897                           DEVSTAT_TYPE_DIRECT |
 1898                           XPORT_DEVSTAT_TYPE(softc->cpi.transport),
 1899                           DEVSTAT_PRIORITY_DISK);
 1900         softc->disk->d_open = adaopen;
 1901         softc->disk->d_close = adaclose;
 1902         softc->disk->d_strategy = adastrategy;
 1903         softc->disk->d_getattr = adagetattr;
 1904         if (cam_sim_pollable(periph->sim))
 1905                 softc->disk->d_dump = adadump;
 1906         softc->disk->d_gone = adadiskgonecb;
 1907         softc->disk->d_name = "ada";
 1908         softc->disk->d_drv1 = periph;
 1909         softc->disk->d_unit = periph->unit_number;
 1910         cam_periph_lock(periph);
 1911 
 1912         dp = &softc->params;
 1913         snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
 1914             "%juMB (%ju %u byte sectors)",
 1915             ((uintmax_t)dp->secsize * dp->sectors) / (1024 * 1024),
 1916             (uintmax_t)dp->sectors, dp->secsize);
 1917 
 1918         sbuf_new(&sb, softc->announce_buffer, ADA_ANNOUNCE_SZ, SBUF_FIXEDLEN);
 1919         xpt_announce_periph_sbuf(periph, &sb, announce_buf);
 1920         xpt_announce_quirks_sbuf(periph, &sb, softc->quirks, ADA_Q_BIT_STRING);
 1921         sbuf_finish(&sb);
 1922         sbuf_putbuf(&sb);
 1923 
 1924         /*
 1925          * Create our sysctl variables, now that we know
 1926          * we have successfully attached.
 1927          */
 1928         if (cam_periph_acquire(periph) == 0)
 1929                 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
 1930 
 1931         /*
 1932          * Add async callbacks for bus reset and
 1933          * bus device reset calls.  I don't bother
 1934          * checking if this fails as, in most cases,
 1935          * the system will function just fine without
 1936          * them and the only alternative would be to
 1937          * not attach the device on failure.
 1938          */
 1939         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
 1940             AC_GETDEV_CHANGED | AC_ADVINFO_CHANGED,
 1941             adaasync, periph, periph->path);
 1942 
 1943         /*
 1944          * Schedule a periodic event to occasionally send an
 1945          * ordered tag to a device.
 1946          */
 1947         callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0);
 1948         callout_reset_sbt(&softc->sendordered_c,
 1949             SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
 1950             adasendorderedtag, softc, C_PREL(1));
 1951 
 1952         /* Released after probe when disk_create() call pass it to GEOM. */
 1953         cam_periph_hold_boot(periph);
 1954 
 1955         if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD) {
 1956                 softc->state = ADA_STATE_RAHEAD;
 1957         } else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE) {
 1958                 softc->state = ADA_STATE_WCACHE;
 1959         } else if ((softc->flags & ADA_FLAG_CAN_LOG)
 1960                 && (softc->zone_mode != ADA_ZONE_NONE)) {
 1961                 softc->state = ADA_STATE_LOGDIR;
 1962         } else {
 1963                 /*
 1964                  * Nothing to probe, so we can just transition to the
 1965                  * normal state.
 1966                  */
 1967                 adaprobedone(periph, NULL);
 1968                 return(CAM_REQ_CMP);
 1969         }
 1970 
 1971         xpt_schedule(periph, CAM_PRIORITY_DEV);
 1972         return(CAM_REQ_CMP);
 1973 }
 1974 
 1975 static int
 1976 ada_dsmtrim_req_create(struct ada_softc *softc, struct bio *bp, struct trim_request *req)
 1977 {
 1978         uint64_t lastlba = (uint64_t)-1, lbas = 0;
 1979         int c, lastcount = 0, off, ranges = 0;
 1980 
 1981         bzero(req, sizeof(*req));
 1982         TAILQ_INIT(&req->bps);
 1983         do {
 1984                 uint64_t lba = bp->bio_pblkno;
 1985                 int count = bp->bio_bcount / softc->params.secsize;
 1986 
 1987                 /* Try to extend the previous range. */
 1988                 if (lba == lastlba) {
 1989                         c = min(count, ATA_DSM_RANGE_MAX - lastcount);
 1990                         lastcount += c;
 1991                         off = (ranges - 1) * ATA_DSM_RANGE_SIZE;
 1992                         req->data[off + 6] = lastcount & 0xff;
 1993                         req->data[off + 7] =
 1994                                 (lastcount >> 8) & 0xff;
 1995                         count -= c;
 1996                         lba += c;
 1997                         lbas += c;
 1998                 }
 1999 
 2000                 while (count > 0) {
 2001                         c = min(count, ATA_DSM_RANGE_MAX);
 2002                         off = ranges * ATA_DSM_RANGE_SIZE;
 2003                         req->data[off + 0] = lba & 0xff;
 2004                         req->data[off + 1] = (lba >> 8) & 0xff;
 2005                         req->data[off + 2] = (lba >> 16) & 0xff;
 2006                         req->data[off + 3] = (lba >> 24) & 0xff;
 2007                         req->data[off + 4] = (lba >> 32) & 0xff;
 2008                         req->data[off + 5] = (lba >> 40) & 0xff;
 2009                         req->data[off + 6] = c & 0xff;
 2010                         req->data[off + 7] = (c >> 8) & 0xff;
 2011                         lba += c;
 2012                         lbas += c;
 2013                         count -= c;
 2014                         lastcount = c;
 2015                         ranges++;
 2016                         /*
 2017                          * Its the caller's responsibility to ensure the
 2018                          * request will fit so we don't need to check for
 2019                          * overrun here
 2020                          */
 2021                 }
 2022                 lastlba = lba;
 2023                 TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
 2024 
 2025                 bp = cam_iosched_next_trim(softc->cam_iosched);
 2026                 if (bp == NULL)
 2027                         break;
 2028                 if (bp->bio_bcount / softc->params.secsize >
 2029                     (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX) {
 2030                         cam_iosched_put_back_trim(softc->cam_iosched, bp);
 2031                         break;
 2032                 }
 2033         } while (1);
 2034         softc->trim_count++;
 2035         softc->trim_ranges += ranges;
 2036         softc->trim_lbas += lbas;
 2037 
 2038         return (ranges);
 2039 }
 2040 
 2041 static void
 2042 ada_dsmtrim(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
 2043 {
 2044         struct trim_request *req = &softc->trim_req;
 2045         int ranges;
 2046 
 2047         ranges = ada_dsmtrim_req_create(softc, bp, req);
 2048         cam_fill_ataio(ataio,
 2049             ada_retry_count,
 2050             adadone,
 2051             CAM_DIR_OUT,
 2052             0,
 2053             req->data,
 2054             howmany(ranges, ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
 2055             ada_default_timeout * 1000);
 2056         ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
 2057             ATA_DSM_TRIM, 0, howmany(ranges, ATA_DSM_BLK_RANGES));
 2058 }
 2059 
 2060 static void
 2061 ada_ncq_dsmtrim(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
 2062 {
 2063         struct trim_request *req = &softc->trim_req;
 2064         int ranges;
 2065 
 2066         ranges = ada_dsmtrim_req_create(softc, bp, req);
 2067         cam_fill_ataio(ataio,
 2068             ada_retry_count,
 2069             adadone,
 2070             CAM_DIR_OUT,
 2071             0,
 2072             req->data,
 2073             howmany(ranges, ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
 2074             ada_default_timeout * 1000);
 2075         ata_ncq_cmd(ataio,
 2076             ATA_SEND_FPDMA_QUEUED,
 2077             0,
 2078             howmany(ranges, ATA_DSM_BLK_RANGES));
 2079         ataio->cmd.sector_count_exp = ATA_SFPDMA_DSM;
 2080         ataio->ata_flags |= ATA_FLAG_AUX;
 2081         ataio->aux = 1;
 2082 }
 2083 
 2084 static void
 2085 ada_cfaerase(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
 2086 {
 2087         struct trim_request *req = &softc->trim_req;
 2088         uint64_t lba = bp->bio_pblkno;
 2089         uint16_t count = bp->bio_bcount / softc->params.secsize;
 2090 
 2091         bzero(req, sizeof(*req));
 2092         TAILQ_INIT(&req->bps);
 2093         TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
 2094 
 2095         cam_fill_ataio(ataio,
 2096             ada_retry_count,
 2097             adadone,
 2098             CAM_DIR_NONE,
 2099             0,
 2100             NULL,
 2101             0,
 2102             ada_default_timeout*1000);
 2103 
 2104         if (count >= 256)
 2105                 count = 0;
 2106         ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
 2107 }
 2108 
 2109 static int
 2110 ada_zone_bio_to_ata(int disk_zone_cmd)
 2111 {
 2112         switch (disk_zone_cmd) {
 2113         case DISK_ZONE_OPEN:
 2114                 return ATA_ZM_OPEN_ZONE;
 2115         case DISK_ZONE_CLOSE:
 2116                 return ATA_ZM_CLOSE_ZONE;
 2117         case DISK_ZONE_FINISH:
 2118                 return ATA_ZM_FINISH_ZONE;
 2119         case DISK_ZONE_RWP:
 2120                 return ATA_ZM_RWP;
 2121         }
 2122 
 2123         return -1;
 2124 }
 2125 
 2126 static int
 2127 ada_zone_cmd(struct cam_periph *periph, union ccb *ccb, struct bio *bp,
 2128              int *queue_ccb)
 2129 {
 2130         struct ada_softc *softc;
 2131         int error;
 2132 
 2133         error = 0;
 2134 
 2135         if (bp->bio_cmd != BIO_ZONE) {
 2136                 error = EINVAL;
 2137                 goto bailout;
 2138         }
 2139 
 2140         softc = periph->softc;
 2141 
 2142         switch (bp->bio_zone.zone_cmd) {
 2143         case DISK_ZONE_OPEN:
 2144         case DISK_ZONE_CLOSE:
 2145         case DISK_ZONE_FINISH:
 2146         case DISK_ZONE_RWP: {
 2147                 int zone_flags;
 2148                 int zone_sa;
 2149                 uint64_t lba;
 2150 
 2151                 zone_sa = ada_zone_bio_to_ata(bp->bio_zone.zone_cmd);
 2152                 if (zone_sa == -1) {
 2153                         xpt_print(periph->path, "Cannot translate zone "
 2154                             "cmd %#x to ATA\n", bp->bio_zone.zone_cmd);
 2155                         error = EINVAL;
 2156                         goto bailout;
 2157                 }
 2158 
 2159                 zone_flags = 0;
 2160                 lba = bp->bio_zone.zone_params.rwp.id;
 2161 
 2162                 if (bp->bio_zone.zone_params.rwp.flags &
 2163                     DISK_ZONE_RWP_FLAG_ALL)
 2164                         zone_flags |= ZBC_OUT_ALL;
 2165 
 2166                 ata_zac_mgmt_out(&ccb->ataio,
 2167                                  /*retries*/ ada_retry_count,
 2168                                  /*cbfcnp*/ adadone,
 2169                                  /*use_ncq*/ (softc->flags &
 2170                                               ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
 2171                                  /*zm_action*/ zone_sa,
 2172                                  /*zone_id*/ lba,
 2173                                  /*zone_flags*/ zone_flags,
 2174                                  /*sector_count*/ 0,
 2175                                  /*data_ptr*/ NULL,
 2176                                  /*dxfer_len*/ 0,
 2177                                  /*timeout*/ ada_default_timeout * 1000);
 2178                 *queue_ccb = 1;
 2179 
 2180                 break;
 2181         }
 2182         case DISK_ZONE_REPORT_ZONES: {
 2183                 uint8_t *rz_ptr;
 2184                 uint32_t num_entries, alloc_size;
 2185                 struct disk_zone_report *rep;
 2186 
 2187                 rep = &bp->bio_zone.zone_params.report;
 2188 
 2189                 num_entries = rep->entries_allocated;
 2190                 if (num_entries == 0) {
 2191                         xpt_print(periph->path, "No entries allocated for "
 2192                             "Report Zones request\n");
 2193                         error = EINVAL;
 2194                         goto bailout;
 2195                 }
 2196                 alloc_size = sizeof(struct scsi_report_zones_hdr) +
 2197                     (sizeof(struct scsi_report_zones_desc) * num_entries);
 2198                 alloc_size = min(alloc_size, softc->disk->d_maxsize);
 2199                 rz_ptr = malloc(alloc_size, M_ATADA, M_NOWAIT | M_ZERO);
 2200                 if (rz_ptr == NULL) {
 2201                         xpt_print(periph->path, "Unable to allocate memory "
 2202                            "for Report Zones request\n");
 2203                         error = ENOMEM;
 2204                         goto bailout;
 2205                 }
 2206 
 2207                 ata_zac_mgmt_in(&ccb->ataio,
 2208                                 /*retries*/ ada_retry_count,
 2209                                 /*cbcfnp*/ adadone,
 2210                                 /*use_ncq*/ (softc->flags &
 2211                                              ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
 2212                                 /*zm_action*/ ATA_ZM_REPORT_ZONES,
 2213                                 /*zone_id*/ rep->starting_id,
 2214                                 /*zone_flags*/ rep->rep_options,
 2215                                 /*data_ptr*/ rz_ptr,
 2216                                 /*dxfer_len*/ alloc_size,
 2217                                 /*timeout*/ ada_default_timeout * 1000);
 2218 
 2219                 /*
 2220                  * For BIO_ZONE, this isn't normally needed.  However, it
 2221                  * is used by devstat_end_transaction_bio() to determine
 2222                  * how much data was transferred.
 2223                  */
 2224                 /*
 2225                  * XXX KDM we have a problem.  But I'm not sure how to fix
 2226                  * it.  devstat uses bio_bcount - bio_resid to calculate
 2227                  * the amount of data transferred.   The GEOM disk code
 2228                  * uses bio_length - bio_resid to calculate the amount of
 2229                  * data in bio_completed.  We have different structure
 2230                  * sizes above and below the ada(4) driver.  So, if we
 2231                  * use the sizes above, the amount transferred won't be
 2232                  * quite accurate for devstat.  If we use different sizes
 2233                  * for bio_bcount and bio_length (above and below
 2234                  * respectively), then the residual needs to match one or
 2235                  * the other.  Everything is calculated after the bio
 2236                  * leaves the driver, so changing the values around isn't
 2237                  * really an option.  For now, just set the count to the
 2238                  * passed in length.  This means that the calculations
 2239                  * above (e.g. bio_completed) will be correct, but the
 2240                  * amount of data reported to devstat will be slightly
 2241                  * under or overstated.
 2242                  */
 2243                 bp->bio_bcount = bp->bio_length;
 2244 
 2245                 *queue_ccb = 1;
 2246 
 2247                 break;
 2248         }
 2249         case DISK_ZONE_GET_PARAMS: {
 2250                 struct disk_zone_disk_params *params;
 2251 
 2252                 params = &bp->bio_zone.zone_params.disk_params;
 2253                 bzero(params, sizeof(*params));
 2254 
 2255                 switch (softc->zone_mode) {
 2256                 case ADA_ZONE_DRIVE_MANAGED:
 2257                         params->zone_mode = DISK_ZONE_MODE_DRIVE_MANAGED;
 2258                         break;
 2259                 case ADA_ZONE_HOST_AWARE:
 2260                         params->zone_mode = DISK_ZONE_MODE_HOST_AWARE;
 2261                         break;
 2262                 case ADA_ZONE_HOST_MANAGED:
 2263                         params->zone_mode = DISK_ZONE_MODE_HOST_MANAGED;
 2264                         break;
 2265                 default:
 2266                 case ADA_ZONE_NONE:
 2267                         params->zone_mode = DISK_ZONE_MODE_NONE;
 2268                         break;
 2269                 }
 2270 
 2271                 if (softc->zone_flags & ADA_ZONE_FLAG_URSWRZ)
 2272                         params->flags |= DISK_ZONE_DISK_URSWRZ;
 2273 
 2274                 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_SEQ_SET) {
 2275                         params->optimal_seq_zones = softc->optimal_seq_zones;
 2276                         params->flags |= DISK_ZONE_OPT_SEQ_SET;
 2277                 }
 2278 
 2279                 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_NONSEQ_SET) {
 2280                         params->optimal_nonseq_zones =
 2281                             softc->optimal_nonseq_zones;
 2282                         params->flags |= DISK_ZONE_OPT_NONSEQ_SET;
 2283                 }
 2284 
 2285                 if (softc->zone_flags & ADA_ZONE_FLAG_MAX_SEQ_SET) {
 2286                         params->max_seq_zones = softc->max_seq_zones;
 2287                         params->flags |= DISK_ZONE_MAX_SEQ_SET;
 2288                 }
 2289                 if (softc->zone_flags & ADA_ZONE_FLAG_RZ_SUP)
 2290                         params->flags |= DISK_ZONE_RZ_SUP;
 2291 
 2292                 if (softc->zone_flags & ADA_ZONE_FLAG_OPEN_SUP)
 2293                         params->flags |= DISK_ZONE_OPEN_SUP;
 2294 
 2295                 if (softc->zone_flags & ADA_ZONE_FLAG_CLOSE_SUP)
 2296                         params->flags |= DISK_ZONE_CLOSE_SUP;
 2297 
 2298                 if (softc->zone_flags & ADA_ZONE_FLAG_FINISH_SUP)
 2299                         params->flags |= DISK_ZONE_FINISH_SUP;
 2300 
 2301                 if (softc->zone_flags & ADA_ZONE_FLAG_RWP_SUP)
 2302                         params->flags |= DISK_ZONE_RWP_SUP;
 2303                 break;
 2304         }
 2305         default:
 2306                 break;
 2307         }
 2308 bailout:
 2309         return (error);
 2310 }
 2311 
 2312 static void
 2313 adastart(struct cam_periph *periph, union ccb *start_ccb)
 2314 {
 2315         struct ada_softc *softc = (struct ada_softc *)periph->softc;
 2316         struct ccb_ataio *ataio = &start_ccb->ataio;
 2317 
 2318         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
 2319 
 2320         switch (softc->state) {
 2321         case ADA_STATE_NORMAL:
 2322         {
 2323                 struct bio *bp;
 2324                 u_int8_t tag_code;
 2325 
 2326                 bp = cam_iosched_next_bio(softc->cam_iosched);
 2327                 if (bp == NULL) {
 2328                         xpt_release_ccb(start_ccb);
 2329                         break;
 2330                 }
 2331 
 2332                 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
 2333                     (bp->bio_cmd != BIO_DELETE && (softc->flags & ADA_FLAG_NEED_OTAG) != 0)) {
 2334                         softc->flags &= ~ADA_FLAG_NEED_OTAG;
 2335                         softc->flags |= ADA_FLAG_WAS_OTAG;
 2336                         tag_code = 0;
 2337                 } else {
 2338                         tag_code = 1;
 2339                 }
 2340                 switch (bp->bio_cmd) {
 2341                 case BIO_WRITE:
 2342                 case BIO_READ:
 2343                 {
 2344                         uint64_t lba = bp->bio_pblkno;
 2345                         uint16_t count = bp->bio_bcount / softc->params.secsize;
 2346                         void *data_ptr;
 2347                         int rw_op;
 2348 
 2349                         if (bp->bio_cmd == BIO_WRITE) {
 2350                                 softc->flags |= ADA_FLAG_DIRTY;
 2351                                 rw_op = CAM_DIR_OUT;
 2352                         } else {
 2353                                 rw_op = CAM_DIR_IN;
 2354                         }
 2355 
 2356                         data_ptr = bp->bio_data;
 2357                         if ((bp->bio_flags & (BIO_UNMAPPED|BIO_VLIST)) != 0) {
 2358                                 rw_op |= CAM_DATA_BIO;
 2359                                 data_ptr = bp;
 2360                         }
 2361 
 2362 #ifdef CAM_TEST_FAILURE
 2363                         int fail = 0;
 2364 
 2365                         /*
 2366                          * Support the failure ioctls.  If the command is a
 2367                          * read, and there are pending forced read errors, or
 2368                          * if a write and pending write errors, then fail this
 2369                          * operation with EIO.  This is useful for testing
 2370                          * purposes.  Also, support having every Nth read fail.
 2371                          *
 2372                          * This is a rather blunt tool.
 2373                          */
 2374                         if (bp->bio_cmd == BIO_READ) {
 2375                                 if (softc->force_read_error) {
 2376                                         softc->force_read_error--;
 2377                                         fail = 1;
 2378                                 }
 2379                                 if (softc->periodic_read_error > 0) {
 2380                                         if (++softc->periodic_read_count >=
 2381                                             softc->periodic_read_error) {
 2382                                                 softc->periodic_read_count = 0;
 2383                                                 fail = 1;
 2384                                         }
 2385                                 }
 2386                         } else {
 2387                                 if (softc->force_write_error) {
 2388                                         softc->force_write_error--;
 2389                                         fail = 1;
 2390                                 }
 2391                         }
 2392                         if (fail) {
 2393                                 biofinish(bp, NULL, EIO);
 2394                                 xpt_release_ccb(start_ccb);
 2395                                 adaschedule(periph);
 2396                                 return;
 2397                         }
 2398 #endif
 2399                         KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
 2400                             round_page(bp->bio_bcount + bp->bio_ma_offset) /
 2401                             PAGE_SIZE == bp->bio_ma_n,
 2402                             ("Short bio %p", bp));
 2403                         cam_fill_ataio(ataio,
 2404                             ada_retry_count,
 2405                             adadone,
 2406                             rw_op,
 2407                             0,
 2408                             data_ptr,
 2409                             bp->bio_bcount,
 2410                             ada_default_timeout*1000);
 2411 
 2412                         if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
 2413                                 if (bp->bio_cmd == BIO_READ) {
 2414                                         ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
 2415                                             lba, count);
 2416                                 } else {
 2417                                         ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
 2418                                             lba, count);
 2419                                 }
 2420                         } else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
 2421                             (lba + count >= ATA_MAX_28BIT_LBA ||
 2422                             count > 256)) {
 2423                                 if (softc->flags & ADA_FLAG_CAN_DMA48) {
 2424                                         if (bp->bio_cmd == BIO_READ) {
 2425                                                 ata_48bit_cmd(ataio, ATA_READ_DMA48,
 2426                                                     0, lba, count);
 2427                                         } else {
 2428                                                 ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
 2429                                                     0, lba, count);
 2430                                         }
 2431                                 } else {
 2432                                         if (bp->bio_cmd == BIO_READ) {
 2433                                                 ata_48bit_cmd(ataio, ATA_READ_MUL48,
 2434                                                     0, lba, count);
 2435                                         } else {
 2436                                                 ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
 2437                                                     0, lba, count);
 2438                                         }
 2439                                 }
 2440                         } else {
 2441                                 if (count == 256)
 2442                                         count = 0;
 2443                                 if (softc->flags & ADA_FLAG_CAN_DMA) {
 2444                                         if (bp->bio_cmd == BIO_READ) {
 2445                                                 ata_28bit_cmd(ataio, ATA_READ_DMA,
 2446                                                     0, lba, count);
 2447                                         } else {
 2448                                                 ata_28bit_cmd(ataio, ATA_WRITE_DMA,
 2449                                                     0, lba, count);
 2450                                         }
 2451                                 } else {
 2452                                         if (bp->bio_cmd == BIO_READ) {
 2453                                                 ata_28bit_cmd(ataio, ATA_READ_MUL,
 2454                                                     0, lba, count);
 2455                                         } else {
 2456                                                 ata_28bit_cmd(ataio, ATA_WRITE_MUL,
 2457                                                     0, lba, count);
 2458                                         }
 2459                                 }
 2460                         }
 2461                         break;
 2462                 }
 2463                 case BIO_DELETE:
 2464                         switch (softc->delete_method) {
 2465                         case ADA_DELETE_NCQ_DSM_TRIM:
 2466                                 ada_ncq_dsmtrim(softc, bp, ataio);
 2467                                 break;
 2468                         case ADA_DELETE_DSM_TRIM:
 2469                                 ada_dsmtrim(softc, bp, ataio);
 2470                                 break;
 2471                         case ADA_DELETE_CFA_ERASE:
 2472                                 ada_cfaerase(softc, bp, ataio);
 2473                                 break;
 2474                         default:
 2475                                 biofinish(bp, NULL, EOPNOTSUPP);
 2476                                 xpt_release_ccb(start_ccb);
 2477                                 adaschedule(periph);
 2478                                 return;
 2479                         }
 2480                         start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
 2481                         start_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2482                         cam_iosched_submit_trim(softc->cam_iosched);
 2483                         goto out;
 2484                 case BIO_FLUSH:
 2485                         cam_fill_ataio(ataio,
 2486                             1,
 2487                             adadone,
 2488                             CAM_DIR_NONE,
 2489                             0,
 2490                             NULL,
 2491                             0,
 2492                             ada_default_timeout*1000);
 2493 
 2494                         if (softc->flags & ADA_FLAG_CAN_48BIT)
 2495                                 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
 2496                         else
 2497                                 ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
 2498                         break;
 2499                 case BIO_ZONE: {
 2500                         int error, queue_ccb;
 2501 
 2502                         queue_ccb = 0;
 2503 
 2504                         error = ada_zone_cmd(periph, start_ccb, bp, &queue_ccb);
 2505                         if ((error != 0)
 2506                          || (queue_ccb == 0)) {
 2507                                 biofinish(bp, NULL, error);
 2508                                 xpt_release_ccb(start_ccb);
 2509                                 return;
 2510                         }
 2511                         break;
 2512                 }
 2513                 default:
 2514                         biofinish(bp, NULL, EOPNOTSUPP);
 2515                         xpt_release_ccb(start_ccb);
 2516                         return;
 2517                 }
 2518                 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
 2519                 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2520 out:
 2521                 start_ccb->ccb_h.ccb_bp = bp;
 2522                 softc->outstanding_cmds++;
 2523                 softc->refcount++;
 2524                 cam_periph_unlock(periph);
 2525                 xpt_action(start_ccb);
 2526                 cam_periph_lock(periph);
 2527 
 2528                 /* May have more work to do, so ensure we stay scheduled */
 2529                 adaschedule(periph);
 2530                 break;
 2531         }
 2532         case ADA_STATE_RAHEAD:
 2533         case ADA_STATE_WCACHE:
 2534         {
 2535                 cam_fill_ataio(ataio,
 2536                     1,
 2537                     adadone,
 2538                     CAM_DIR_NONE,
 2539                     0,
 2540                     NULL,
 2541                     0,
 2542                     ada_default_timeout*1000);
 2543 
 2544                 if (softc->state == ADA_STATE_RAHEAD) {
 2545                         ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_RA ?
 2546                             ATA_SF_ENAB_RCACHE : ATA_SF_DIS_RCACHE, 0, 0);
 2547                         start_ccb->ccb_h.ccb_state = ADA_CCB_RAHEAD;
 2548                 } else {
 2549                         ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_WC ?
 2550                             ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0);
 2551                         start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE;
 2552                 }
 2553                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 2554                 xpt_action(start_ccb);
 2555                 break;
 2556         }
 2557         case ADA_STATE_LOGDIR:
 2558         {
 2559                 struct ata_gp_log_dir *log_dir;
 2560 
 2561                 if ((softc->flags & ADA_FLAG_CAN_LOG) == 0) {
 2562                         adaprobedone(periph, start_ccb);
 2563                         break;
 2564                 }
 2565 
 2566                 log_dir = malloc(sizeof(*log_dir), M_ATADA, M_NOWAIT|M_ZERO);
 2567                 if (log_dir == NULL) {
 2568                         xpt_print(periph->path, "Couldn't malloc log_dir "
 2569                             "data\n");
 2570                         softc->state = ADA_STATE_NORMAL;
 2571                         xpt_release_ccb(start_ccb);
 2572                         break;
 2573                 }
 2574 
 2575                 ata_read_log(ataio,
 2576                     /*retries*/1,
 2577                     /*cbfcnp*/adadone,
 2578                     /*log_address*/ ATA_LOG_DIRECTORY,
 2579                     /*page_number*/ 0,
 2580                     /*block_count*/ 1,
 2581                     /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
 2582                                  CAM_ATAIO_DMA : 0,
 2583                     /*data_ptr*/ (uint8_t *)log_dir,
 2584                     /*dxfer_len*/sizeof(*log_dir),
 2585                     /*timeout*/ada_default_timeout*1000);
 2586 
 2587                 start_ccb->ccb_h.ccb_state = ADA_CCB_LOGDIR;
 2588                 xpt_action(start_ccb);
 2589                 break;
 2590         }
 2591         case ADA_STATE_IDDIR:
 2592         {
 2593                 struct ata_identify_log_pages *id_dir;
 2594 
 2595                 id_dir = malloc(sizeof(*id_dir), M_ATADA, M_NOWAIT | M_ZERO);
 2596                 if (id_dir == NULL) {
 2597                         xpt_print(periph->path, "Couldn't malloc id_dir "
 2598                             "data\n");
 2599                         adaprobedone(periph, start_ccb);
 2600                         break;
 2601                 }
 2602 
 2603                 ata_read_log(ataio,
 2604                     /*retries*/1,
 2605                     /*cbfcnp*/adadone,
 2606                     /*log_address*/ ATA_IDENTIFY_DATA_LOG,
 2607                     /*page_number*/ ATA_IDL_PAGE_LIST,
 2608                     /*block_count*/ 1,
 2609                     /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
 2610                                  CAM_ATAIO_DMA : 0,
 2611                     /*data_ptr*/ (uint8_t *)id_dir,
 2612                     /*dxfer_len*/ sizeof(*id_dir),
 2613                     /*timeout*/ada_default_timeout*1000);
 2614 
 2615                 start_ccb->ccb_h.ccb_state = ADA_CCB_IDDIR;
 2616                 xpt_action(start_ccb);
 2617                 break;
 2618         }
 2619         case ADA_STATE_SUP_CAP:
 2620         {
 2621                 struct ata_identify_log_sup_cap *sup_cap;
 2622 
 2623                 sup_cap = malloc(sizeof(*sup_cap), M_ATADA, M_NOWAIT|M_ZERO);
 2624                 if (sup_cap == NULL) {
 2625                         xpt_print(periph->path, "Couldn't malloc sup_cap "
 2626                             "data\n");
 2627                         adaprobedone(periph, start_ccb);
 2628                         break;
 2629                 }
 2630 
 2631                 ata_read_log(ataio,
 2632                     /*retries*/1,
 2633                     /*cbfcnp*/adadone,
 2634                     /*log_address*/ ATA_IDENTIFY_DATA_LOG,
 2635                     /*page_number*/ ATA_IDL_SUP_CAP,
 2636                     /*block_count*/ 1,
 2637                     /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
 2638                                  CAM_ATAIO_DMA : 0,
 2639                     /*data_ptr*/ (uint8_t *)sup_cap,
 2640                     /*dxfer_len*/ sizeof(*sup_cap),
 2641                     /*timeout*/ada_default_timeout*1000);
 2642 
 2643                 start_ccb->ccb_h.ccb_state = ADA_CCB_SUP_CAP;
 2644                 xpt_action(start_ccb);
 2645                 break;
 2646         }
 2647         case ADA_STATE_ZONE:
 2648         {
 2649                 struct ata_zoned_info_log *ata_zone;
 2650 
 2651                 ata_zone = malloc(sizeof(*ata_zone), M_ATADA, M_NOWAIT|M_ZERO);
 2652                 if (ata_zone == NULL) {
 2653                         xpt_print(periph->path, "Couldn't malloc ata_zone "
 2654                             "data\n");
 2655                         adaprobedone(periph, start_ccb);
 2656                         break;
 2657                 }
 2658 
 2659                 ata_read_log(ataio,
 2660                     /*retries*/1,
 2661                     /*cbfcnp*/adadone,
 2662                     /*log_address*/ ATA_IDENTIFY_DATA_LOG,
 2663                     /*page_number*/ ATA_IDL_ZDI,
 2664                     /*block_count*/ 1,
 2665                     /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
 2666                                  CAM_ATAIO_DMA : 0,
 2667                     /*data_ptr*/ (uint8_t *)ata_zone,
 2668                     /*dxfer_len*/ sizeof(*ata_zone),
 2669                     /*timeout*/ada_default_timeout*1000);
 2670 
 2671                 start_ccb->ccb_h.ccb_state = ADA_CCB_ZONE;
 2672                 xpt_action(start_ccb);
 2673                 break;
 2674         }
 2675         }
 2676 }
 2677 
 2678 static void
 2679 adaprobedone(struct cam_periph *periph, union ccb *ccb)
 2680 {
 2681         struct ada_softc *softc;
 2682 
 2683         softc = (struct ada_softc *)periph->softc;
 2684 
 2685         /*
 2686          * Since our peripheral may be invalidated by an error we must release
 2687          * our CCB before releasing the reference on the peripheral.  The
 2688          * peripheral will only go away once the last reference is removed, and
 2689          * we need it around for the CCB release operation.
 2690          */
 2691         if (ccb != NULL)
 2692                 xpt_release_ccb(ccb);
 2693 
 2694         softc->state = ADA_STATE_NORMAL;
 2695         softc->flags |= ADA_FLAG_PROBED;
 2696         adaschedule(periph);
 2697         if ((softc->flags & ADA_FLAG_ANNOUNCED) == 0) {
 2698                 softc->flags |= ADA_FLAG_ANNOUNCED;
 2699 
 2700                 /*
 2701                  * We'll release this reference once GEOM calls us back via
 2702                  * adadiskgonecb(), telling us that our provider has been freed.
 2703                  */
 2704                 if (cam_periph_acquire(periph) == 0)
 2705                         disk_create(softc->disk, DISK_VERSION);
 2706 
 2707                 cam_periph_release_boot(periph);
 2708         }
 2709         cam_periph_release_locked(periph);
 2710 }
 2711 
 2712 static void
 2713 adazonedone(struct cam_periph *periph, union ccb *ccb)
 2714 {
 2715         struct bio *bp;
 2716 
 2717         bp = (struct bio *)ccb->ccb_h.ccb_bp;
 2718 
 2719         switch (bp->bio_zone.zone_cmd) {
 2720         case DISK_ZONE_OPEN:
 2721         case DISK_ZONE_CLOSE:
 2722         case DISK_ZONE_FINISH:
 2723         case DISK_ZONE_RWP:
 2724                 break;
 2725         case DISK_ZONE_REPORT_ZONES: {
 2726                 uint32_t avail_len;
 2727                 struct disk_zone_report *rep;
 2728                 struct scsi_report_zones_hdr *hdr;
 2729                 struct scsi_report_zones_desc *desc;
 2730                 struct disk_zone_rep_entry *entry;
 2731                 uint32_t hdr_len, num_avail;
 2732                 uint32_t num_to_fill, i;
 2733 
 2734                 rep = &bp->bio_zone.zone_params.report;
 2735                 avail_len = ccb->ataio.dxfer_len - ccb->ataio.resid;
 2736                 /*
 2737                  * Note that bio_resid isn't normally used for zone
 2738                  * commands, but it is used by devstat_end_transaction_bio()
 2739                  * to determine how much data was transferred.  Because
 2740                  * the size of the SCSI/ATA data structures is different
 2741                  * than the size of the BIO interface structures, the
 2742                  * amount of data actually transferred from the drive will
 2743                  * be different than the amount of data transferred to
 2744                  * the user.
 2745                  */
 2746                 hdr = (struct scsi_report_zones_hdr *)ccb->ataio.data_ptr;
 2747                 if (avail_len < sizeof(*hdr)) {
 2748                         /*
 2749                          * Is there a better error than EIO here?  We asked
 2750                          * for at least the header, and we got less than
 2751                          * that.
 2752                          */
 2753                         bp->bio_error = EIO;
 2754                         bp->bio_flags |= BIO_ERROR;
 2755                         bp->bio_resid = bp->bio_bcount;
 2756                         break;
 2757                 }
 2758 
 2759                 hdr_len = le32dec(hdr->length);
 2760                 if (hdr_len > 0)
 2761                         rep->entries_available = hdr_len / sizeof(*desc);
 2762                 else
 2763                         rep->entries_available = 0;
 2764                 /*
 2765                  * NOTE: using the same values for the BIO version of the
 2766                  * same field as the SCSI/ATA values.  This means we could
 2767                  * get some additional values that aren't defined in bio.h
 2768                  * if more values of the same field are defined later.
 2769                  */
 2770                 rep->header.same = hdr->byte4 & SRZ_SAME_MASK;
 2771                 rep->header.maximum_lba = le64dec(hdr->maximum_lba);
 2772                 /*
 2773                  * If the drive reports no entries that match the query,
 2774                  * we're done.
 2775                  */
 2776                 if (hdr_len == 0) {
 2777                         rep->entries_filled = 0;
 2778                         bp->bio_resid = bp->bio_bcount;
 2779                         break;
 2780                 }
 2781 
 2782                 num_avail = min((avail_len - sizeof(*hdr)) / sizeof(*desc),
 2783                                 hdr_len / sizeof(*desc));
 2784                 /*
 2785                  * If the drive didn't return any data, then we're done.
 2786                  */
 2787                 if (num_avail == 0) {
 2788                         rep->entries_filled = 0;
 2789                         bp->bio_resid = bp->bio_bcount;
 2790                         break;
 2791                 }
 2792 
 2793                 num_to_fill = min(num_avail, rep->entries_allocated);
 2794                 /*
 2795                  * If the user didn't allocate any entries for us to fill,
 2796                  * we're done.
 2797                  */
 2798                 if (num_to_fill == 0) {
 2799                         rep->entries_filled = 0;
 2800                         bp->bio_resid = bp->bio_bcount;
 2801                         break;
 2802                 }
 2803 
 2804                 for (i = 0, desc = &hdr->desc_list[0], entry=&rep->entries[0];
 2805                      i < num_to_fill; i++, desc++, entry++) {
 2806                         /*
 2807                          * NOTE: we're mapping the values here directly
 2808                          * from the SCSI/ATA bit definitions to the bio.h
 2809                          * definitions.  There is also a warning in
 2810                          * disk_zone.h, but the impact is that if
 2811                          * additional values are added in the SCSI/ATA
 2812                          * specs these will be visible to consumers of
 2813                          * this interface.
 2814                          */
 2815                         entry->zone_type = desc->zone_type & SRZ_TYPE_MASK;
 2816                         entry->zone_condition =
 2817                             (desc->zone_flags & SRZ_ZONE_COND_MASK) >>
 2818                             SRZ_ZONE_COND_SHIFT;
 2819                         entry->zone_flags |= desc->zone_flags &
 2820                             (SRZ_ZONE_NON_SEQ|SRZ_ZONE_RESET);
 2821                         entry->zone_length = le64dec(desc->zone_length);
 2822                         entry->zone_start_lba = le64dec(desc->zone_start_lba);
 2823                         entry->write_pointer_lba =
 2824                             le64dec(desc->write_pointer_lba);
 2825                 }
 2826                 rep->entries_filled = num_to_fill;
 2827                 /*
 2828                  * Note that this residual is accurate from the user's
 2829                  * standpoint, but the amount transferred isn't accurate
 2830                  * from the standpoint of what actually came back from the
 2831                  * drive.
 2832                  */
 2833                 bp->bio_resid = bp->bio_bcount - (num_to_fill * sizeof(*entry));
 2834                 break;
 2835         }
 2836         case DISK_ZONE_GET_PARAMS:
 2837         default:
 2838                 /*
 2839                  * In theory we should not get a GET_PARAMS bio, since it
 2840                  * should be handled without queueing the command to the
 2841                  * drive.
 2842                  */
 2843                 panic("%s: Invalid zone command %d", __func__,
 2844                     bp->bio_zone.zone_cmd);
 2845                 break;
 2846         }
 2847 
 2848         if (bp->bio_zone.zone_cmd == DISK_ZONE_REPORT_ZONES)
 2849                 free(ccb->ataio.data_ptr, M_ATADA);
 2850 }
 2851 
 2852 static void
 2853 adadone(struct cam_periph *periph, union ccb *done_ccb)
 2854 {
 2855         struct ada_softc *softc;
 2856         struct ccb_ataio *ataio;
 2857         struct cam_path *path;
 2858         uint32_t priority;
 2859         int state;
 2860 
 2861         softc = (struct ada_softc *)periph->softc;
 2862         ataio = &done_ccb->ataio;
 2863         path = done_ccb->ccb_h.path;
 2864         priority = done_ccb->ccb_h.pinfo.priority;
 2865 
 2866         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("adadone\n"));
 2867 
 2868         state = ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK;
 2869         switch (state) {
 2870         case ADA_CCB_BUFFER_IO:
 2871         case ADA_CCB_TRIM:
 2872         {
 2873                 struct bio *bp;
 2874                 int error;
 2875 
 2876                 cam_periph_lock(periph);
 2877                 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
 2878                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 2879                         error = adaerror(done_ccb, CAM_RETRY_SELTO, 0);
 2880                         if (error == ERESTART) {
 2881                                 /* A retry was scheduled, so just return. */
 2882                                 cam_periph_unlock(periph);
 2883                                 return;
 2884                         }
 2885                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 2886                                 cam_release_devq(path,
 2887                                                  /*relsim_flags*/0,
 2888                                                  /*reduction*/0,
 2889                                                  /*timeout*/0,
 2890                                                  /*getcount_only*/0);
 2891                         /*
 2892                          * If we get an error on an NCQ DSM TRIM, fall back
 2893                          * to a non-NCQ DSM TRIM forever. Please note that if
 2894                          * CAN_NCQ_TRIM is set, CAN_TRIM is necessarily set too.
 2895                          * However, for this one trim, we treat it as advisory
 2896                          * and return success up the stack.
 2897                          */
 2898                         if (state == ADA_CCB_TRIM &&
 2899                             error != 0 &&
 2900                             (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) != 0) {
 2901                                 softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
 2902                                 error = 0;
 2903                                 adasetdeletemethod(softc);
 2904                         }
 2905                 } else {
 2906                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 2907                                 panic("REQ_CMP with QFRZN");
 2908 
 2909                         error = 0;
 2910                 }
 2911                 bp->bio_error = error;
 2912                 if (error != 0) {
 2913                         bp->bio_resid = bp->bio_bcount;
 2914                         bp->bio_flags |= BIO_ERROR;
 2915                 } else {
 2916                         if (bp->bio_cmd == BIO_ZONE)
 2917                                 adazonedone(periph, done_ccb);
 2918                         else if (state == ADA_CCB_TRIM)
 2919                                 bp->bio_resid = 0;
 2920                         else
 2921                                 bp->bio_resid = ataio->resid;
 2922 
 2923                         if ((bp->bio_resid > 0)
 2924                          && (bp->bio_cmd != BIO_ZONE))
 2925                                 bp->bio_flags |= BIO_ERROR;
 2926                 }
 2927                 softc->outstanding_cmds--;
 2928                 if (softc->outstanding_cmds == 0)
 2929                         softc->flags |= ADA_FLAG_WAS_OTAG;
 2930 
 2931                 /*
 2932                  * We need to call cam_iosched before we call biodone so that we
 2933                  * don't measure any activity that happens in the completion
 2934                  * routine, which in the case of sendfile can be quite
 2935                  * extensive.  Release the periph refcount taken in adastart()
 2936                  * for each CCB.
 2937                  */
 2938                 cam_iosched_bio_complete(softc->cam_iosched, bp, done_ccb);
 2939                 xpt_release_ccb(done_ccb);
 2940                 KASSERT(softc->refcount >= 1, ("adadone softc %p refcount %d", softc, softc->refcount));
 2941                 softc->refcount--;
 2942                 if (state == ADA_CCB_TRIM) {
 2943                         TAILQ_HEAD(, bio) queue;
 2944                         struct bio *bp1;
 2945 
 2946                         TAILQ_INIT(&queue);
 2947                         TAILQ_CONCAT(&queue, &softc->trim_req.bps, bio_queue);
 2948                         /*
 2949                          * Normally, the xpt_release_ccb() above would make sure
 2950                          * that when we have more work to do, that work would
 2951                          * get kicked off. However, we specifically keep
 2952                          * trim_running set to 0 before the call above to allow
 2953                          * other I/O to progress when many BIO_DELETE requests
 2954                          * are pushed down. We set trim_running to 0 and call
 2955                          * daschedule again so that we don't stall if there are
 2956                          * no other I/Os pending apart from BIO_DELETEs.
 2957                          */
 2958                         cam_iosched_trim_done(softc->cam_iosched);
 2959                         adaschedule(periph);
 2960                         cam_periph_unlock(periph);
 2961                         while ((bp1 = TAILQ_FIRST(&queue)) != NULL) {
 2962                                 TAILQ_REMOVE(&queue, bp1, bio_queue);
 2963                                 bp1->bio_error = error;
 2964                                 if (error != 0) {
 2965                                         bp1->bio_flags |= BIO_ERROR;
 2966                                         bp1->bio_resid = bp1->bio_bcount;
 2967                                 } else
 2968                                         bp1->bio_resid = 0;
 2969                                 biodone(bp1);
 2970                         }
 2971                 } else {
 2972                         adaschedule(periph);
 2973                         cam_periph_unlock(periph);
 2974                         biodone(bp);
 2975                 }
 2976                 return;
 2977         }
 2978         case ADA_CCB_RAHEAD:
 2979         {
 2980                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 2981                         if (adaerror(done_ccb, 0, 0) == ERESTART) {
 2982                                 /* Drop freeze taken due to CAM_DEV_QFREEZE */
 2983                                 cam_release_devq(path, 0, 0, 0, FALSE);
 2984                                 return;
 2985                         } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 2986                                 cam_release_devq(path,
 2987                                     /*relsim_flags*/0,
 2988                                     /*reduction*/0,
 2989                                     /*timeout*/0,
 2990                                     /*getcount_only*/0);
 2991                         }
 2992                 }
 2993 
 2994                 xpt_release_ccb(done_ccb);
 2995                 softc->state = ADA_STATE_WCACHE;
 2996                 xpt_schedule(periph, priority);
 2997                 /* Drop freeze taken due to CAM_DEV_QFREEZE */
 2998                 cam_release_devq(path, 0, 0, 0, FALSE);
 2999                 return;
 3000         }
 3001         case ADA_CCB_WCACHE:
 3002         {
 3003                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 3004                         if (adaerror(done_ccb, 0, 0) == ERESTART) {
 3005                                 /* Drop freeze taken due to CAM_DEV_QFREEZE */
 3006                                 cam_release_devq(path, 0, 0, 0, FALSE);
 3007                                 return;
 3008                         } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 3009                                 cam_release_devq(path,
 3010                                     /*relsim_flags*/0,
 3011                                     /*reduction*/0,
 3012                                     /*timeout*/0,
 3013                                     /*getcount_only*/0);
 3014                         }
 3015                 }
 3016 
 3017                 /* Drop freeze taken due to CAM_DEV_QFREEZE */
 3018                 cam_release_devq(path, 0, 0, 0, FALSE);
 3019 
 3020                 if ((softc->flags & ADA_FLAG_CAN_LOG)
 3021                  && (softc->zone_mode != ADA_ZONE_NONE)) {
 3022                         xpt_release_ccb(done_ccb);
 3023                         softc->state = ADA_STATE_LOGDIR;
 3024                         xpt_schedule(periph, priority);
 3025                 } else {
 3026                         adaprobedone(periph, done_ccb);
 3027                 }
 3028                 return;
 3029         }
 3030         case ADA_CCB_LOGDIR:
 3031         {
 3032                 int error;
 3033 
 3034                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3035                         error = 0;
 3036                         softc->valid_logdir_len = 0;
 3037                         bzero(&softc->ata_logdir, sizeof(softc->ata_logdir));
 3038                         softc->valid_logdir_len =
 3039                                 ataio->dxfer_len - ataio->resid;
 3040                         if (softc->valid_logdir_len > 0)
 3041                                 bcopy(ataio->data_ptr, &softc->ata_logdir,
 3042                                     min(softc->valid_logdir_len,
 3043                                         sizeof(softc->ata_logdir)));
 3044                         /*
 3045                          * Figure out whether the Identify Device log is
 3046                          * supported.  The General Purpose log directory
 3047                          * has a header, and lists the number of pages
 3048                          * available for each GP log identified by the
 3049                          * offset into the list.
 3050                          */
 3051                         if ((softc->valid_logdir_len >=
 3052                             ((ATA_IDENTIFY_DATA_LOG + 1) * sizeof(uint16_t)))
 3053                          && (le16dec(softc->ata_logdir.header) ==
 3054                              ATA_GP_LOG_DIR_VERSION)
 3055                          && (le16dec(&softc->ata_logdir.num_pages[
 3056                              (ATA_IDENTIFY_DATA_LOG *
 3057                              sizeof(uint16_t)) - sizeof(uint16_t)]) > 0)){
 3058                                 softc->flags |= ADA_FLAG_CAN_IDLOG;
 3059                         } else {
 3060                                 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
 3061                         }
 3062                 } else {
 3063                         error = adaerror(done_ccb, CAM_RETRY_SELTO,
 3064                                          SF_RETRY_UA|SF_NO_PRINT);
 3065                         if (error == ERESTART)
 3066                                 return;
 3067                         else if (error != 0) {
 3068                                 /*
 3069                                  * If we can't get the ATA log directory,
 3070                                  * then ATA logs are effectively not
 3071                                  * supported even if the bit is set in the
 3072                                  * identify data.
 3073                                  */
 3074                                 softc->flags &= ~(ADA_FLAG_CAN_LOG |
 3075                                                   ADA_FLAG_CAN_IDLOG);
 3076                                 if ((done_ccb->ccb_h.status &
 3077                                      CAM_DEV_QFRZN) != 0) {
 3078                                         /* Don't wedge this device's queue */
 3079                                         cam_release_devq(done_ccb->ccb_h.path,
 3080                                                          /*relsim_flags*/0,
 3081                                                          /*reduction*/0,
 3082                                                          /*timeout*/0,
 3083                                                          /*getcount_only*/0);
 3084                                 }
 3085                         }
 3086                 }
 3087 
 3088                 free(ataio->data_ptr, M_ATADA);
 3089 
 3090                 if ((error == 0)
 3091                  && (softc->flags & ADA_FLAG_CAN_IDLOG)) {
 3092                         softc->state = ADA_STATE_IDDIR;
 3093                         xpt_release_ccb(done_ccb);
 3094                         xpt_schedule(periph, priority);
 3095                 } else
 3096                         adaprobedone(periph, done_ccb);
 3097 
 3098                 return;
 3099         }
 3100         case ADA_CCB_IDDIR: {
 3101                 int error;
 3102 
 3103                 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3104                         off_t entries_offset, max_entries;
 3105                         error = 0;
 3106 
 3107                         softc->valid_iddir_len = 0;
 3108                         bzero(&softc->ata_iddir, sizeof(softc->ata_iddir));
 3109                         softc->flags &= ~(ADA_FLAG_CAN_SUPCAP |
 3110                                           ADA_FLAG_CAN_ZONE);
 3111                         softc->valid_iddir_len =
 3112                                 ataio->dxfer_len - ataio->resid;
 3113                         if (softc->valid_iddir_len > 0)
 3114                                 bcopy(ataio->data_ptr, &softc->ata_iddir,
 3115                                     min(softc->valid_iddir_len,
 3116                                         sizeof(softc->ata_iddir)));
 3117 
 3118                         entries_offset =
 3119                             __offsetof(struct ata_identify_log_pages,entries);
 3120                         max_entries = softc->valid_iddir_len - entries_offset;
 3121                         if ((softc->valid_iddir_len > (entries_offset + 1))
 3122                          && (le64dec(softc->ata_iddir.header) ==
 3123                              ATA_IDLOG_REVISION)
 3124                          && (softc->ata_iddir.entry_count > 0)) {
 3125                                 int num_entries, i;
 3126 
 3127                                 num_entries = softc->ata_iddir.entry_count;
 3128                                 num_entries = min(num_entries,
 3129                                    softc->valid_iddir_len - entries_offset);
 3130                                 for (i = 0; i < num_entries &&
 3131                                      i < max_entries; i++) {
 3132                                         if (softc->ata_iddir.entries[i] ==
 3133                                             ATA_IDL_SUP_CAP)
 3134                                                 softc->flags |=
 3135                                                     ADA_FLAG_CAN_SUPCAP;
 3136                                         else if (softc->ata_iddir.entries[i]==
 3137                                                  ATA_IDL_ZDI)
 3138                                                 softc->flags |=
 3139                                                     ADA_FLAG_CAN_ZONE;
 3140 
 3141                                         if ((softc->flags &
 3142                                              ADA_FLAG_CAN_SUPCAP)
 3143                                          && (softc->flags &
 3144                                              ADA_FLAG_CAN_ZONE))
 3145                                                 break;
 3146                                 }
 3147                         }
 3148                 } else {
 3149                         error = adaerror(done_ccb, CAM_RETRY_SELTO,
 3150                                          SF_RETRY_UA|SF_NO_PRINT);
 3151                         if (error == ERESTART)
 3152                                 return;
 3153                         else if (error != 0) {
 3154                                 /*
 3155                                  * If we can't get the ATA Identify Data log
 3156                                  * directory, then it effectively isn't
 3157                                  * supported even if the ATA Log directory
 3158                                  * a non-zero number of pages present for
 3159                                  * this log.
 3160                                  */
 3161                                 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
 3162                                 if ((done_ccb->ccb_h.status &
 3163                                      CAM_DEV_QFRZN) != 0) {
 3164                                         /* Don't wedge this device's queue */
 3165                                         cam_release_devq(done_ccb->ccb_h.path,
 3166                                                          /*relsim_flags*/0,
 3167                                                          /*reduction*/0,
 3168                                                          /*timeout*/0,
 3169                                                          /*getcount_only*/0);
 3170                                 }
 3171                         }
 3172                 }
 3173 
 3174                 free(ataio->data_ptr, M_ATADA);
 3175 
 3176                 if ((error == 0)
 3177                  && (softc->flags & ADA_FLAG_CAN_SUPCAP)) {
 3178                         softc->state = ADA_STATE_SUP_CAP;
 3179                         xpt_release_ccb(done_ccb);
 3180                         xpt_schedule(periph, priority);
 3181                 } else
 3182                         adaprobedone(periph, done_ccb);
 3183                 return;
 3184         }
 3185         case ADA_CCB_SUP_CAP: {
 3186                 int error;
 3187 
 3188                 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3189                         uint32_t valid_len;
 3190                         size_t needed_size;
 3191                         struct ata_identify_log_sup_cap *sup_cap;
 3192                         error = 0;
 3193 
 3194                         sup_cap = (struct ata_identify_log_sup_cap *)
 3195                             ataio->data_ptr;
 3196                         valid_len = ataio->dxfer_len - ataio->resid;
 3197                         needed_size =
 3198                             __offsetof(struct ata_identify_log_sup_cap,
 3199                             sup_zac_cap) + 1 + sizeof(sup_cap->sup_zac_cap);
 3200                         if (valid_len >= needed_size) {
 3201                                 uint64_t zoned, zac_cap;
 3202 
 3203                                 zoned = le64dec(sup_cap->zoned_cap);
 3204                                 if (zoned & ATA_ZONED_VALID) {
 3205                                         /*
 3206                                          * This should have already been
 3207                                          * set, because this is also in the
 3208                                          * ATA identify data.
 3209                                          */
 3210                                         if ((zoned & ATA_ZONED_MASK) ==
 3211                                             ATA_SUPPORT_ZONE_HOST_AWARE)
 3212                                                 softc->zone_mode =
 3213                                                     ADA_ZONE_HOST_AWARE;
 3214                                         else if ((zoned & ATA_ZONED_MASK) ==
 3215                                             ATA_SUPPORT_ZONE_DEV_MANAGED)
 3216                                                 softc->zone_mode =
 3217                                                     ADA_ZONE_DRIVE_MANAGED;
 3218                                 }
 3219 
 3220                                 zac_cap = le64dec(sup_cap->sup_zac_cap);
 3221                                 if (zac_cap & ATA_SUP_ZAC_CAP_VALID) {
 3222                                         if (zac_cap & ATA_REPORT_ZONES_SUP)
 3223                                                 softc->zone_flags |=
 3224                                                     ADA_ZONE_FLAG_RZ_SUP;
 3225                                         if (zac_cap & ATA_ND_OPEN_ZONE_SUP)
 3226                                                 softc->zone_flags |=
 3227                                                     ADA_ZONE_FLAG_OPEN_SUP;
 3228                                         if (zac_cap & ATA_ND_CLOSE_ZONE_SUP)
 3229                                                 softc->zone_flags |=
 3230                                                     ADA_ZONE_FLAG_CLOSE_SUP;
 3231                                         if (zac_cap & ATA_ND_FINISH_ZONE_SUP)
 3232                                                 softc->zone_flags |=
 3233                                                     ADA_ZONE_FLAG_FINISH_SUP;
 3234                                         if (zac_cap & ATA_ND_RWP_SUP)
 3235                                                 softc->zone_flags |=
 3236                                                     ADA_ZONE_FLAG_RWP_SUP;
 3237                                 } else {
 3238                                         /*
 3239                                          * This field was introduced in
 3240                                          * ACS-4, r08 on April 28th, 2015.
 3241                                          * If the drive firmware was written
 3242                                          * to an earlier spec, it won't have
 3243                                          * the field.  So, assume all
 3244                                          * commands are supported.
 3245                                          */
 3246                                         softc->zone_flags |=
 3247                                             ADA_ZONE_FLAG_SUP_MASK;
 3248                                 }
 3249                         }
 3250                 } else {
 3251                         error = adaerror(done_ccb, CAM_RETRY_SELTO,
 3252                                          SF_RETRY_UA|SF_NO_PRINT);
 3253                         if (error == ERESTART)
 3254                                 return;
 3255                         else if (error != 0) {
 3256                                 /*
 3257                                  * If we can't get the ATA Identify Data
 3258                                  * Supported Capabilities page, clear the
 3259                                  * flag...
 3260                                  */
 3261                                 softc->flags &= ~ADA_FLAG_CAN_SUPCAP;
 3262                                 /*
 3263                                  * And clear zone capabilities.
 3264                                  */
 3265                                 softc->zone_flags &= ~ADA_ZONE_FLAG_SUP_MASK;
 3266                                 if ((done_ccb->ccb_h.status &
 3267                                      CAM_DEV_QFRZN) != 0) {
 3268                                         /* Don't wedge this device's queue */
 3269                                         cam_release_devq(done_ccb->ccb_h.path,
 3270                                                          /*relsim_flags*/0,
 3271                                                          /*reduction*/0,
 3272                                                          /*timeout*/0,
 3273                                                          /*getcount_only*/0);
 3274                                 }
 3275                         }
 3276                 }
 3277 
 3278                 free(ataio->data_ptr, M_ATADA);
 3279 
 3280                 if ((error == 0)
 3281                  && (softc->flags & ADA_FLAG_CAN_ZONE)) {
 3282                         softc->state = ADA_STATE_ZONE;
 3283                         xpt_release_ccb(done_ccb);
 3284                         xpt_schedule(periph, priority);
 3285                 } else
 3286                         adaprobedone(periph, done_ccb);
 3287                 return;
 3288         }
 3289         case ADA_CCB_ZONE: {
 3290                 int error;
 3291 
 3292                 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 3293                         struct ata_zoned_info_log *zi_log;
 3294                         uint32_t valid_len;
 3295                         size_t needed_size;
 3296 
 3297                         zi_log = (struct ata_zoned_info_log *)ataio->data_ptr;
 3298 
 3299                         valid_len = ataio->dxfer_len - ataio->resid;
 3300                         needed_size = __offsetof(struct ata_zoned_info_log,
 3301                             version_info) + 1 + sizeof(zi_log->version_info);
 3302                         if (valid_len >= needed_size) {
 3303                                 uint64_t tmpvar;
 3304 
 3305                                 tmpvar = le64dec(zi_log->zoned_cap);
 3306                                 if (tmpvar & ATA_ZDI_CAP_VALID) {
 3307                                         if (tmpvar & ATA_ZDI_CAP_URSWRZ)
 3308                                                 softc->zone_flags |=
 3309                                                     ADA_ZONE_FLAG_URSWRZ;
 3310                                         else
 3311                                                 softc->zone_flags &=
 3312                                                     ~ADA_ZONE_FLAG_URSWRZ;
 3313                                 }
 3314                                 tmpvar = le64dec(zi_log->optimal_seq_zones);
 3315                                 if (tmpvar & ATA_ZDI_OPT_SEQ_VALID) {
 3316                                         softc->zone_flags |=
 3317                                             ADA_ZONE_FLAG_OPT_SEQ_SET;
 3318                                         softc->optimal_seq_zones = (tmpvar &
 3319                                             ATA_ZDI_OPT_SEQ_MASK);
 3320                                 } else {
 3321                                         softc->zone_flags &=
 3322                                             ~ADA_ZONE_FLAG_OPT_SEQ_SET;
 3323                                         softc->optimal_seq_zones = 0;
 3324                                 }
 3325 
 3326                                 tmpvar =le64dec(zi_log->optimal_nonseq_zones);
 3327                                 if (tmpvar & ATA_ZDI_OPT_NS_VALID) {
 3328                                         softc->zone_flags |=
 3329                                             ADA_ZONE_FLAG_OPT_NONSEQ_SET;
 3330                                         softc->optimal_nonseq_zones =
 3331                                             (tmpvar & ATA_ZDI_OPT_NS_MASK);
 3332                                 } else {
 3333                                         softc->zone_flags &=
 3334                                             ~ADA_ZONE_FLAG_OPT_NONSEQ_SET;
 3335                                         softc->optimal_nonseq_zones = 0;
 3336                                 }
 3337 
 3338                                 tmpvar = le64dec(zi_log->max_seq_req_zones);
 3339                                 if (tmpvar & ATA_ZDI_MAX_SEQ_VALID) {
 3340                                         softc->zone_flags |=
 3341                                             ADA_ZONE_FLAG_MAX_SEQ_SET;
 3342                                         softc->max_seq_zones =
 3343                                             (tmpvar & ATA_ZDI_MAX_SEQ_MASK);
 3344                                 } else {
 3345                                         softc->zone_flags &=
 3346                                             ~ADA_ZONE_FLAG_MAX_SEQ_SET;
 3347                                         softc->max_seq_zones = 0;
 3348                                 }
 3349                         }
 3350                 } else {
 3351                         error = adaerror(done_ccb, CAM_RETRY_SELTO,
 3352                                          SF_RETRY_UA|SF_NO_PRINT);
 3353                         if (error == ERESTART)
 3354                                 return;
 3355                         else if (error != 0) {
 3356                                 softc->flags &= ~ADA_FLAG_CAN_ZONE;
 3357                                 softc->flags &= ~ADA_ZONE_FLAG_SET_MASK;
 3358 
 3359                                 if ((done_ccb->ccb_h.status &
 3360                                      CAM_DEV_QFRZN) != 0) {
 3361                                         /* Don't wedge this device's queue */
 3362                                         cam_release_devq(done_ccb->ccb_h.path,
 3363                                                          /*relsim_flags*/0,
 3364                                                          /*reduction*/0,
 3365                                                          /*timeout*/0,
 3366                                                          /*getcount_only*/0);
 3367                                 }
 3368                         }
 3369                 }
 3370                 free(ataio->data_ptr, M_ATADA);
 3371 
 3372                 adaprobedone(periph, done_ccb);
 3373                 return;
 3374         }
 3375         case ADA_CCB_DUMP:
 3376                 /* No-op.  We're polling */
 3377                 return;
 3378         default:
 3379                 break;
 3380         }
 3381         xpt_release_ccb(done_ccb);
 3382 }
 3383 
 3384 static int
 3385 adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
 3386 {
 3387 #ifdef CAM_IO_STATS
 3388         struct ada_softc *softc;
 3389         struct cam_periph *periph;
 3390 
 3391         periph = xpt_path_periph(ccb->ccb_h.path);
 3392         softc = (struct ada_softc *)periph->softc;
 3393 
 3394         switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
 3395         case CAM_CMD_TIMEOUT:
 3396                 softc->timeouts++;
 3397                 break;
 3398         case CAM_REQ_ABORTED:
 3399         case CAM_REQ_CMP_ERR:
 3400         case CAM_REQ_TERMIO:
 3401         case CAM_UNREC_HBA_ERROR:
 3402         case CAM_DATA_RUN_ERR:
 3403         case CAM_ATA_STATUS_ERROR:
 3404                 softc->errors++;
 3405                 break;
 3406         default:
 3407                 break;
 3408         }
 3409 #endif
 3410 
 3411         return(cam_periph_error(ccb, cam_flags, sense_flags));
 3412 }
 3413 
 3414 static void
 3415 adasetgeom(struct ada_softc *softc, struct ccb_getdev *cgd)
 3416 {
 3417         struct disk_params *dp = &softc->params;
 3418         u_int64_t lbasize48;
 3419         u_int32_t lbasize;
 3420         u_int maxio, d_flags;
 3421         size_t tmpsize;
 3422 
 3423         dp->secsize = ata_logical_sector_size(&cgd->ident_data);
 3424         if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
 3425             cgd->ident_data.current_heads != 0 &&
 3426             cgd->ident_data.current_sectors != 0) {
 3427                 dp->heads = cgd->ident_data.current_heads;
 3428                 dp->secs_per_track = cgd->ident_data.current_sectors;
 3429                 dp->cylinders = cgd->ident_data.cylinders;
 3430                 dp->sectors = (u_int32_t)cgd->ident_data.current_size_1 |
 3431                           ((u_int32_t)cgd->ident_data.current_size_2 << 16);
 3432         } else {
 3433                 dp->heads = cgd->ident_data.heads;
 3434                 dp->secs_per_track = cgd->ident_data.sectors;
 3435                 dp->cylinders = cgd->ident_data.cylinders;
 3436                 dp->sectors = cgd->ident_data.cylinders *
 3437                               (u_int32_t)(dp->heads * dp->secs_per_track);
 3438         }
 3439         lbasize = (u_int32_t)cgd->ident_data.lba_size_1 |
 3440                   ((u_int32_t)cgd->ident_data.lba_size_2 << 16);
 3441 
 3442         /* use the 28bit LBA size if valid or bigger than the CHS mapping */
 3443         if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
 3444                 dp->sectors = lbasize;
 3445 
 3446         /* use the 48bit LBA size if valid */
 3447         lbasize48 = ((u_int64_t)cgd->ident_data.lba_size48_1) |
 3448                     ((u_int64_t)cgd->ident_data.lba_size48_2 << 16) |
 3449                     ((u_int64_t)cgd->ident_data.lba_size48_3 << 32) |
 3450                     ((u_int64_t)cgd->ident_data.lba_size48_4 << 48);
 3451         if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) &&
 3452             lbasize48 > ATA_MAX_28BIT_LBA)
 3453                 dp->sectors = lbasize48;
 3454 
 3455         maxio = softc->cpi.maxio;               /* Honor max I/O size of SIM */
 3456         if (maxio == 0)
 3457                 maxio = DFLTPHYS;       /* traditional default */
 3458         else if (maxio > maxphys)
 3459                 maxio = maxphys;        /* for safety */
 3460         if (softc->flags & ADA_FLAG_CAN_48BIT)
 3461                 maxio = min(maxio, 65536 * softc->params.secsize);
 3462         else                                    /* 28bit ATA command limit */
 3463                 maxio = min(maxio, 256 * softc->params.secsize);
 3464         if (softc->quirks & ADA_Q_128KB)
 3465                 maxio = min(maxio, 128 * 1024);
 3466         softc->disk->d_maxsize = maxio;
 3467         d_flags = DISKFLAG_DIRECT_COMPLETION | DISKFLAG_CANZONE;
 3468         if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
 3469                 d_flags |= DISKFLAG_CANFLUSHCACHE;
 3470         if (softc->flags & ADA_FLAG_CAN_TRIM) {
 3471                 d_flags |= DISKFLAG_CANDELETE;
 3472                 softc->disk->d_delmaxsize = softc->params.secsize *
 3473                     ATA_DSM_RANGE_MAX * softc->trim_max_ranges;
 3474         } else if ((softc->flags & ADA_FLAG_CAN_CFA) &&
 3475             !(softc->flags & ADA_FLAG_CAN_48BIT)) {
 3476                 d_flags |= DISKFLAG_CANDELETE;
 3477                 softc->disk->d_delmaxsize = 256 * softc->params.secsize;
 3478         } else
 3479                 softc->disk->d_delmaxsize = maxio;
 3480         if ((softc->cpi.hba_misc & PIM_UNMAPPED) != 0) {
 3481                 d_flags |= DISKFLAG_UNMAPPED_BIO;
 3482                 softc->flags |= ADA_FLAG_UNMAPPEDIO;
 3483         }
 3484         softc->disk->d_flags = d_flags;
 3485 
 3486         /*
 3487          * ata_param_fixup will strip trailing padding spaces and add a NUL,
 3488          * but if the field has no padding (as is common for serial numbers)
 3489          * there will still be no NUL terminator. We cannot use strlcpy, since
 3490          * it keeps reading src until it finds a NUL in order to compute the
 3491          * return value (and will truncate the final character due to having a
 3492          * single dsize rather than separate ssize and dsize), and strncpy does
 3493          * not add a NUL to the destination if it reaches the character limit.
 3494          */
 3495         tmpsize = MIN(sizeof(softc->disk->d_descr) - 1,
 3496             sizeof(cgd->ident_data.model));
 3497         memcpy(softc->disk->d_descr, cgd->ident_data.model, tmpsize);
 3498         softc->disk->d_descr[tmpsize] = '\0';
 3499 
 3500         tmpsize = MIN(sizeof(softc->disk->d_ident) - 1,
 3501             sizeof(cgd->ident_data.serial));
 3502         memcpy(softc->disk->d_ident, cgd->ident_data.serial, tmpsize);
 3503         softc->disk->d_ident[tmpsize] = '\0';
 3504 
 3505         softc->disk->d_sectorsize = softc->params.secsize;
 3506         softc->disk->d_mediasize = (off_t)softc->params.sectors *
 3507             softc->params.secsize;
 3508         if (ata_physical_sector_size(&cgd->ident_data) !=
 3509             softc->params.secsize) {
 3510                 softc->disk->d_stripesize =
 3511                     ata_physical_sector_size(&cgd->ident_data);
 3512                 softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
 3513                     ata_logical_sector_offset(&cgd->ident_data)) %
 3514                     softc->disk->d_stripesize;
 3515         } else if (softc->quirks & ADA_Q_4K) {
 3516                 softc->disk->d_stripesize = 4096;
 3517                 softc->disk->d_stripeoffset = 0;
 3518         }
 3519         softc->disk->d_fwsectors = softc->params.secs_per_track;
 3520         softc->disk->d_fwheads = softc->params.heads;
 3521         softc->disk->d_rotation_rate = cgd->ident_data.media_rotation_rate;
 3522         snprintf(softc->disk->d_attachment, sizeof(softc->disk->d_attachment),
 3523             "%s%d", softc->cpi.dev_name, softc->cpi.unit_number);
 3524 }
 3525 
 3526 static void
 3527 adasendorderedtag(void *arg)
 3528 {
 3529         struct ada_softc *softc = arg;
 3530 
 3531         if (ada_send_ordered) {
 3532                 if (softc->outstanding_cmds > 0) {
 3533                         if ((softc->flags & ADA_FLAG_WAS_OTAG) == 0)
 3534                                 softc->flags |= ADA_FLAG_NEED_OTAG;
 3535                         softc->flags &= ~ADA_FLAG_WAS_OTAG;
 3536                 }
 3537         }
 3538 
 3539         /* Queue us up again */
 3540         callout_schedule_sbt(&softc->sendordered_c,
 3541             SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
 3542             C_PREL(1));
 3543 }
 3544 
 3545 /*
 3546  * Step through all ADA peripheral drivers, and if the device is still open,
 3547  * sync the disk cache to physical media.
 3548  */
 3549 static void
 3550 adaflush(void)
 3551 {
 3552         struct cam_periph *periph;
 3553         struct ada_softc *softc;
 3554         union ccb *ccb;
 3555         int error;
 3556 
 3557         CAM_PERIPH_FOREACH(periph, &adadriver) {
 3558                 softc = (struct ada_softc *)periph->softc;
 3559                 if (SCHEDULER_STOPPED()) {
 3560                         /* If we panicked with the lock held, do not recurse. */
 3561                         if (!cam_periph_owned(periph) &&
 3562                             (softc->flags & ADA_FLAG_OPEN)) {
 3563                                 adadump(softc->disk, NULL, 0, 0);
 3564                         }
 3565                         continue;
 3566                 }
 3567                 cam_periph_lock(periph);
 3568                 /*
 3569                  * We only sync the cache if the drive is still open, and
 3570                  * if the drive is capable of it..
 3571                  */
 3572                 if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
 3573                     (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
 3574                         cam_periph_unlock(periph);
 3575                         continue;
 3576                 }
 3577 
 3578                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
 3579                 cam_fill_ataio(&ccb->ataio,
 3580                                     0,
 3581                                     NULL,
 3582                                     CAM_DIR_NONE,
 3583                                     0,
 3584                                     NULL,
 3585                                     0,
 3586                                     ada_default_timeout*1000);
 3587                 if (softc->flags & ADA_FLAG_CAN_48BIT)
 3588                         ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
 3589                 else
 3590                         ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
 3591 
 3592                 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
 3593                     /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
 3594                     softc->disk->d_devstat);
 3595                 if (error != 0)
 3596                         xpt_print(periph->path, "Synchronize cache failed\n");
 3597                 xpt_release_ccb(ccb);
 3598                 cam_periph_unlock(periph);
 3599         }
 3600 }
 3601 
 3602 static void
 3603 adaspindown(uint8_t cmd, int flags)
 3604 {
 3605         struct cam_periph *periph;
 3606         struct ada_softc *softc;
 3607         struct ccb_ataio local_ccb;
 3608         int error;
 3609         int mode;
 3610 
 3611         CAM_PERIPH_FOREACH(periph, &adadriver) {
 3612                 /* If we panicked with lock held - not recurse here. */
 3613                 if (cam_periph_owned(periph))
 3614                         continue;
 3615                 cam_periph_lock(periph);
 3616                 softc = (struct ada_softc *)periph->softc;
 3617                 /*
 3618                  * We only spin-down the drive if it is capable of it..
 3619                  */
 3620                 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
 3621                         cam_periph_unlock(periph);
 3622                         continue;
 3623                 }
 3624 
 3625                 /*
 3626                  * Additionally check if we would spin up the drive instead of
 3627                  * spinning it down.
 3628                  */
 3629                 if (cmd == ATA_IDLE_IMMEDIATE) {
 3630                         memset(&local_ccb, 0, sizeof(local_ccb));
 3631                         xpt_setup_ccb(&local_ccb.ccb_h, periph->path,
 3632                             CAM_PRIORITY_NORMAL);
 3633                         local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
 3634 
 3635                         cam_fill_ataio(&local_ccb, 0, NULL, CAM_DIR_NONE,
 3636                             0, NULL, 0, ada_default_timeout * 1000);
 3637                         ata_28bit_cmd(&local_ccb, ATA_CHECK_POWER_MODE,
 3638                             0, 0, 0);
 3639                         local_ccb.cmd.flags |= CAM_ATAIO_NEEDRESULT;
 3640 
 3641                         error = cam_periph_runccb((union ccb *)&local_ccb,
 3642                             adaerror, /*cam_flags*/0,
 3643                             /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
 3644                             softc->disk->d_devstat);
 3645                         if (error != 0) {
 3646                                 xpt_print(periph->path,
 3647                                     "Failed to read current power mode\n");
 3648                         } else {
 3649                                 mode = local_ccb.res.sector_count;
 3650 #ifdef DIAGNOSTIC
 3651                                 if (bootverbose) {
 3652                                         xpt_print(periph->path,
 3653                                             "disk power mode 0x%02x\n", mode);
 3654                                 }
 3655 #endif
 3656                                 switch (mode) {
 3657                                 case ATA_PM_STANDBY:
 3658                                 case ATA_PM_STANDBY_Y:
 3659                                         if (bootverbose) {
 3660                                                 xpt_print(periph->path,
 3661                                                     "already spun down\n");
 3662                                         }
 3663                                         cam_periph_unlock(periph);
 3664                                         continue;
 3665                                 default:
 3666                                         break;
 3667                                 }
 3668                         }
 3669                 }
 3670 
 3671                 if (bootverbose)
 3672                         xpt_print(periph->path, "spin-down\n");
 3673 
 3674                 memset(&local_ccb, 0, sizeof(local_ccb));
 3675                 xpt_setup_ccb(&local_ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
 3676                 local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
 3677 
 3678                 cam_fill_ataio(&local_ccb,
 3679                                     0,
 3680                                     NULL,
 3681                                     CAM_DIR_NONE | flags,
 3682                                     0,
 3683                                     NULL,
 3684                                     0,
 3685                                     ada_default_timeout*1000);
 3686                 ata_28bit_cmd(&local_ccb, cmd, 0, 0, 0);
 3687                 error = cam_periph_runccb((union ccb *)&local_ccb, adaerror,
 3688                     /*cam_flags*/0, /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
 3689                     softc->disk->d_devstat);
 3690                 if (error != 0)
 3691                         xpt_print(periph->path, "Spin-down disk failed\n");
 3692                 cam_periph_unlock(periph);
 3693         }
 3694 }
 3695 
 3696 static void
 3697 adashutdown(void *arg, int howto)
 3698 {
 3699         int how;
 3700 
 3701         if ((howto & RB_NOSYNC) != 0)
 3702                 return;
 3703 
 3704         adaflush();
 3705 
 3706         /*
 3707          * STANDBY IMMEDIATE saves any volatile data to the drive. It also spins
 3708          * down hard drives. IDLE IMMEDIATE also saves the volatile data without
 3709          * a spindown. We send the former when we expect to lose power soon. For
 3710          * a warm boot, we send the latter to avoid a thundering herd of spinups
 3711          * just after the kernel loads while probing. We have to do something to
 3712          * flush the data because the BIOS in many systems resets the HBA
 3713          * causing a COMINIT/COMRESET negotiation, which some drives interpret
 3714          * as license to toss the volatile data, and others count as unclean
 3715          * shutdown when in the Active PM state in SMART attributes.
 3716          *
 3717          * adaspindown will ensure that we don't send this to a drive that
 3718          * doesn't support it.
 3719          */
 3720         if (ada_spindown_shutdown != 0) {
 3721                 how = (howto & (RB_HALT | RB_POWEROFF | RB_POWERCYCLE)) ?
 3722                     ATA_STANDBY_IMMEDIATE : ATA_IDLE_IMMEDIATE;
 3723                 adaspindown(how, 0);
 3724         }
 3725 }
 3726 
 3727 static void
 3728 adasuspend(void *arg)
 3729 {
 3730 
 3731         adaflush();
 3732         /*
 3733          * SLEEP also fushes any volatile data, like STANDBY IMEDIATE,
 3734          * so we don't need to send it as well.
 3735          */
 3736         if (ada_spindown_suspend != 0)
 3737                 adaspindown(ATA_SLEEP, CAM_DEV_QFREEZE);
 3738 }
 3739 
 3740 static void
 3741 adaresume(void *arg)
 3742 {
 3743         struct cam_periph *periph;
 3744         struct ada_softc *softc;
 3745 
 3746         if (ada_spindown_suspend == 0)
 3747                 return;
 3748 
 3749         CAM_PERIPH_FOREACH(periph, &adadriver) {
 3750                 cam_periph_lock(periph);
 3751                 softc = (struct ada_softc *)periph->softc;
 3752                 /*
 3753                  * We only spin-down the drive if it is capable of it..
 3754                  */
 3755                 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
 3756                         cam_periph_unlock(periph);
 3757                         continue;
 3758                 }
 3759 
 3760                 if (bootverbose)
 3761                         xpt_print(periph->path, "resume\n");
 3762 
 3763                 /*
 3764                  * Drop freeze taken due to CAM_DEV_QFREEZE flag set on
 3765                  * sleep request.
 3766                  */
 3767                 cam_release_devq(periph->path,
 3768                          /*relsim_flags*/0,
 3769                          /*openings*/0,
 3770                          /*timeout*/0,
 3771                          /*getcount_only*/0);
 3772 
 3773                 cam_periph_unlock(periph);
 3774         }
 3775 }
 3776 
 3777 #endif /* _KERNEL */

Cache object: fdb14784698d79c3d2e0e9b008a2adab


[ 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.