root/dev/pci/arc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arc_match
  2. arc_attach
  3. arc_detach
  4. arc_shutdown
  5. arc_intr
  6. arc_scsi_cmd
  7. arc_load_xs
  8. arc_scsi_cmd_done
  9. arc_complete
  10. arc_minphys
  11. arc_map_pci_resources
  12. arc_query_firmware
  13. arc_bioctl
  14. arc_bio_alarm
  15. arc_bio_alarm_state
  16. arc_bio_inq
  17. arc_bio_getvol
  18. arc_bio_vol
  19. arc_bio_disk
  20. arc_msg_cksum
  21. arc_msgbuf
  22. arc_lock
  23. arc_unlock
  24. arc_wait
  25. arc_create_sensors
  26. arc_refresh_sensors
  27. arc_read
  28. arc_read_region
  29. arc_write
  30. arc_write_region
  31. arc_wait_eq
  32. arc_wait_ne
  33. arc_msg0
  34. arc_dmamem_alloc
  35. arc_dmamem_free
  36. arc_alloc_ccbs
  37. arc_get_ccb
  38. arc_put_ccb

    1 /*      $OpenBSD: arc.c,v 1.65 2007/07/11 19:01:30 otto Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include "bio.h"
   20 
   21 #include <sys/param.h>
   22 #include <sys/systm.h>
   23 #include <sys/buf.h>
   24 #include <sys/kernel.h>
   25 #include <sys/malloc.h>
   26 #include <sys/device.h>
   27 #include <sys/proc.h>
   28 #include <sys/rwlock.h>
   29 
   30 #include <machine/bus.h>
   31 
   32 #include <dev/pci/pcireg.h>
   33 #include <dev/pci/pcivar.h>
   34 #include <dev/pci/pcidevs.h>
   35 
   36 #include <scsi/scsi_all.h>
   37 #include <scsi/scsiconf.h>
   38 
   39 #include <sys/sensors.h>
   40 #if NBIO > 0
   41 #include <sys/ioctl.h>
   42 #include <dev/biovar.h>
   43 #endif
   44 
   45 #ifdef ARC_DEBUG
   46 #define ARC_D_INIT      (1<<0)
   47 #define ARC_D_RW        (1<<1)
   48 #define ARC_D_DB        (1<<2)
   49 
   50 int arcdebug = 0;
   51 
   52 #define DPRINTF(p...)           do { if (arcdebug) printf(p); } while (0)
   53 #define DNPRINTF(n, p...)       do { if ((n) & arcdebug) printf(p); } while (0)
   54 
   55 #else
   56 #define DPRINTF(p...)           /* p */
   57 #define DNPRINTF(n, p...)       /* n, p */
   58 #endif
   59 
   60 static const struct pci_matchid arc_devices[] = {
   61         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1110 },
   62         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1120 },
   63         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1130 },
   64         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1160 },
   65         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1170 },
   66         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1210 },
   67         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1220 },
   68         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1230 },
   69         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1260 },
   70         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1270 },
   71         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1280 },
   72         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1380 },
   73         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1381 },
   74         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1680 },
   75         { PCI_VENDOR_ARECA,     PCI_PRODUCT_ARECA_ARC1681 }
   76 };
   77 
   78 #define ARC_PCI_BAR                     PCI_MAPREG_START
   79 
   80 #define ARC_REG_INB_MSG0                0x0010
   81 #define  ARC_REG_INB_MSG0_NOP                   (0x00000000)
   82 #define  ARC_REG_INB_MSG0_GET_CONFIG            (0x00000001)
   83 #define  ARC_REG_INB_MSG0_SET_CONFIG            (0x00000002)
   84 #define  ARC_REG_INB_MSG0_ABORT_CMD             (0x00000003)
   85 #define  ARC_REG_INB_MSG0_STOP_BGRB             (0x00000004)
   86 #define  ARC_REG_INB_MSG0_FLUSH_CACHE           (0x00000005)
   87 #define  ARC_REG_INB_MSG0_START_BGRB            (0x00000006)
   88 #define  ARC_REG_INB_MSG0_CHK331PENDING         (0x00000007)
   89 #define  ARC_REG_INB_MSG0_SYNC_TIMER            (0x00000008)
   90 #define ARC_REG_INB_MSG1                0x0014
   91 #define ARC_REG_OUTB_ADDR0              0x0018
   92 #define ARC_REG_OUTB_ADDR1              0x001c
   93 #define  ARC_REG_OUTB_ADDR1_FIRMWARE_OK         (1<<31)
   94 #define ARC_REG_INB_DOORBELL            0x0020
   95 #define  ARC_REG_INB_DOORBELL_WRITE_OK          (1<<0)
   96 #define  ARC_REG_INB_DOORBELL_READ_OK           (1<<1)
   97 #define ARC_REG_OUTB_DOORBELL           0x002c
   98 #define  ARC_REG_OUTB_DOORBELL_WRITE_OK         (1<<0)
   99 #define  ARC_REG_OUTB_DOORBELL_READ_OK          (1<<1)
  100 #define ARC_REG_INTRSTAT                0x0030
  101 #define  ARC_REG_INTRSTAT_MSG0                  (1<<0)
  102 #define  ARC_REG_INTRSTAT_MSG1                  (1<<1)
  103 #define  ARC_REG_INTRSTAT_DOORBELL              (1<<2)
  104 #define  ARC_REG_INTRSTAT_POSTQUEUE             (1<<3)
  105 #define  ARC_REG_INTRSTAT_PCI                   (1<<4)
  106 #define ARC_REG_INTRMASK                0x0034
  107 #define  ARC_REG_INTRMASK_MSG0                  (1<<0)
  108 #define  ARC_REG_INTRMASK_MSG1                  (1<<1)
  109 #define  ARC_REG_INTRMASK_DOORBELL              (1<<2)
  110 #define  ARC_REG_INTRMASK_POSTQUEUE             (1<<3)
  111 #define  ARC_REG_INTRMASK_PCI                   (1<<4)
  112 #define ARC_REG_POST_QUEUE              0x0040
  113 #define  ARC_REG_POST_QUEUE_ADDR_SHIFT          5
  114 #define  ARC_REG_POST_QUEUE_IAMBIOS             (1<<30)
  115 #define  ARC_REG_POST_QUEUE_BIGFRAME            (1<<31)
  116 #define ARC_REG_REPLY_QUEUE             0x0044
  117 #define  ARC_REG_REPLY_QUEUE_ADDR_SHIFT         5
  118 #define  ARC_REG_REPLY_QUEUE_ERR                (1<<28)
  119 #define  ARC_REG_REPLY_QUEUE_IAMBIOS            (1<<30)
  120 #define ARC_REG_MSGBUF                  0x0a00
  121 #define  ARC_REG_MSGBUF_LEN             1024
  122 #define ARC_REG_IOC_WBUF_LEN            0x0e00
  123 #define ARC_REG_IOC_WBUF                0x0e04
  124 #define ARC_REG_IOC_RBUF_LEN            0x0f00
  125 #define ARC_REG_IOC_RBUF                0x0f04
  126 #define  ARC_REG_IOC_RWBUF_MAXLEN       124 /* for both RBUF and WBUF */
  127 
  128 struct arc_msg_firmware_info {
  129         u_int32_t               signature;
  130 #define ARC_FWINFO_SIGNATURE_GET_CONFIG         (0x87974060)
  131         u_int32_t               request_len;
  132         u_int32_t               queue_len;
  133         u_int32_t               sdram_size;
  134         u_int32_t               sata_ports;
  135         u_int8_t                vendor[40];
  136         u_int8_t                model[8];
  137         u_int8_t                fw_version[16];
  138         u_int8_t                device_map[16];
  139 } __packed;
  140 
  141 struct arc_msg_scsicmd {
  142         u_int8_t                bus;
  143         u_int8_t                target;
  144         u_int8_t                lun;
  145         u_int8_t                function;
  146 
  147         u_int8_t                cdb_len;
  148         u_int8_t                sgl_len;
  149         u_int8_t                flags;
  150 #define ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512      (1<<0)
  151 #define ARC_MSG_SCSICMD_FLAG_FROM_BIOS          (1<<1)
  152 #define ARC_MSG_SCSICMD_FLAG_WRITE              (1<<2)
  153 #define ARC_MSG_SCSICMD_FLAG_SIMPLEQ            (0x00)
  154 #define ARC_MSG_SCSICMD_FLAG_HEADQ              (0x08)
  155 #define ARC_MSG_SCSICMD_FLAG_ORDERQ             (0x10)
  156         u_int8_t                reserved;
  157 
  158         u_int32_t               context;
  159         u_int32_t               data_len;
  160 
  161 #define ARC_MSG_CDBLEN                          16
  162         u_int8_t                cdb[ARC_MSG_CDBLEN];
  163 
  164         u_int8_t                status;
  165 #define ARC_MSG_STATUS_SELTIMEOUT               0xf0
  166 #define ARC_MSG_STATUS_ABORTED                  0xf1
  167 #define ARC_MSG_STATUS_INIT_FAIL                0xf2
  168 #define ARC_MSG_SENSELEN                        15
  169         u_int8_t                sense_data[ARC_MSG_SENSELEN];
  170 
  171         /* followed by an sgl */
  172 } __packed;
  173 
  174 struct arc_sge {
  175         u_int32_t               sg_hdr;
  176 #define ARC_SGE_64BIT                           (1<<24)
  177         u_int32_t               sg_lo_addr;
  178         u_int32_t               sg_hi_addr;
  179 } __packed;
  180 
  181 #define ARC_MAX_TARGET          16
  182 #define ARC_MAX_LUN             8
  183 #define ARC_MAX_IOCMDLEN        512
  184 #define ARC_BLOCKSIZE           512
  185 
  186 /* the firmware deals with up to 256 or 512 byte command frames. */
  187 /* sizeof(struct arc_msg_scsicmd) + (sizeof(struct arc_sge) * 38) == 508 */
  188 #define ARC_SGL_MAXLEN          38
  189 /* sizeof(struct arc_msg_scsicmd) + (sizeof(struct arc_sge) * 17) == 252 */
  190 #define ARC_SGL_256LEN          17
  191 
  192 struct arc_io_cmd {
  193         struct arc_msg_scsicmd  cmd;
  194         struct arc_sge          sgl[ARC_SGL_MAXLEN];
  195 } __packed;
  196 
  197 /* definitions of the firmware commands sent via the doorbells */
  198 
  199 struct arc_fw_hdr {
  200         u_int8_t                byte1;
  201         u_int8_t                byte2;
  202         u_int8_t                byte3;
  203 } __packed;
  204 
  205 /* the fw header must always equal this */
  206 struct arc_fw_hdr arc_fw_hdr = { 0x5e, 0x01, 0x61 };
  207 
  208 struct arc_fw_bufhdr {
  209         struct arc_fw_hdr       hdr;
  210         u_int16_t               len;
  211 } __packed;
  212 
  213 #define ARC_FW_RAIDINFO         0x20    /* opcode + raid# */
  214 #define ARC_FW_VOLINFO          0x21    /* opcode + vol# */
  215 #define ARC_FW_DISKINFO         0x22    /* opcode + physdisk# */
  216 #define ARC_FW_SYSINFO          0x23    /* opcode. reply is fw_sysinfo */
  217 #define ARC_FW_MUTE_ALARM       0x30    /* opcode only */
  218 #define ARC_FW_SET_ALARM        0x31    /* opcode + 1 byte for setting */
  219 #define  ARC_FW_SET_ALARM_DISABLE               0x00
  220 #define  ARC_FW_SET_ALARM_ENABLE                0x01
  221 #define ARC_FW_NOP              0x38    /* opcode only */
  222 
  223 #define ARC_FW_CMD_OK           0x41
  224 
  225 struct arc_fw_comminfo {
  226         u_int8_t                baud_rate;
  227         u_int8_t                data_bits;
  228         u_int8_t                stop_bits;
  229         u_int8_t                parity;
  230         u_int8_t                flow_control;
  231 } __packed;
  232 
  233 struct arc_fw_scsiattr {
  234         u_int8_t                channel;// channel for SCSI target (0/1)
  235         u_int8_t                target;
  236         u_int8_t                lun;
  237         u_int8_t                tagged;
  238         u_int8_t                cache;
  239         u_int8_t                speed;
  240 } __packed;
  241 
  242 struct arc_fw_raidinfo {
  243         u_int8_t                set_name[16];
  244         u_int32_t               capacity;
  245         u_int32_t               capacity2;
  246         u_int32_t               fail_mask;
  247         u_int8_t                device_array[32];
  248         u_int8_t                member_devices;
  249         u_int8_t                new_member_devices;
  250         u_int8_t                raid_state;
  251         u_int8_t                volumes;
  252         u_int8_t                volume_list[16];
  253         u_int8_t                reserved1[3];
  254         u_int8_t                free_segments;
  255         u_int32_t               raw_stripes[8];
  256         u_int8_t                reserved2[12];
  257 } __packed;
  258 
  259 struct arc_fw_volinfo {
  260         u_int8_t                set_name[16];
  261         u_int32_t               capacity;
  262         u_int32_t               capacity2;
  263         u_int32_t               fail_mask;
  264         u_int32_t               stripe_size; /* in blocks */
  265         u_int32_t               new_fail_mask;
  266         u_int32_t               new_stripe_size;
  267         u_int32_t               volume_status;
  268 #define ARC_FW_VOL_STATUS_NORMAL        0x00
  269 #define ARC_FW_VOL_STATUS_INITTING      (1<<0)
  270 #define ARC_FW_VOL_STATUS_FAILED        (1<<1)
  271 #define ARC_FW_VOL_STATUS_MIGRATING     (1<<2)
  272 #define ARC_FW_VOL_STATUS_REBUILDING    (1<<3)
  273 #define ARC_FW_VOL_STATUS_NEED_INIT     (1<<4)
  274 #define ARC_FW_VOL_STATUS_NEED_MIGRATE  (1<<5)
  275 #define ARC_FW_VOL_STATUS_INIT_FLAG     (1<<6)
  276 #define ARC_FW_VOL_STATUS_NEED_REGEN    (1<<7)
  277 #define ARC_FW_VOL_STATUS_CHECKING      (1<<8)
  278 #define ARC_FW_VOL_STATUS_NEED_CHECK    (1<<9)
  279         u_int32_t               progress;
  280         struct arc_fw_scsiattr  scsi_attr;
  281         u_int8_t                member_disks;
  282         u_int8_t                raid_level;
  283 #define ARC_FW_VOL_RAIDLEVEL_0          0x00
  284 #define ARC_FW_VOL_RAIDLEVEL_1          0x01
  285 #define ARC_FW_VOL_RAIDLEVEL_3          0x02
  286 #define ARC_FW_VOL_RAIDLEVEL_5          0x03
  287 #define ARC_FW_VOL_RAIDLEVEL_6          0x04
  288 #define ARC_FW_VOL_RAIDLEVEL_PASSTHRU   0x05
  289         u_int8_t                new_member_disks;
  290         u_int8_t                new_raid_level;
  291         u_int8_t                raid_set_number;
  292         u_int8_t                reserved[5];
  293 } __packed;
  294 
  295 struct arc_fw_diskinfo {
  296         u_int8_t                model[40];
  297         u_int8_t                serial[20];
  298         u_int8_t                firmware_rev[8];
  299         u_int32_t               capacity;
  300         u_int32_t               capacity2;
  301         u_int8_t                device_state;
  302         u_int8_t                pio_mode;
  303         u_int8_t                current_udma_mode;
  304         u_int8_t                udma_mode;
  305         u_int8_t                drive_select;
  306         u_int8_t                raid_number; // 0xff unowned
  307         struct arc_fw_scsiattr  scsi_attr;
  308         u_int8_t                reserved[40];
  309 } __packed;
  310 
  311 struct arc_fw_sysinfo {
  312         u_int8_t                vendor_name[40];
  313         u_int8_t                serial_number[16];
  314         u_int8_t                firmware_version[16];
  315         u_int8_t                boot_version[16];
  316         u_int8_t                mb_version[16];
  317         u_int8_t                model_name[8];
  318 
  319         u_int8_t                local_ip[4];
  320         u_int8_t                current_ip[4];
  321 
  322         u_int32_t               time_tick;
  323         u_int32_t               cpu_speed;
  324         u_int32_t               icache;
  325         u_int32_t               dcache;
  326         u_int32_t               scache;
  327         u_int32_t               memory_size;
  328         u_int32_t               memory_speed;
  329         u_int32_t               events;
  330 
  331         u_int8_t                gsiMacAddress[6];
  332         u_int8_t                gsiDhcp;
  333 
  334         u_int8_t                alarm;
  335         u_int8_t                channel_usage;
  336         u_int8_t                max_ata_mode;
  337         u_int8_t                sdram_ecc;
  338         u_int8_t                rebuild_priority;
  339         struct arc_fw_comminfo  comm_a;
  340         struct arc_fw_comminfo  comm_b;
  341         u_int8_t                ide_channels;
  342         u_int8_t                scsi_host_channels;
  343         u_int8_t                ide_host_channels;
  344         u_int8_t                max_volume_set;
  345         u_int8_t                max_raid_set;
  346         u_int8_t                ether_port;
  347         u_int8_t                raid6_engine;
  348         u_int8_t                reserved[75];
  349 } __packed;
  350 
  351 int                     arc_match(struct device *, void *, void *);
  352 void                    arc_attach(struct device *, struct device *, void *);
  353 int                     arc_detach(struct device *, int);
  354 void                    arc_shutdown(void *);
  355 int                     arc_intr(void *);
  356 
  357 struct arc_ccb;
  358 TAILQ_HEAD(arc_ccb_list, arc_ccb);
  359 
  360 struct arc_softc {
  361         struct device           sc_dev;
  362         struct scsi_link        sc_link;
  363 
  364         pci_chipset_tag_t       sc_pc;
  365         pcitag_t                sc_tag;
  366 
  367         bus_space_tag_t         sc_iot;
  368         bus_space_handle_t      sc_ioh;
  369         bus_size_t              sc_ios;
  370         bus_dma_tag_t           sc_dmat;
  371 
  372         void                    *sc_ih;
  373 
  374         void                    *sc_shutdownhook;
  375 
  376         int                     sc_req_count;
  377 
  378         struct arc_dmamem       *sc_requests;
  379         struct arc_ccb          *sc_ccbs;
  380         struct arc_ccb_list     sc_ccb_free;
  381 
  382         struct scsibus_softc    *sc_scsibus;
  383 
  384         struct rwlock           sc_lock;
  385         volatile int            sc_talking;
  386 
  387         struct ksensor          *sc_sensors;
  388         struct ksensordev       sc_sensordev;
  389         int                     sc_nsensors;
  390 };
  391 #define DEVNAME(_s)             ((_s)->sc_dev.dv_xname)
  392 
  393 struct cfattach arc_ca = {
  394         sizeof(struct arc_softc), arc_match, arc_attach, arc_detach
  395 };
  396 
  397 struct cfdriver arc_cd = {
  398         NULL, "arc", DV_DULL
  399 };
  400 
  401 /* interface for scsi midlayer to talk to */
  402 int                     arc_scsi_cmd(struct scsi_xfer *);
  403 void                    arc_minphys(struct buf *);
  404 
  405 struct scsi_adapter arc_switch = {
  406         arc_scsi_cmd, arc_minphys, NULL, NULL, NULL
  407 };
  408 
  409 struct scsi_device arc_dev = {
  410         NULL, NULL, NULL, NULL
  411 };
  412 
  413 /* code to deal with getting bits in and out of the bus space */
  414 u_int32_t               arc_read(struct arc_softc *, bus_size_t);
  415 void                    arc_read_region(struct arc_softc *, bus_size_t,
  416                             void *, size_t);
  417 void                    arc_write(struct arc_softc *, bus_size_t, u_int32_t);
  418 void                    arc_write_region(struct arc_softc *, bus_size_t,
  419                             void *, size_t);
  420 int                     arc_wait_eq(struct arc_softc *, bus_size_t,
  421                             u_int32_t, u_int32_t);
  422 int                     arc_wait_ne(struct arc_softc *, bus_size_t,
  423                             u_int32_t, u_int32_t);
  424 int                     arc_msg0(struct arc_softc *, u_int32_t);
  425 
  426 #define arc_push(_s, _r)        arc_write((_s), ARC_REG_POST_QUEUE, (_r))
  427 #define arc_pop(_s)             arc_read((_s), ARC_REG_REPLY_QUEUE)
  428 
  429 /* wrap up the bus_dma api */
  430 struct arc_dmamem {
  431         bus_dmamap_t            adm_map;
  432         bus_dma_segment_t       adm_seg;
  433         size_t                  adm_size;
  434         caddr_t                 adm_kva;
  435 };
  436 #define ARC_DMA_MAP(_adm)       ((_adm)->adm_map)
  437 #define ARC_DMA_DVA(_adm)       ((_adm)->adm_map->dm_segs[0].ds_addr)
  438 #define ARC_DMA_KVA(_adm)       ((void *)(_adm)->adm_kva)
  439 
  440 struct arc_dmamem       *arc_dmamem_alloc(struct arc_softc *, size_t);
  441 void                    arc_dmamem_free(struct arc_softc *,
  442                             struct arc_dmamem *);
  443 
  444 /* stuff to manage a scsi command */
  445 struct arc_ccb {
  446         struct arc_softc        *ccb_sc;
  447         int                     ccb_id;
  448 
  449         struct scsi_xfer        *ccb_xs;
  450 
  451         bus_dmamap_t            ccb_dmamap;
  452         bus_addr_t              ccb_offset;
  453         struct arc_io_cmd       *ccb_cmd;
  454         u_int32_t               ccb_cmd_post;
  455 
  456         TAILQ_ENTRY(arc_ccb)    ccb_link;
  457 };
  458 
  459 int                     arc_alloc_ccbs(struct arc_softc *);
  460 struct arc_ccb          *arc_get_ccb(struct arc_softc *);
  461 void                    arc_put_ccb(struct arc_softc *, struct arc_ccb *);
  462 int                     arc_load_xs(struct arc_ccb *);
  463 int                     arc_complete(struct arc_softc *, struct arc_ccb *,
  464                             int);
  465 void                    arc_scsi_cmd_done(struct arc_softc *, struct arc_ccb *,
  466                             u_int32_t);
  467 
  468 /* real stuff for dealing with the hardware */
  469 int                     arc_map_pci_resources(struct arc_softc *,
  470                             struct pci_attach_args *);
  471 int                     arc_query_firmware(struct arc_softc *);
  472 
  473 
  474 #if NBIO > 0
  475 /* stuff to do messaging via the doorbells */
  476 void                    arc_lock(struct arc_softc *);
  477 void                    arc_unlock(struct arc_softc *);
  478 void                    arc_wait(struct arc_softc *);
  479 u_int8_t                arc_msg_cksum(void *, u_int16_t);
  480 int                     arc_msgbuf(struct arc_softc *, void *, size_t,
  481                             void *, size_t);
  482 
  483 /* bioctl */
  484 int                     arc_bioctl(struct device *, u_long, caddr_t);
  485 int                     arc_bio_inq(struct arc_softc *, struct bioc_inq *);
  486 int                     arc_bio_vol(struct arc_softc *, struct bioc_vol *);
  487 int                     arc_bio_disk(struct arc_softc *, struct bioc_disk *);
  488 int                     arc_bio_alarm(struct arc_softc *, struct bioc_alarm *);
  489 int                     arc_bio_alarm_state(struct arc_softc *,
  490                             struct bioc_alarm *);
  491 
  492 int                     arc_bio_getvol(struct arc_softc *, int,
  493                             struct arc_fw_volinfo *);
  494 
  495 #ifndef SMALL_KERNEL
  496 /* sensors */
  497 void                    arc_create_sensors(void *, void *);
  498 void                    arc_refresh_sensors(void *);
  499 #endif /* SMALL_KERNEL */
  500 #endif
  501 
  502 int
  503 arc_match(struct device *parent, void *match, void *aux)
  504 {
  505         return (pci_matchbyid((struct pci_attach_args *)aux, arc_devices,
  506             sizeof(arc_devices) / sizeof(arc_devices[0])));
  507 }
  508 
  509 void
  510 arc_attach(struct device *parent, struct device *self, void *aux)
  511 {
  512         struct arc_softc                *sc = (struct arc_softc *)self;
  513         struct pci_attach_args          *pa = aux;
  514         struct scsibus_attach_args      saa;
  515         struct device                   *child;
  516 
  517         sc->sc_talking = 0;
  518         rw_init(&sc->sc_lock, "arcmsg");
  519 
  520         if (arc_map_pci_resources(sc, pa) != 0) {
  521                 /* error message printed by arc_map_pci_resources */
  522                 return;
  523         }
  524 
  525         if (arc_query_firmware(sc) != 0) {
  526                 /* error message printed by arc_query_firmware */
  527                 return;
  528         }
  529 
  530         if (arc_alloc_ccbs(sc) != 0) {
  531                 /* error message printed by arc_alloc_ccbs */
  532                 return;
  533         }
  534 
  535         sc->sc_shutdownhook = shutdownhook_establish(arc_shutdown, sc);
  536         if (sc->sc_shutdownhook == NULL)
  537                 panic("unable to establish arc powerhook");
  538 
  539         sc->sc_link.device = &arc_dev;
  540         sc->sc_link.adapter = &arc_switch;
  541         sc->sc_link.adapter_softc = sc;
  542         sc->sc_link.adapter_target = ARC_MAX_TARGET;
  543         sc->sc_link.adapter_buswidth = ARC_MAX_TARGET;
  544         sc->sc_link.openings = sc->sc_req_count / ARC_MAX_TARGET;
  545 
  546         bzero(&saa, sizeof(saa));
  547         saa.saa_sc_link = &sc->sc_link;
  548 
  549         child = config_found(self, &saa, scsiprint);
  550         sc->sc_scsibus = (struct scsibus_softc *)child;
  551 
  552         /* enable interrupts */
  553         arc_write(sc, ARC_REG_INTRMASK,
  554             ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRSTAT_DOORBELL));
  555 
  556 #if NBIO > 0
  557         if (bio_register(self, arc_bioctl) != 0)
  558                 panic("%s: bioctl registration failed\n", DEVNAME(sc));
  559 
  560 #ifndef SMALL_KERNEL
  561         /*
  562          * you need to talk to the firmware to get volume info. our firmware
  563          * interface relies on being able to sleep, so we need to use a thread
  564          * to do the work.
  565          */
  566         if (scsi_task(arc_create_sensors, sc, NULL, 1) != 0)
  567                 printf("%s: unable to schedule arc_create_sensors as a "
  568                     "scsi task", DEVNAME(sc));
  569 #endif
  570 #endif
  571 
  572         return;
  573 }
  574 
  575 int
  576 arc_detach(struct device *self, int flags)
  577 {
  578         struct arc_softc                *sc = (struct arc_softc *)self;
  579 
  580         shutdownhook_disestablish(sc->sc_shutdownhook);
  581 
  582         if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0)
  583                 printf("%s: timeout waiting to stop bg rebuild\n", DEVNAME(sc));
  584 
  585         if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0)
  586                 printf("%s: timeout waiting to flush cache\n", DEVNAME(sc));
  587 
  588         return (0);
  589 }
  590 
  591 void
  592 arc_shutdown(void *xsc)
  593 {
  594         struct arc_softc                *sc = xsc;
  595 
  596         if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0)
  597                 printf("%s: timeout waiting to stop bg rebuild\n", DEVNAME(sc));
  598 
  599         if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0)
  600                 printf("%s: timeout waiting to flush cache\n", DEVNAME(sc));
  601 }
  602 
  603 int
  604 arc_intr(void *arg)
  605 {
  606         struct arc_softc                *sc = arg;
  607         struct arc_ccb                  *ccb = NULL;
  608         char                            *kva = ARC_DMA_KVA(sc->sc_requests);
  609         struct arc_io_cmd               *cmd;
  610         u_int32_t                       reg, intrstat;
  611 
  612         intrstat = arc_read(sc, ARC_REG_INTRSTAT);
  613         if (intrstat == 0x0)
  614                 return (0);
  615         intrstat &= ARC_REG_INTRSTAT_POSTQUEUE | ARC_REG_INTRSTAT_DOORBELL;
  616         arc_write(sc, ARC_REG_INTRSTAT, intrstat);
  617 
  618         if (intrstat & ARC_REG_INTRSTAT_DOORBELL) {
  619                 if (sc->sc_talking) {
  620                         /* if an ioctl is talking, wake it up */
  621                         arc_write(sc, ARC_REG_INTRMASK,
  622                             ~ARC_REG_INTRMASK_POSTQUEUE);
  623                         wakeup(sc);
  624                 } else {
  625                         /* otherwise drop it */
  626                         reg = arc_read(sc, ARC_REG_OUTB_DOORBELL);
  627                         arc_write(sc, ARC_REG_OUTB_DOORBELL, reg);
  628                         if (reg & ARC_REG_OUTB_DOORBELL_WRITE_OK)
  629                                 arc_write(sc, ARC_REG_INB_DOORBELL,
  630                                     ARC_REG_INB_DOORBELL_READ_OK);
  631                 }
  632         }
  633 
  634         while ((reg = arc_pop(sc)) != 0xffffffff) {
  635                 cmd = (struct arc_io_cmd *)(kva +
  636                     ((reg << ARC_REG_REPLY_QUEUE_ADDR_SHIFT) -
  637                     (u_int32_t)ARC_DMA_DVA(sc->sc_requests)));
  638                 ccb = &sc->sc_ccbs[letoh32(cmd->cmd.context)];
  639 
  640                 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
  641                     ccb->ccb_offset, ARC_MAX_IOCMDLEN,
  642                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  643 
  644                 arc_scsi_cmd_done(sc, ccb, reg);
  645         }
  646 
  647         return (1);
  648 }
  649 
  650 int
  651 arc_scsi_cmd(struct scsi_xfer *xs)
  652 {
  653         struct scsi_link                *link = xs->sc_link;
  654         struct arc_softc                *sc = link->adapter_softc;
  655         struct arc_ccb                  *ccb;
  656         struct arc_msg_scsicmd          *cmd;
  657         u_int32_t                       reg;
  658         int                             rv = SUCCESSFULLY_QUEUED;
  659         int                             s;
  660 
  661         if (xs->cmdlen > ARC_MSG_CDBLEN) {
  662                 bzero(&xs->sense, sizeof(xs->sense));
  663                 xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
  664                 xs->sense.flags = SKEY_ILLEGAL_REQUEST;
  665                 xs->sense.add_sense_code = 0x20;
  666                 xs->error = XS_SENSE;
  667                 s = splbio();
  668                 scsi_done(xs);
  669                 splx(s);
  670                 return (COMPLETE);
  671         }
  672 
  673         s = splbio();
  674         ccb = arc_get_ccb(sc);
  675         splx(s);
  676         if (ccb == NULL) {
  677                 xs->error = XS_DRIVER_STUFFUP;
  678                 s = splbio();
  679                 scsi_done(xs);
  680                 splx(s);
  681                 return (COMPLETE);
  682         }
  683 
  684         ccb->ccb_xs = xs;
  685 
  686         if (arc_load_xs(ccb) != 0) {
  687                 xs->error = XS_DRIVER_STUFFUP;
  688                 s = splbio();
  689                 arc_put_ccb(sc, ccb);
  690                 scsi_done(xs);
  691                 splx(s);
  692                 return (COMPLETE);
  693         }
  694 
  695         cmd = &ccb->ccb_cmd->cmd;
  696         reg = ccb->ccb_cmd_post;
  697 
  698         /* bus is always 0 */
  699         cmd->target = link->target;
  700         cmd->lun = link->lun;
  701         cmd->function = 1; /* XXX magic number */
  702 
  703         cmd->cdb_len = xs->cmdlen;
  704         cmd->sgl_len = ccb->ccb_dmamap->dm_nsegs;
  705         if (xs->flags & SCSI_DATA_OUT)
  706                 cmd->flags = ARC_MSG_SCSICMD_FLAG_WRITE;
  707         if (ccb->ccb_dmamap->dm_nsegs > ARC_SGL_256LEN) {
  708                 cmd->flags |= ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512;
  709                 reg |= ARC_REG_POST_QUEUE_BIGFRAME;
  710         }
  711 
  712         cmd->context = htole32(ccb->ccb_id);
  713         cmd->data_len = htole32(xs->datalen);
  714 
  715         bcopy(xs->cmd, cmd->cdb, xs->cmdlen);
  716 
  717         /* we've built the command, let's put it on the hw */
  718         bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
  719             ccb->ccb_offset, ARC_MAX_IOCMDLEN,
  720             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  721 
  722         s = splbio();
  723         arc_push(sc, reg);
  724         if (xs->flags & SCSI_POLL) {
  725                 rv = COMPLETE;
  726                 if (arc_complete(sc, ccb, xs->timeout) != 0) {
  727                         xs->error = XS_DRIVER_STUFFUP;
  728                         scsi_done(xs);
  729                 }
  730         }
  731         splx(s);
  732 
  733         return (rv);
  734 }
  735 
  736 int
  737 arc_load_xs(struct arc_ccb *ccb)
  738 {
  739         struct arc_softc                *sc = ccb->ccb_sc;
  740         struct scsi_xfer                *xs = ccb->ccb_xs;
  741         bus_dmamap_t                    dmap = ccb->ccb_dmamap;
  742         struct arc_sge                  *sgl = ccb->ccb_cmd->sgl, *sge;
  743         u_int64_t                       addr;
  744         int                             i, error;
  745 
  746         if (xs->datalen == 0)
  747                 return (0);
  748 
  749         error = bus_dmamap_load(sc->sc_dmat, dmap,
  750             xs->data, xs->datalen, NULL,
  751             (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
  752         if (error != 0) {
  753                 printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
  754                 return (1);
  755         }
  756 
  757         for (i = 0; i < dmap->dm_nsegs; i++) {
  758                 sge = &sgl[i];
  759 
  760                 sge->sg_hdr = htole32(ARC_SGE_64BIT | dmap->dm_segs[i].ds_len);
  761                 addr = dmap->dm_segs[i].ds_addr;
  762                 sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32));
  763                 sge->sg_lo_addr = htole32((u_int32_t)addr);
  764         }
  765 
  766         bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
  767             (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
  768             BUS_DMASYNC_PREWRITE);
  769 
  770         return (0);
  771 }
  772 
  773 void
  774 arc_scsi_cmd_done(struct arc_softc *sc, struct arc_ccb *ccb, u_int32_t reg)
  775 {
  776         struct scsi_xfer                *xs = ccb->ccb_xs;
  777         struct arc_msg_scsicmd          *cmd;
  778 
  779         if (xs->datalen != 0) {
  780                 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
  781                     ccb->ccb_dmamap->dm_mapsize, (xs->flags & SCSI_DATA_IN) ?
  782                     BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
  783                 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
  784         }
  785 
  786         /* timeout_del */
  787         xs->flags |= ITSDONE;
  788 
  789         if (reg & ARC_REG_REPLY_QUEUE_ERR) {
  790                 cmd = &ccb->ccb_cmd->cmd;
  791 
  792                 switch (cmd->status) {
  793                 case ARC_MSG_STATUS_SELTIMEOUT:
  794                 case ARC_MSG_STATUS_ABORTED:
  795                 case ARC_MSG_STATUS_INIT_FAIL:
  796                         xs->status = SCSI_OK;
  797                         xs->error = XS_SELTIMEOUT;
  798                         break;
  799 
  800                 case SCSI_CHECK:
  801                         bzero(&xs->sense, sizeof(xs->sense));
  802                         bcopy(cmd->sense_data, &xs->sense,
  803                             min(ARC_MSG_SENSELEN, sizeof(xs->sense)));
  804                         xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
  805                         xs->status = SCSI_CHECK;
  806                         xs->error = XS_SENSE;
  807                         xs->resid = 0;
  808                         break;
  809 
  810                 default:
  811                         /* unknown device status */
  812                         xs->error = XS_BUSY; /* try again later? */
  813                         xs->status = SCSI_BUSY;
  814                         break;
  815                 }
  816         } else {
  817                 xs->status = SCSI_OK;
  818                 xs->error = XS_NOERROR;
  819                 xs->resid = 0;
  820         }
  821 
  822         arc_put_ccb(sc, ccb);
  823         scsi_done(xs);
  824 }
  825 
  826 int
  827 arc_complete(struct arc_softc *sc, struct arc_ccb *nccb, int timeout)
  828 {
  829         struct arc_ccb                  *ccb = NULL;
  830         char                            *kva = ARC_DMA_KVA(sc->sc_requests);
  831         struct arc_io_cmd               *cmd;
  832         u_int32_t                       reg;
  833 
  834         do {
  835                 reg = arc_pop(sc);
  836                 if (reg == 0xffffffff) {
  837                         if (timeout-- == 0)
  838                                 return (1);
  839 
  840                         delay(1000);
  841                         continue;
  842                 }
  843 
  844                 cmd = (struct arc_io_cmd *)(kva +
  845                     ((reg << ARC_REG_REPLY_QUEUE_ADDR_SHIFT) -
  846                     ARC_DMA_DVA(sc->sc_requests)));
  847                 ccb = &sc->sc_ccbs[letoh32(cmd->cmd.context)];
  848 
  849                 bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests),
  850                     ccb->ccb_offset, ARC_MAX_IOCMDLEN,
  851                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  852 
  853                 arc_scsi_cmd_done(sc, ccb, reg);
  854         } while (nccb != ccb);
  855 
  856         return (0);
  857 }
  858 
  859 void
  860 arc_minphys(struct buf *bp)
  861 {
  862         if (bp->b_bcount > MAXPHYS)
  863                 bp->b_bcount = MAXPHYS;
  864         minphys(bp);
  865 }
  866 
  867 int
  868 arc_map_pci_resources(struct arc_softc *sc, struct pci_attach_args *pa)
  869 {
  870         pcireg_t                        memtype;
  871         pci_intr_handle_t               ih;
  872         const char                      *intrstr;
  873 
  874         sc->sc_pc = pa->pa_pc;
  875         sc->sc_tag = pa->pa_tag;
  876         sc->sc_dmat = pa->pa_dmat;
  877 
  878         memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_PCI_BAR);
  879         if (pci_mapreg_map(pa, ARC_PCI_BAR, memtype, 0, &sc->sc_iot,
  880             &sc->sc_ioh, NULL, &sc->sc_ios, 0) != 0) {
  881                 printf(": unable to map system interface register\n");
  882                 return(1);
  883         }
  884 
  885         if (pci_intr_map(pa, &ih) != 0) {
  886                 printf(": unable to map interrupt\n");
  887                 goto unmap;
  888         }
  889         intrstr = pci_intr_string(pa->pa_pc, ih);
  890         sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
  891             arc_intr, sc, DEVNAME(sc));
  892         if (sc->sc_ih == NULL) {
  893                 printf(": unable to map interrupt%s%s\n",
  894                     intrstr == NULL ? "" : " at ",
  895                     intrstr == NULL ? "" : intrstr);
  896                 goto unmap;
  897         }
  898         printf(": %s\n", intrstr);
  899 
  900         return (0);
  901 
  902 unmap:
  903         bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
  904         sc->sc_ios = 0;
  905         return (1);
  906 }
  907 
  908 int
  909 arc_query_firmware(struct arc_softc *sc)
  910 {
  911         struct arc_msg_firmware_info    fwinfo;
  912         char                            string[81]; /* sizeof(vendor)*2+1 */
  913 
  914         if (arc_wait_eq(sc, ARC_REG_OUTB_ADDR1, ARC_REG_OUTB_ADDR1_FIRMWARE_OK,
  915             ARC_REG_OUTB_ADDR1_FIRMWARE_OK) != 0) {
  916                 printf("%s: timeout waiting for firmware ok\n", DEVNAME(sc));
  917                 return (1);
  918         }
  919 
  920         if (arc_msg0(sc, ARC_REG_INB_MSG0_GET_CONFIG) != 0) {
  921                 printf("%s: timeout waiting for get config\n", DEVNAME(sc));
  922                 return (1);
  923         }
  924 
  925         arc_read_region(sc, ARC_REG_MSGBUF, &fwinfo, sizeof(fwinfo));
  926 
  927         DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n", DEVNAME(sc),
  928             letoh32(fwinfo.signature));
  929 
  930         if (letoh32(fwinfo.signature) != ARC_FWINFO_SIGNATURE_GET_CONFIG) {
  931                 printf("%s: invalid firmware info from iop\n", DEVNAME(sc));
  932                 return (1);
  933         }
  934 
  935         DNPRINTF(ARC_D_INIT, "%s: request_len: %d\n", DEVNAME(sc),
  936             letoh32(fwinfo.request_len));
  937         DNPRINTF(ARC_D_INIT, "%s: queue_len: %d\n", DEVNAME(sc),
  938             letoh32(fwinfo.queue_len));
  939         DNPRINTF(ARC_D_INIT, "%s: sdram_size: %d\n", DEVNAME(sc),
  940             letoh32(fwinfo.sdram_size));
  941         DNPRINTF(ARC_D_INIT, "%s: sata_ports: %d\n", DEVNAME(sc),
  942             letoh32(fwinfo.sata_ports), letoh32(fwinfo.sata_ports));
  943 
  944 #ifdef ARC_DEBUG
  945         scsi_strvis(string, fwinfo.vendor, sizeof(fwinfo.vendor));
  946         DNPRINTF(ARC_D_INIT, "%s: vendor: \"%s\"\n", DEVNAME(sc), string);
  947         scsi_strvis(string, fwinfo.model, sizeof(fwinfo.model));
  948         DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
  949 #endif /* ARC_DEBUG */
  950 
  951         scsi_strvis(string, fwinfo.fw_version, sizeof(fwinfo.fw_version));
  952         DNPRINTF(ARC_D_INIT, "%s: model: \"%s\"\n", DEVNAME(sc), string);
  953 
  954         if (letoh32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) {
  955                 printf("%s: unexpected request frame size (%d != %d)\n",
  956                     DEVNAME(sc), letoh32(fwinfo.request_len), ARC_MAX_IOCMDLEN);
  957                 return (1);
  958         }
  959 
  960         sc->sc_req_count = letoh32(fwinfo.queue_len);
  961 
  962         if (arc_msg0(sc, ARC_REG_INB_MSG0_START_BGRB) != 0) {
  963                 printf("%s: timeout waiting to start bg rebuild\n",
  964                     DEVNAME(sc));
  965                 return (1);
  966         }
  967 
  968         printf("%s: %d SATA Ports, %dMB SDRAM, FW Version: %s\n",
  969             DEVNAME(sc), letoh32(fwinfo.sata_ports),
  970             letoh32(fwinfo.sdram_size), string);
  971 
  972         return (0);
  973 }
  974 
  975 #if NBIO > 0
  976 int
  977 arc_bioctl(struct device *self, u_long cmd, caddr_t addr)
  978 {
  979         struct arc_softc                *sc = (struct arc_softc *)self;
  980         int                             error = 0;
  981 
  982         switch (cmd) {
  983         case BIOCINQ:
  984                 error = arc_bio_inq(sc, (struct bioc_inq *)addr);
  985                 break;
  986 
  987         case BIOCVOL:
  988                 error = arc_bio_vol(sc, (struct bioc_vol *)addr);
  989                 break;
  990 
  991         case BIOCDISK:
  992                 error = arc_bio_disk(sc, (struct bioc_disk *)addr);
  993                 break;
  994 
  995         case BIOCALARM:
  996                 error = arc_bio_alarm(sc, (struct bioc_alarm *)addr);
  997                 break;
  998 
  999         default:
 1000                 error = ENOTTY;
 1001                 break;
 1002         }
 1003 
 1004         return (error);
 1005 }
 1006 
 1007 int
 1008 arc_bio_alarm(struct arc_softc *sc, struct bioc_alarm *ba)
 1009 {
 1010         u_int8_t                        request[2];
 1011         u_int8_t                        reply[1];
 1012         size_t                          len;
 1013         int                             error = 0;
 1014 
 1015         switch (ba->ba_opcode) {
 1016         case BIOC_SAENABLE:
 1017         case BIOC_SADISABLE:
 1018                 request[0] = ARC_FW_SET_ALARM;
 1019                 request[1] = (ba->ba_opcode == BIOC_SAENABLE) ?
 1020                     ARC_FW_SET_ALARM_ENABLE : ARC_FW_SET_ALARM_DISABLE;
 1021                 len = sizeof(request);
 1022 
 1023                 break;
 1024 
 1025         case BIOC_SASILENCE:
 1026                 request[0] = ARC_FW_MUTE_ALARM;
 1027                 len = 1;
 1028 
 1029                 break;
 1030 
 1031         case BIOC_GASTATUS:
 1032                 /* system info is too big/ugly to deal with here */
 1033                 return (arc_bio_alarm_state(sc, ba));
 1034 
 1035         default:
 1036                 return (EOPNOTSUPP);
 1037         }
 1038 
 1039         arc_lock(sc);
 1040         error = arc_msgbuf(sc, request, len, reply, sizeof(reply));
 1041         arc_unlock(sc);
 1042 
 1043         if (error != 0)
 1044                 return (error);
 1045 
 1046         if (reply[0] != ARC_FW_CMD_OK)
 1047                 return (EIO);
 1048 
 1049         return (0);
 1050 }
 1051 
 1052 int
 1053 arc_bio_alarm_state(struct arc_softc *sc, struct bioc_alarm *ba)
 1054 {
 1055         u_int8_t                        request = ARC_FW_SYSINFO;
 1056         struct arc_fw_sysinfo           *sysinfo;
 1057         int                             error = 0;
 1058 
 1059         sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
 1060 
 1061         request = ARC_FW_SYSINFO;
 1062 
 1063         arc_lock(sc);
 1064         error = arc_msgbuf(sc, &request, sizeof(request),
 1065             sysinfo, sizeof(struct arc_fw_sysinfo));
 1066         arc_unlock(sc);
 1067 
 1068         if (error != 0)
 1069                 goto out;
 1070 
 1071         ba->ba_status = sysinfo->alarm;
 1072 
 1073 out:
 1074         free(sysinfo, M_TEMP);
 1075         return (error);
 1076 }
 1077 
 1078 
 1079 int
 1080 arc_bio_inq(struct arc_softc *sc, struct bioc_inq *bi)
 1081 {
 1082         u_int8_t                        request[2];
 1083         struct arc_fw_sysinfo           *sysinfo;
 1084         struct arc_fw_volinfo           *volinfo;
 1085         int                             maxvols, nvols = 0, i;
 1086         int                             error = 0;
 1087 
 1088         sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
 1089         volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
 1090 
 1091         arc_lock(sc);
 1092 
 1093         request[0] = ARC_FW_SYSINFO;
 1094         error = arc_msgbuf(sc, request, 1, sysinfo,
 1095             sizeof(struct arc_fw_sysinfo));
 1096         if (error != 0)
 1097                 goto out;
 1098 
 1099         maxvols = sysinfo->max_volume_set;
 1100 
 1101         request[0] = ARC_FW_VOLINFO;
 1102         for (i = 0; i < maxvols; i++) {
 1103                 request[1] = i;
 1104                 error = arc_msgbuf(sc, request, sizeof(request), volinfo,
 1105                     sizeof(struct arc_fw_volinfo));
 1106                 if (error != 0)
 1107                         goto out;
 1108 
 1109                 /*
 1110                  * I can't find an easy way to see if the volume exists or not
 1111                  * except to say that if it has no capacity then it isn't there.
 1112                  * Ignore passthru volumes, bioc_vol doesn't understand them.
 1113                  */
 1114                 if ((volinfo->capacity != 0 || volinfo->capacity2 != 0) &&
 1115                     volinfo->raid_level != ARC_FW_VOL_RAIDLEVEL_PASSTHRU)
 1116                         nvols++;
 1117         }
 1118 
 1119         strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
 1120         bi->bi_novol = nvols;
 1121 out:
 1122         arc_unlock(sc);
 1123         free(volinfo, M_TEMP);
 1124         free(sysinfo, M_TEMP);
 1125         return (error);
 1126 }
 1127 
 1128 int
 1129 arc_bio_getvol(struct arc_softc *sc, int vol, struct arc_fw_volinfo *volinfo)
 1130 {
 1131         u_int8_t                        request[2];
 1132         struct arc_fw_sysinfo           *sysinfo;
 1133         int                             error = 0;
 1134         int                             maxvols, nvols = 0, i;
 1135 
 1136         sysinfo = malloc(sizeof(struct arc_fw_sysinfo), M_TEMP, M_WAITOK);
 1137 
 1138         request[0] = ARC_FW_SYSINFO;
 1139         error = arc_msgbuf(sc, request, 1, sysinfo,
 1140             sizeof(struct arc_fw_sysinfo));
 1141         if (error != 0)
 1142                 goto out;
 1143 
 1144         maxvols = sysinfo->max_volume_set;
 1145 
 1146         request[0] = ARC_FW_VOLINFO;
 1147         for (i = 0; i < maxvols; i++) {
 1148                 request[1] = i;
 1149                 error = arc_msgbuf(sc, request, sizeof(request), volinfo,
 1150                     sizeof(struct arc_fw_volinfo));
 1151                 if (error != 0)
 1152                         goto out;
 1153 
 1154                 if ((volinfo->capacity == 0 && volinfo->capacity2 == 0) ||
 1155                     volinfo->raid_level == ARC_FW_VOL_RAIDLEVEL_PASSTHRU)
 1156                         continue;
 1157 
 1158                 if (nvols == vol)
 1159                         break;
 1160 
 1161                 nvols++;
 1162         }
 1163 
 1164         if (nvols != vol ||
 1165             (volinfo->capacity == 0 && volinfo->capacity2 == 0) ||
 1166             volinfo->raid_level == ARC_FW_VOL_RAIDLEVEL_PASSTHRU) {
 1167                 error = ENODEV;
 1168                 goto out;
 1169         }
 1170 
 1171 out:
 1172         free(sysinfo, M_TEMP);
 1173         return (error);
 1174 }
 1175 
 1176 int
 1177 arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv)
 1178 {
 1179         struct arc_fw_volinfo           *volinfo;
 1180         struct scsi_link                *sc_link;
 1181         struct device                   *dev;
 1182         u_int64_t                       blocks;
 1183         u_int32_t                       status;
 1184         int                             error = 0;
 1185 
 1186         volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
 1187 
 1188         arc_lock(sc);
 1189         error = arc_bio_getvol(sc, bv->bv_volid, volinfo);
 1190         arc_unlock(sc);
 1191 
 1192         if (error != 0)
 1193                 goto out;
 1194 
 1195         bv->bv_percent = -1;
 1196         bv->bv_seconds = 0;
 1197 
 1198         status = letoh32(volinfo->volume_status);
 1199         if (status == 0x0) {
 1200                 if (letoh32(volinfo->fail_mask) == 0x0)
 1201                         bv->bv_status = BIOC_SVONLINE;
 1202                 else
 1203                         bv->bv_status = BIOC_SVDEGRADED;
 1204         } else if (status & ARC_FW_VOL_STATUS_NEED_REGEN)
 1205                 bv->bv_status = BIOC_SVDEGRADED;
 1206         else if (status & ARC_FW_VOL_STATUS_FAILED)
 1207                 bv->bv_status = BIOC_SVOFFLINE;
 1208         else if (status & ARC_FW_VOL_STATUS_INITTING) {
 1209                 bv->bv_status = BIOC_SVBUILDING;
 1210                 bv->bv_percent = letoh32(volinfo->progress) / 10;
 1211         } else if (status & ARC_FW_VOL_STATUS_REBUILDING) {
 1212                 bv->bv_status = BIOC_SVREBUILD;
 1213                 bv->bv_percent = letoh32(volinfo->progress) / 10;
 1214         }
 1215 
 1216         blocks = (u_int64_t)letoh32(volinfo->capacity2) << 32;
 1217         blocks += (u_int64_t)letoh32(volinfo->capacity);
 1218         bv->bv_size = blocks * ARC_BLOCKSIZE; /* XXX */
 1219 
 1220         switch (volinfo->raid_level) {
 1221         case ARC_FW_VOL_RAIDLEVEL_0:
 1222                 bv->bv_level = 0;
 1223                 break;
 1224         case ARC_FW_VOL_RAIDLEVEL_1:
 1225                 bv->bv_level = 1;
 1226                 break;
 1227         case ARC_FW_VOL_RAIDLEVEL_3:
 1228                 bv->bv_level = 3;
 1229                 break;
 1230         case ARC_FW_VOL_RAIDLEVEL_5:
 1231                 bv->bv_level = 5;
 1232                 break;
 1233         case ARC_FW_VOL_RAIDLEVEL_6:
 1234                 bv->bv_level = 6;
 1235                 break;
 1236         case ARC_FW_VOL_RAIDLEVEL_PASSTHRU:
 1237         default:
 1238                 bv->bv_level = -1;
 1239                 break;
 1240         }
 1241 
 1242         bv->bv_nodisk = volinfo->member_disks;
 1243         sc_link = sc->sc_scsibus->sc_link[volinfo->scsi_attr.target]
 1244             [volinfo->scsi_attr.lun];
 1245         if (sc_link != NULL) {
 1246                 dev = sc_link->device_softc;
 1247                 strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev));
 1248         }
 1249 
 1250 out:
 1251         free(volinfo, M_TEMP);
 1252         return (error);
 1253 }
 1254 
 1255 int
 1256 arc_bio_disk(struct arc_softc *sc, struct bioc_disk *bd)
 1257 {
 1258         u_int8_t                        request[2];
 1259         struct arc_fw_volinfo           *volinfo;
 1260         struct arc_fw_raidinfo          *raidinfo;
 1261         struct arc_fw_diskinfo          *diskinfo;
 1262         int                             error = 0;
 1263         u_int64_t                       blocks;
 1264         char                            model[81];
 1265         char                            serial[41];
 1266         char                            rev[17];
 1267 
 1268         volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK);
 1269         raidinfo = malloc(sizeof(struct arc_fw_raidinfo), M_TEMP, M_WAITOK);
 1270         diskinfo = malloc(sizeof(struct arc_fw_diskinfo), M_TEMP, M_WAITOK);
 1271 
 1272         arc_lock(sc);
 1273 
 1274         error = arc_bio_getvol(sc, bd->bd_volid, volinfo);
 1275         if (error != 0)
 1276                 goto out;
 1277 
 1278         request[0] = ARC_FW_RAIDINFO;
 1279         request[1] = volinfo->raid_set_number;
 1280         error = arc_msgbuf(sc, request, sizeof(request), raidinfo,
 1281             sizeof(struct arc_fw_raidinfo));
 1282         if (error != 0)
 1283                 goto out;
 1284 
 1285         if (bd->bd_diskid > raidinfo->member_devices) {
 1286                 error = ENODEV;
 1287                 goto out;
 1288         }
 1289 
 1290         if (raidinfo->device_array[bd->bd_diskid] == 0xff) {
 1291                 /*
 1292                  * the disk doesn't exist anymore. bio is too dumb to be
 1293                  * able to display that, so put it on another bus
 1294                  */
 1295                 bd->bd_channel = 1;
 1296                 bd->bd_target = 0;
 1297                 bd->bd_lun = 0;
 1298                 bd->bd_status = BIOC_SDOFFLINE;
 1299                 strlcpy(bd->bd_vendor, "disk missing", sizeof(bd->bd_vendor));
 1300                 goto out;
 1301         }
 1302 
 1303         request[0] = ARC_FW_DISKINFO;
 1304         request[1] = raidinfo->device_array[bd->bd_diskid];
 1305         error = arc_msgbuf(sc, request, sizeof(request), diskinfo,
 1306             sizeof(struct arc_fw_diskinfo));
 1307         if (error != 0)
 1308                 goto out;
 1309 
 1310 #if 0
 1311         bd->bd_channel = diskinfo->scsi_attr.channel;
 1312         bd->bd_target = diskinfo->scsi_attr.target;
 1313         bd->bd_lun = diskinfo->scsi_attr.lun;
 1314 #endif
 1315         /*
 1316          * the firwmare doesnt seem to fill scsi_attr in, so fake it with
 1317          * the diskid.
 1318          */
 1319         bd->bd_channel = 0;
 1320         bd->bd_target = raidinfo->device_array[bd->bd_diskid];
 1321         bd->bd_lun = 0;
 1322 
 1323         bd->bd_status = BIOC_SDONLINE;
 1324         blocks = (u_int64_t)letoh32(diskinfo->capacity2) << 32;
 1325         blocks += (u_int64_t)letoh32(diskinfo->capacity);
 1326         bd->bd_size = blocks * ARC_BLOCKSIZE; /* XXX */
 1327 
 1328         scsi_strvis(model, diskinfo->model, sizeof(diskinfo->model));
 1329         scsi_strvis(serial, diskinfo->serial, sizeof(diskinfo->serial));
 1330         scsi_strvis(rev, diskinfo->firmware_rev,
 1331             sizeof(diskinfo->firmware_rev));
 1332 
 1333         snprintf(bd->bd_vendor, sizeof(bd->bd_vendor), "%s %s",
 1334             model, rev);
 1335         strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial));
 1336 
 1337 out:
 1338         arc_unlock(sc);
 1339         free(diskinfo, M_TEMP);
 1340         free(raidinfo, M_TEMP);
 1341         free(volinfo, M_TEMP);
 1342         return (error);
 1343 }
 1344 
 1345 u_int8_t
 1346 arc_msg_cksum(void *cmd, u_int16_t len)
 1347 {
 1348         u_int8_t                        *buf = cmd;
 1349         u_int8_t                        cksum;
 1350         int                             i;
 1351 
 1352         cksum = (u_int8_t)(len >> 8) + (u_int8_t)len;
 1353         for (i = 0; i < len; i++)
 1354                 cksum += buf[i];
 1355 
 1356         return (cksum);
 1357 }
 1358 
 1359 
 1360 int
 1361 arc_msgbuf(struct arc_softc *sc, void *wptr, size_t wbuflen, void *rptr,
 1362     size_t rbuflen)
 1363 {
 1364         u_int8_t                        rwbuf[ARC_REG_IOC_RWBUF_MAXLEN];
 1365         u_int8_t                        *wbuf, *rbuf;
 1366         int                             wlen, wdone = 0, rlen, rdone = 0;
 1367         struct arc_fw_bufhdr            *bufhdr;
 1368         u_int32_t                       reg, rwlen;
 1369         int                             error = 0;
 1370 #ifdef ARC_DEBUG
 1371         int                             i;
 1372 #endif
 1373 
 1374         DNPRINTF(ARC_D_DB, "%s: arc_msgbuf wbuflen: %d rbuflen: %d\n",
 1375             DEVNAME(sc), wbuflen, rbuflen);
 1376 
 1377         if (arc_read(sc, ARC_REG_OUTB_DOORBELL) != 0)
 1378                 return (EBUSY);
 1379 
 1380         wlen = sizeof(struct arc_fw_bufhdr) + wbuflen + 1; /* 1 for cksum */
 1381         wbuf = malloc(wlen, M_TEMP, M_WAITOK);
 1382 
 1383         rlen = sizeof(struct arc_fw_bufhdr) + rbuflen + 1; /* 1 for cksum */
 1384         rbuf = malloc(rlen, M_TEMP, M_WAITOK);
 1385 
 1386         DNPRINTF(ARC_D_DB, "%s: arc_msgbuf wlen: %d rlen: %d\n", DEVNAME(sc),
 1387             wlen, rlen);
 1388 
 1389         bufhdr = (struct arc_fw_bufhdr *)wbuf;
 1390         bufhdr->hdr = arc_fw_hdr;
 1391         bufhdr->len = htole16(wbuflen);
 1392         bcopy(wptr, wbuf + sizeof(struct arc_fw_bufhdr), wbuflen);
 1393         wbuf[wlen - 1] = arc_msg_cksum(wptr, wbuflen);
 1394 
 1395         reg = ARC_REG_OUTB_DOORBELL_READ_OK;
 1396 
 1397         do {
 1398                 if ((reg & ARC_REG_OUTB_DOORBELL_READ_OK) && wdone < wlen) {
 1399                         bzero(rwbuf, sizeof(rwbuf));
 1400                         rwlen = (wlen - wdone) % sizeof(rwbuf);
 1401                         bcopy(&wbuf[wdone], rwbuf, rwlen);
 1402 
 1403 #ifdef ARC_DEBUG
 1404                         if (arcdebug & ARC_D_DB) {
 1405                                 printf("%s: write %d:", DEVNAME(sc), rwlen);
 1406                                 for (i = 0; i < rwlen; i++)
 1407                                         printf(" 0x%02x", rwbuf[i]);
 1408                                 printf("\n");
 1409                         }
 1410 #endif
 1411 
 1412                         /* copy the chunk to the hw */
 1413                         arc_write(sc, ARC_REG_IOC_WBUF_LEN, rwlen);
 1414                         arc_write_region(sc, ARC_REG_IOC_WBUF, rwbuf,
 1415                             sizeof(rwbuf));
 1416 
 1417                         /* say we have a buffer for the hw */
 1418                         arc_write(sc, ARC_REG_INB_DOORBELL,
 1419                             ARC_REG_INB_DOORBELL_WRITE_OK);
 1420 
 1421                         wdone += rwlen;
 1422                 }
 1423 
 1424                 while ((reg = arc_read(sc, ARC_REG_OUTB_DOORBELL)) == 0)
 1425                         arc_wait(sc);
 1426                 arc_write(sc, ARC_REG_OUTB_DOORBELL, reg);
 1427 
 1428                 DNPRINTF(ARC_D_DB, "%s: reg: 0x%08x\n", DEVNAME(sc), reg);
 1429 
 1430                 if ((reg & ARC_REG_OUTB_DOORBELL_WRITE_OK) && rdone < rlen) {
 1431                         rwlen = arc_read(sc, ARC_REG_IOC_RBUF_LEN);
 1432                         if (rwlen > sizeof(rwbuf)) {
 1433                                 DNPRINTF(ARC_D_DB, "%s:  rwlen too big\n",
 1434                                     DEVNAME(sc));
 1435                                 error = EIO;
 1436                                 goto out;
 1437                         }
 1438 
 1439                         arc_read_region(sc, ARC_REG_IOC_RBUF, rwbuf,
 1440                             sizeof(rwbuf));
 1441 
 1442                         arc_write(sc, ARC_REG_INB_DOORBELL,
 1443                             ARC_REG_INB_DOORBELL_READ_OK);
 1444 
 1445 #ifdef ARC_DEBUG
 1446                         printf("%s:  len: %d+%d=%d/%d\n", DEVNAME(sc),
 1447                             rwlen, rdone, rwlen + rdone, rlen);
 1448                         if (arcdebug & ARC_D_DB) {
 1449                                 printf("%s: read:", DEVNAME(sc));
 1450                                 for (i = 0; i < rwlen; i++)
 1451                                         printf(" 0x%02x", rwbuf[i]);
 1452                                 printf("\n");
 1453                         }
 1454 #endif
 1455 
 1456                         if ((rdone + rwlen) > rlen) {
 1457                                 DNPRINTF(ARC_D_DB, "%s:  rwbuf too big\n",
 1458                                     DEVNAME(sc));
 1459                                 error = EIO;
 1460                                 goto out;
 1461                         }
 1462 
 1463                         bcopy(rwbuf, &rbuf[rdone], rwlen);
 1464                         rdone += rwlen;
 1465                 }
 1466         } while (rdone != rlen);
 1467 
 1468         bufhdr = (struct arc_fw_bufhdr *)rbuf;
 1469         if (memcmp(&bufhdr->hdr, &arc_fw_hdr, sizeof(bufhdr->hdr)) != 0 ||
 1470             bufhdr->len != htole16(rbuflen)) {
 1471                 DNPRINTF(ARC_D_DB, "%s:  rbuf hdr is wrong\n", DEVNAME(sc));
 1472                 error = EIO;
 1473                 goto out;
 1474         }
 1475 
 1476         bcopy(rbuf + sizeof(struct arc_fw_bufhdr), rptr, rbuflen);
 1477 
 1478         if (rbuf[rlen - 1] != arc_msg_cksum(rptr, rbuflen)) {
 1479                 DNPRINTF(ARC_D_DB, "%s:  invalid cksum\n", DEVNAME(sc));
 1480                 error = EIO;
 1481                 goto out;
 1482         }
 1483 
 1484 out:
 1485         free(wbuf, M_TEMP);
 1486         free(rbuf, M_TEMP);
 1487 
 1488         return (error);
 1489 }
 1490 
 1491 void
 1492 arc_lock(struct arc_softc *sc)
 1493 {
 1494         int                             s;
 1495 
 1496         rw_enter_write(&sc->sc_lock);
 1497         s = splbio();
 1498         arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE);
 1499         sc->sc_talking = 1;
 1500         splx(s);
 1501 }
 1502 
 1503 void
 1504 arc_unlock(struct arc_softc *sc)
 1505 {
 1506         int                             s;
 1507 
 1508         s = splbio();
 1509         sc->sc_talking = 0;
 1510         arc_write(sc, ARC_REG_INTRMASK,
 1511             ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL));
 1512         splx(s);
 1513         rw_exit_write(&sc->sc_lock);
 1514 }
 1515 
 1516 void
 1517 arc_wait(struct arc_softc *sc)
 1518 {
 1519         int                             s;
 1520 
 1521         s = splbio();
 1522         arc_write(sc, ARC_REG_INTRMASK,
 1523             ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL));
 1524         if (tsleep(sc, PWAIT, "arcdb", hz) == EWOULDBLOCK)
 1525                 arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE);
 1526         splx(s);
 1527 }
 1528 
 1529 #ifndef SMALL_KERNEL
 1530 void
 1531 arc_create_sensors(void *xsc, void *arg)
 1532 {
 1533         struct arc_softc        *sc = xsc;
 1534         struct bioc_inq         bi;
 1535         struct bioc_vol         bv;
 1536         int                     i;
 1537 
 1538         /*
 1539          * XXX * this is bollocks. the firmware has garbage coming out of it
 1540          * so we have to wait a bit for it to finish spewing.
 1541          */
 1542         tsleep(sc, PWAIT, "arcspew", 2 * hz);
 1543 
 1544         bzero(&bi, sizeof(bi));
 1545         if (arc_bio_inq(sc, &bi) != 0) {
 1546                 printf("%s: unable to query firmware for sensor info\n",
 1547                     DEVNAME(sc));
 1548                 return;
 1549         }
 1550         sc->sc_nsensors = bi.bi_novol;
 1551 
 1552         sc->sc_sensors = malloc(sizeof(struct ksensor) * sc->sc_nsensors,
 1553             M_DEVBUF, M_WAITOK);
 1554         bzero(sc->sc_sensors, sizeof(struct ksensor) * sc->sc_nsensors);
 1555 
 1556         strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
 1557             sizeof(sc->sc_sensordev.xname));
 1558 
 1559         for (i = 0; i < sc->sc_nsensors; i++) {
 1560                 bzero(&bv, sizeof(bv));
 1561                 bv.bv_volid = i;
 1562                 if (arc_bio_vol(sc, &bv) != 0)
 1563                         goto bad;
 1564 
 1565                 sc->sc_sensors[i].type = SENSOR_DRIVE;
 1566                 sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
 1567 
 1568                 strlcpy(sc->sc_sensors[i].desc, bv.bv_dev,
 1569                     sizeof(sc->sc_sensors[i].desc));
 1570 
 1571                 sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[i]);
 1572         }
 1573 
 1574         if (sensor_task_register(sc, arc_refresh_sensors, 120) == NULL)
 1575                 goto bad;
 1576 
 1577         sensordev_install(&sc->sc_sensordev);
 1578 
 1579         return;
 1580 
 1581 bad:
 1582         free(sc->sc_sensors, M_DEVBUF);
 1583 }
 1584 
 1585 void
 1586 arc_refresh_sensors(void *arg)
 1587 {
 1588         struct arc_softc        *sc = arg;
 1589         struct bioc_vol         bv;
 1590         int                     i;
 1591 
 1592         for (i = 0; i < sc->sc_nsensors; i++) {
 1593                 bzero(&bv, sizeof(bv));
 1594                 bv.bv_volid = i;
 1595                 if (arc_bio_vol(sc, &bv)) {
 1596                         sc->sc_sensors[i].flags = SENSOR_FINVALID;
 1597                         return;
 1598                 }
 1599 
 1600                 switch(bv.bv_status) {
 1601                 case BIOC_SVOFFLINE:
 1602                         sc->sc_sensors[i].value = SENSOR_DRIVE_FAIL;
 1603                         sc->sc_sensors[i].status = SENSOR_S_CRIT;
 1604                         break;
 1605 
 1606                 case BIOC_SVDEGRADED:
 1607                         sc->sc_sensors[i].value = SENSOR_DRIVE_PFAIL;
 1608                         sc->sc_sensors[i].status = SENSOR_S_WARN;
 1609                         break;
 1610 
 1611                 case BIOC_SVSCRUB:
 1612                 case BIOC_SVONLINE:
 1613                         sc->sc_sensors[i].value = SENSOR_DRIVE_ONLINE;
 1614                         sc->sc_sensors[i].status = SENSOR_S_OK;
 1615                         break;
 1616 
 1617                 case BIOC_SVINVALID:
 1618                         /* FALLTRHOUGH */
 1619                 default:
 1620                         sc->sc_sensors[i].value = 0; /* unknown */
 1621                         sc->sc_sensors[i].status = SENSOR_S_UNKNOWN;
 1622                 }
 1623 
 1624         }
 1625 }
 1626 #endif /* SMALL_KERNEL */
 1627 #endif /* NBIO > 0 */
 1628 
 1629 u_int32_t
 1630 arc_read(struct arc_softc *sc, bus_size_t r)
 1631 {
 1632         u_int32_t                       v;
 1633 
 1634         bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
 1635             BUS_SPACE_BARRIER_READ);
 1636         v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
 1637 
 1638         DNPRINTF(ARC_D_RW, "%s: arc_read 0x%x 0x%08x\n", DEVNAME(sc), r, v);
 1639 
 1640         return (v);
 1641 }
 1642 
 1643 void
 1644 arc_read_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len)
 1645 {
 1646         bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len,
 1647             BUS_SPACE_BARRIER_READ);
 1648         bus_space_read_raw_region_4(sc->sc_iot, sc->sc_ioh, r, buf, len);
 1649 }
 1650 
 1651 void
 1652 arc_write(struct arc_softc *sc, bus_size_t r, u_int32_t v)
 1653 {
 1654         DNPRINTF(ARC_D_RW, "%s: arc_write 0x%x 0x%08x\n", DEVNAME(sc), r, v);
 1655 
 1656         bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
 1657         bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
 1658             BUS_SPACE_BARRIER_WRITE);
 1659 }
 1660 
 1661 void
 1662 arc_write_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len)
 1663 {
 1664         bus_space_write_raw_region_4(sc->sc_iot, sc->sc_ioh, r, buf, len);
 1665         bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len,
 1666             BUS_SPACE_BARRIER_WRITE);
 1667 }
 1668 
 1669 int
 1670 arc_wait_eq(struct arc_softc *sc, bus_size_t r, u_int32_t mask,
 1671     u_int32_t target)
 1672 {
 1673         int                             i;
 1674 
 1675         DNPRINTF(ARC_D_RW, "%s: arc_wait_eq 0x%x 0x%08x 0x%08x\n",
 1676             DEVNAME(sc), r, mask, target);
 1677 
 1678         for (i = 0; i < 10000; i++) {
 1679                 if ((arc_read(sc, r) & mask) == target)
 1680                         return (0);
 1681                 delay(1000);
 1682         }
 1683 
 1684         return (1);
 1685 }
 1686 
 1687 int
 1688 arc_wait_ne(struct arc_softc *sc, bus_size_t r, u_int32_t mask,
 1689     u_int32_t target)
 1690 {
 1691         int                             i;
 1692 
 1693         DNPRINTF(ARC_D_RW, "%s: arc_wait_ne 0x%x 0x%08x 0x%08x\n",
 1694             DEVNAME(sc), r, mask, target);
 1695 
 1696         for (i = 0; i < 10000; i++) {
 1697                 if ((arc_read(sc, r) & mask) != target)
 1698                         return (0);
 1699                 delay(1000);
 1700         }
 1701 
 1702         return (1);
 1703 }
 1704 
 1705 int
 1706 arc_msg0(struct arc_softc *sc, u_int32_t m)
 1707 {
 1708         /* post message */
 1709         arc_write(sc, ARC_REG_INB_MSG0, m);
 1710         /* wait for the fw to do it */
 1711         if (arc_wait_eq(sc, ARC_REG_INTRSTAT, ARC_REG_INTRSTAT_MSG0,
 1712             ARC_REG_INTRSTAT_MSG0) != 0)
 1713                 return (1);
 1714 
 1715         /* ack it */
 1716         arc_write(sc, ARC_REG_INTRSTAT, ARC_REG_INTRSTAT_MSG0);
 1717 
 1718         return (0);
 1719 }
 1720 
 1721 struct arc_dmamem *
 1722 arc_dmamem_alloc(struct arc_softc *sc, size_t size)
 1723 {
 1724         struct arc_dmamem               *adm;
 1725         int                             nsegs;
 1726 
 1727         adm = malloc(sizeof(struct arc_dmamem), M_DEVBUF, M_NOWAIT);
 1728         if (adm == NULL)
 1729                 return (NULL);
 1730 
 1731         bzero(adm, sizeof(struct arc_dmamem));
 1732         adm->adm_size = size;
 1733 
 1734         if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
 1735             BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &adm->adm_map) != 0)
 1736                 goto admfree;
 1737 
 1738         if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &adm->adm_seg,
 1739             1, &nsegs, BUS_DMA_NOWAIT) != 0)
 1740                 goto destroy;
 1741 
 1742         if (bus_dmamem_map(sc->sc_dmat, &adm->adm_seg, nsegs, size,
 1743             &adm->adm_kva, BUS_DMA_NOWAIT) != 0)
 1744                 goto free;
 1745 
 1746         if (bus_dmamap_load(sc->sc_dmat, adm->adm_map, adm->adm_kva, size,
 1747             NULL, BUS_DMA_NOWAIT) != 0)
 1748                 goto unmap;
 1749 
 1750         bzero(adm->adm_kva, size);
 1751 
 1752         return (adm);
 1753 
 1754 unmap:
 1755         bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, size);
 1756 free:
 1757         bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
 1758 destroy:
 1759         bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
 1760 admfree:
 1761         free(adm, M_DEVBUF);
 1762 
 1763         return (NULL);
 1764 }
 1765 
 1766 void
 1767 arc_dmamem_free(struct arc_softc *sc, struct arc_dmamem *adm)
 1768 {
 1769         bus_dmamap_unload(sc->sc_dmat, adm->adm_map);
 1770         bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, adm->adm_size);
 1771         bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1);
 1772         bus_dmamap_destroy(sc->sc_dmat, adm->adm_map);
 1773         free(adm, M_DEVBUF);
 1774 }
 1775 
 1776 int
 1777 arc_alloc_ccbs(struct arc_softc *sc)
 1778 {
 1779         struct arc_ccb                  *ccb;
 1780         u_int8_t                        *cmd;
 1781         int                             i;
 1782 
 1783         TAILQ_INIT(&sc->sc_ccb_free);
 1784 
 1785         sc->sc_ccbs = malloc(sizeof(struct arc_ccb) * sc->sc_req_count,
 1786             M_DEVBUF, M_WAITOK);
 1787         bzero(sc->sc_ccbs, sizeof(struct arc_ccb) * sc->sc_req_count);
 1788 
 1789         sc->sc_requests = arc_dmamem_alloc(sc,
 1790             ARC_MAX_IOCMDLEN * sc->sc_req_count);
 1791         if (sc->sc_requests == NULL) {
 1792                 printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
 1793                 goto free_ccbs;
 1794         }
 1795         cmd = ARC_DMA_KVA(sc->sc_requests);
 1796 
 1797         for (i = 0; i < sc->sc_req_count; i++) {
 1798                 ccb = &sc->sc_ccbs[i];
 1799 
 1800                 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, ARC_SGL_MAXLEN,
 1801                     MAXPHYS, 0, 0, &ccb->ccb_dmamap) != 0) {
 1802                         printf("%s: unable to create dmamap for ccb %d\n",
 1803                             DEVNAME(sc), i);
 1804                         goto free_maps;
 1805                 }
 1806 
 1807                 ccb->ccb_sc = sc;
 1808                 ccb->ccb_id = i;
 1809                 ccb->ccb_offset = ARC_MAX_IOCMDLEN * i;
 1810 
 1811                 ccb->ccb_cmd = (struct arc_io_cmd *)&cmd[ccb->ccb_offset];
 1812                 ccb->ccb_cmd_post = (ARC_DMA_DVA(sc->sc_requests) +
 1813                     ccb->ccb_offset) >> ARC_REG_POST_QUEUE_ADDR_SHIFT;
 1814 
 1815                 arc_put_ccb(sc, ccb);
 1816         }
 1817 
 1818         return (0);
 1819 
 1820 free_maps:
 1821         while ((ccb = arc_get_ccb(sc)) != NULL)
 1822             bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
 1823         arc_dmamem_free(sc, sc->sc_requests);
 1824 
 1825 free_ccbs:
 1826         free(sc->sc_ccbs, M_DEVBUF);
 1827 
 1828         return (1);
 1829 }
 1830 
 1831 struct arc_ccb *
 1832 arc_get_ccb(struct arc_softc *sc)
 1833 {
 1834         struct arc_ccb                  *ccb;
 1835 
 1836         ccb = TAILQ_FIRST(&sc->sc_ccb_free);
 1837         if (ccb != NULL)
 1838                 TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
 1839 
 1840         return (ccb);
 1841 }
 1842 
 1843 void
 1844 arc_put_ccb(struct arc_softc *sc, struct arc_ccb *ccb)
 1845 {
 1846         ccb->ccb_xs = NULL;
 1847         bzero(ccb->ccb_cmd, ARC_MAX_IOCMDLEN);
 1848         TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
 1849 }

/* [<][>][^][v][top][bottom][index][help] */