1 1.45 andvar /* $NetBSD: arcmsr.c,v 1.45 2024/02/09 17:57:03 andvar Exp $ */ 2 1.1 xtraeme /* $OpenBSD: arc.c,v 1.68 2007/10/27 03:28:27 dlg Exp $ */ 3 1.1 xtraeme 4 1.1 xtraeme /* 5 1.10 xtraeme * Copyright (c) 2007, 2008 Juan Romero Pardines <xtraeme (at) netbsd.org> 6 1.1 xtraeme * Copyright (c) 2006 David Gwynne <dlg (at) openbsd.org> 7 1.1 xtraeme * 8 1.1 xtraeme * Permission to use, copy, modify, and distribute this software for any 9 1.1 xtraeme * purpose with or without fee is hereby granted, provided that the above 10 1.1 xtraeme * copyright notice and this permission notice appear in all copies. 11 1.1 xtraeme * 12 1.1 xtraeme * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 1.1 xtraeme * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 1.1 xtraeme * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 1.1 xtraeme * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 1.1 xtraeme * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 1.1 xtraeme * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 1.1 xtraeme * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 1.1 xtraeme */ 20 1.1 xtraeme 21 1.1 xtraeme #include "bio.h" 22 1.1 xtraeme 23 1.1 xtraeme #include <sys/cdefs.h> 24 1.45 andvar __KERNEL_RCSID(0, "$NetBSD: arcmsr.c,v 1.45 2024/02/09 17:57:03 andvar Exp $"); 25 1.1 xtraeme 26 1.1 xtraeme #include <sys/param.h> 27 1.1 xtraeme #include <sys/buf.h> 28 1.1 xtraeme #include <sys/kernel.h> 29 1.1 xtraeme #include <sys/device.h> 30 1.7 xtraeme #include <sys/kmem.h> 31 1.1 xtraeme #include <sys/kthread.h> 32 1.3 xtraeme #include <sys/mutex.h> 33 1.3 xtraeme #include <sys/condvar.h> 34 1.5 xtraeme #include <sys/rwlock.h> 35 1.1 xtraeme 36 1.1 xtraeme #if NBIO > 0 37 1.1 xtraeme #include <sys/ioctl.h> 38 1.1 xtraeme #include <dev/biovar.h> 39 1.1 xtraeme #endif 40 1.1 xtraeme 41 1.1 xtraeme #include <dev/pci/pcireg.h> 42 1.1 xtraeme #include <dev/pci/pcivar.h> 43 1.1 xtraeme #include <dev/pci/pcidevs.h> 44 1.1 xtraeme 45 1.1 xtraeme #include <dev/scsipi/scsipi_all.h> 46 1.1 xtraeme #include <dev/scsipi/scsi_all.h> 47 1.1 xtraeme #include <dev/scsipi/scsiconf.h> 48 1.1 xtraeme 49 1.1 xtraeme #include <dev/sysmon/sysmonvar.h> 50 1.1 xtraeme 51 1.1 xtraeme #include <sys/bus.h> 52 1.1 xtraeme 53 1.1 xtraeme #include <dev/pci/arcmsrvar.h> 54 1.1 xtraeme 55 1.1 xtraeme /* #define ARC_DEBUG */ 56 1.1 xtraeme #ifdef ARC_DEBUG 57 1.1 xtraeme #define ARC_D_INIT (1<<0) 58 1.1 xtraeme #define ARC_D_RW (1<<1) 59 1.1 xtraeme #define ARC_D_DB (1<<2) 60 1.1 xtraeme 61 1.1 xtraeme int arcdebug = 0; 62 1.1 xtraeme 63 1.1 xtraeme #define DPRINTF(p...) do { if (arcdebug) printf(p); } while (0) 64 1.1 xtraeme #define DNPRINTF(n, p...) do { if ((n) & arcdebug) printf(p); } while (0) 65 1.1 xtraeme 66 1.1 xtraeme #else 67 1.21 gmcgarry #define DPRINTF(p, ...) /* p */ 68 1.21 gmcgarry #define DNPRINTF(n, p, ...) /* n, p */ 69 1.1 xtraeme #endif 70 1.1 xtraeme 71 1.1 xtraeme /* 72 1.1 xtraeme * the fw header must always equal this. 73 1.1 xtraeme */ 74 1.36 dholland #if NBIO > 0 75 1.1 xtraeme static struct arc_fw_hdr arc_fw_hdr = { 0x5e, 0x01, 0x61 }; 76 1.36 dholland #endif 77 1.1 xtraeme 78 1.1 xtraeme /* 79 1.1 xtraeme * autoconf(9) glue. 80 1.1 xtraeme */ 81 1.19 xtraeme static int arc_match(device_t, cfdata_t, void *); 82 1.1 xtraeme static void arc_attach(device_t, device_t, void *); 83 1.1 xtraeme static int arc_detach(device_t, int); 84 1.10 xtraeme static bool arc_shutdown(device_t, int); 85 1.1 xtraeme static int arc_intr(void *); 86 1.1 xtraeme static void arc_minphys(struct buf *); 87 1.1 xtraeme 88 1.19 xtraeme CFATTACH_DECL_NEW(arcmsr, sizeof(struct arc_softc), 89 1.1 xtraeme arc_match, arc_attach, arc_detach, NULL); 90 1.1 xtraeme 91 1.1 xtraeme /* 92 1.1 xtraeme * bio(4) and sysmon_envsys(9) glue. 93 1.1 xtraeme */ 94 1.1 xtraeme #if NBIO > 0 95 1.19 xtraeme static int arc_bioctl(device_t, u_long, void *); 96 1.1 xtraeme static int arc_bio_inq(struct arc_softc *, struct bioc_inq *); 97 1.1 xtraeme static int arc_bio_vol(struct arc_softc *, struct bioc_vol *); 98 1.9 xtraeme static int arc_bio_disk_volume(struct arc_softc *, struct bioc_disk *); 99 1.9 xtraeme static int arc_bio_disk_novol(struct arc_softc *, struct bioc_disk *); 100 1.9 xtraeme static void arc_bio_disk_filldata(struct arc_softc *, struct bioc_disk *, 101 1.9 xtraeme struct arc_fw_diskinfo *, int); 102 1.1 xtraeme static int arc_bio_alarm(struct arc_softc *, struct bioc_alarm *); 103 1.1 xtraeme static int arc_bio_alarm_state(struct arc_softc *, struct bioc_alarm *); 104 1.1 xtraeme static int arc_bio_getvol(struct arc_softc *, int, 105 1.1 xtraeme struct arc_fw_volinfo *); 106 1.9 xtraeme static int arc_bio_setstate(struct arc_softc *, struct bioc_setstate *); 107 1.9 xtraeme static int arc_bio_volops(struct arc_softc *, struct bioc_volops *); 108 1.1 xtraeme static void arc_create_sensors(void *); 109 1.2 xtraeme static void arc_refresh_sensors(struct sysmon_envsys *, envsys_data_t *); 110 1.9 xtraeme static int arc_fw_parse_status_code(struct arc_softc *, uint8_t *); 111 1.1 xtraeme #endif 112 1.1 xtraeme 113 1.34 christos /* 114 1.34 christos * interface for scsi midlayer to talk to. 115 1.34 christos */ 116 1.34 christos static void arc_scsi_cmd(struct scsipi_channel *, scsipi_adapter_req_t, 117 1.34 christos void *); 118 1.34 christos 119 1.34 christos /* 120 1.34 christos * code to deal with getting bits in and out of the bus space. 121 1.34 christos */ 122 1.34 christos static uint32_t arc_read(struct arc_softc *, bus_size_t); 123 1.34 christos static void arc_read_region(struct arc_softc *, bus_size_t, void *, 124 1.34 christos size_t); 125 1.34 christos static void arc_write(struct arc_softc *, bus_size_t, uint32_t); 126 1.36 dholland #if NBIO > 0 127 1.34 christos static void arc_write_region(struct arc_softc *, bus_size_t, void *, 128 1.34 christos size_t); 129 1.36 dholland #endif 130 1.34 christos static int arc_wait_eq(struct arc_softc *, bus_size_t, uint32_t, 131 1.34 christos uint32_t); 132 1.34 christos #ifdef unused 133 1.34 christos static int arc_wait_ne(struct arc_softc *, bus_size_t, uint32_t, 134 1.34 christos uint32_t); 135 1.34 christos #endif 136 1.34 christos static int arc_msg0(struct arc_softc *, uint32_t); 137 1.34 christos static struct arc_dmamem *arc_dmamem_alloc(struct arc_softc *, size_t); 138 1.34 christos static void arc_dmamem_free(struct arc_softc *, 139 1.34 christos struct arc_dmamem *); 140 1.34 christos 141 1.34 christos static int arc_alloc_ccbs(device_t); 142 1.34 christos static struct arc_ccb *arc_get_ccb(struct arc_softc *); 143 1.34 christos static void arc_put_ccb(struct arc_softc *, struct arc_ccb *); 144 1.34 christos static int arc_load_xs(struct arc_ccb *); 145 1.34 christos static int arc_complete(struct arc_softc *, struct arc_ccb *, int); 146 1.34 christos static void arc_scsi_cmd_done(struct arc_softc *, struct arc_ccb *, 147 1.34 christos uint32_t); 148 1.34 christos 149 1.34 christos /* 150 1.34 christos * real stuff for dealing with the hardware. 151 1.34 christos */ 152 1.34 christos static int arc_map_pci_resources(device_t, struct pci_attach_args *); 153 1.34 christos static void arc_unmap_pci_resources(struct arc_softc *); 154 1.34 christos static int arc_query_firmware(device_t); 155 1.34 christos 156 1.34 christos /* 157 1.34 christos * stuff to do messaging via the doorbells. 158 1.34 christos */ 159 1.35 dholland #if NBIO > 0 160 1.34 christos static void arc_lock(struct arc_softc *); 161 1.34 christos static void arc_unlock(struct arc_softc *); 162 1.34 christos static void arc_wait(struct arc_softc *); 163 1.34 christos static uint8_t arc_msg_cksum(void *, uint16_t); 164 1.34 christos static int arc_msgbuf(struct arc_softc *, void *, size_t, void *, size_t); 165 1.35 dholland #endif 166 1.34 christos 167 1.34 christos #define arc_push(_s, _r) arc_write((_s), ARC_REG_POST_QUEUE, (_r)) 168 1.34 christos #define arc_pop(_s) arc_read((_s), ARC_REG_REPLY_QUEUE) 169 1.34 christos 170 1.1 xtraeme static int 171 1.19 xtraeme arc_match(device_t parent, cfdata_t match, void *aux) 172 1.1 xtraeme { 173 1.1 xtraeme struct pci_attach_args *pa = aux; 174 1.1 xtraeme 175 1.1 xtraeme if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ARECA) { 176 1.1 xtraeme switch (PCI_PRODUCT(pa->pa_id)) { 177 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1110: 178 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1120: 179 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1130: 180 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1160: 181 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1170: 182 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1200: 183 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1202: 184 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1210: 185 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1220: 186 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1230: 187 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1260: 188 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1270: 189 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1280: 190 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1380: 191 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1381: 192 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1680: 193 1.1 xtraeme case PCI_PRODUCT_ARECA_ARC1681: 194 1.1 xtraeme return 1; 195 1.1 xtraeme default: 196 1.1 xtraeme break; 197 1.1 xtraeme } 198 1.1 xtraeme } 199 1.1 xtraeme 200 1.1 xtraeme return 0; 201 1.1 xtraeme } 202 1.1 xtraeme 203 1.1 xtraeme static void 204 1.1 xtraeme arc_attach(device_t parent, device_t self, void *aux) 205 1.1 xtraeme { 206 1.1 xtraeme struct arc_softc *sc = device_private(self); 207 1.1 xtraeme struct pci_attach_args *pa = aux; 208 1.1 xtraeme struct scsipi_adapter *adapt = &sc->sc_adapter; 209 1.1 xtraeme struct scsipi_channel *chan = &sc->sc_chan; 210 1.1 xtraeme 211 1.19 xtraeme sc->sc_dev = self; 212 1.1 xtraeme sc->sc_talking = 0; 213 1.5 xtraeme rw_init(&sc->sc_rwlock); 214 1.3 xtraeme mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_BIO); 215 1.3 xtraeme cv_init(&sc->sc_condvar, "arcdb"); 216 1.1 xtraeme 217 1.19 xtraeme if (arc_map_pci_resources(self, pa) != 0) { 218 1.1 xtraeme /* error message printed by arc_map_pci_resources */ 219 1.1 xtraeme return; 220 1.1 xtraeme } 221 1.1 xtraeme 222 1.19 xtraeme if (arc_query_firmware(self) != 0) { 223 1.1 xtraeme /* error message printed by arc_query_firmware */ 224 1.1 xtraeme goto unmap_pci; 225 1.1 xtraeme } 226 1.1 xtraeme 227 1.19 xtraeme if (arc_alloc_ccbs(self) != 0) { 228 1.1 xtraeme /* error message printed by arc_alloc_ccbs */ 229 1.1 xtraeme goto unmap_pci; 230 1.1 xtraeme } 231 1.1 xtraeme 232 1.10 xtraeme if (!pmf_device_register1(self, NULL, NULL, arc_shutdown)) 233 1.11 xtraeme panic("%s: couldn't establish shutdown handler\n", 234 1.11 xtraeme device_xname(self)); 235 1.1 xtraeme 236 1.1 xtraeme memset(adapt, 0, sizeof(*adapt)); 237 1.1 xtraeme adapt->adapt_dev = self; 238 1.1 xtraeme adapt->adapt_nchannels = 1; 239 1.1 xtraeme adapt->adapt_openings = sc->sc_req_count / ARC_MAX_TARGET; 240 1.1 xtraeme adapt->adapt_max_periph = adapt->adapt_openings; 241 1.1 xtraeme adapt->adapt_minphys = arc_minphys; 242 1.1 xtraeme adapt->adapt_request = arc_scsi_cmd; 243 1.37 mlelstv adapt->adapt_flags = SCSIPI_ADAPT_MPSAFE; 244 1.1 xtraeme 245 1.1 xtraeme memset(chan, 0, sizeof(*chan)); 246 1.1 xtraeme chan->chan_adapter = adapt; 247 1.1 xtraeme chan->chan_bustype = &scsi_bustype; 248 1.1 xtraeme chan->chan_nluns = ARC_MAX_LUN; 249 1.1 xtraeme chan->chan_ntargets = ARC_MAX_TARGET; 250 1.1 xtraeme chan->chan_id = ARC_MAX_TARGET; 251 1.4 xtraeme chan->chan_flags = SCSIPI_CHAN_NOSETTLE; 252 1.1 xtraeme 253 1.9 xtraeme /* 254 1.9 xtraeme * Save the device_t returned, because we could to attach 255 1.9 xtraeme * devices via the management interface. 256 1.9 xtraeme */ 257 1.41 thorpej sc->sc_scsibus_dv = config_found(self, &sc->sc_chan, scsiprint, 258 1.43 thorpej CFARGS_NONE); 259 1.1 xtraeme 260 1.1 xtraeme /* enable interrupts */ 261 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, 262 1.1 xtraeme ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRSTAT_DOORBELL)); 263 1.1 xtraeme 264 1.1 xtraeme #if NBIO > 0 265 1.7 xtraeme /* 266 1.7 xtraeme * Register the driver to bio(4) and setup the sensors. 267 1.7 xtraeme */ 268 1.1 xtraeme if (bio_register(self, arc_bioctl) != 0) 269 1.1 xtraeme panic("%s: bioctl registration failed\n", device_xname(self)); 270 1.7 xtraeme 271 1.7 xtraeme /* 272 1.1 xtraeme * you need to talk to the firmware to get volume info. our firmware 273 1.1 xtraeme * interface relies on being able to sleep, so we need to use a thread 274 1.1 xtraeme * to do the work. 275 1.1 xtraeme */ 276 1.1 xtraeme if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, 277 1.1 xtraeme arc_create_sensors, sc, &sc->sc_lwp, "arcmsr_sensors") != 0) 278 1.1 xtraeme panic("%s: unable to create a kernel thread for sensors\n", 279 1.1 xtraeme device_xname(self)); 280 1.1 xtraeme #endif 281 1.1 xtraeme 282 1.1 xtraeme return; 283 1.1 xtraeme 284 1.1 xtraeme unmap_pci: 285 1.1 xtraeme arc_unmap_pci_resources(sc); 286 1.1 xtraeme } 287 1.1 xtraeme 288 1.1 xtraeme static int 289 1.1 xtraeme arc_detach(device_t self, int flags) 290 1.1 xtraeme { 291 1.1 xtraeme struct arc_softc *sc = device_private(self); 292 1.1 xtraeme 293 1.1 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0) 294 1.19 xtraeme aprint_error_dev(self, "timeout waiting to stop bg rebuild\n"); 295 1.1 xtraeme 296 1.1 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0) 297 1.19 xtraeme aprint_error_dev(self, "timeout waiting to flush cache\n"); 298 1.1 xtraeme 299 1.25 jruoho if (sc->sc_sme != NULL) 300 1.25 jruoho sysmon_envsys_unregister(sc->sc_sme); 301 1.25 jruoho 302 1.1 xtraeme return 0; 303 1.1 xtraeme } 304 1.1 xtraeme 305 1.10 xtraeme static bool 306 1.10 xtraeme arc_shutdown(device_t self, int how) 307 1.1 xtraeme { 308 1.10 xtraeme struct arc_softc *sc = device_private(self); 309 1.1 xtraeme 310 1.1 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_STOP_BGRB) != 0) 311 1.19 xtraeme aprint_error_dev(self, "timeout waiting to stop bg rebuild\n"); 312 1.1 xtraeme 313 1.1 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_FLUSH_CACHE) != 0) 314 1.19 xtraeme aprint_error_dev(self, "timeout waiting to flush cache\n"); 315 1.10 xtraeme 316 1.10 xtraeme return true; 317 1.1 xtraeme } 318 1.1 xtraeme 319 1.1 xtraeme static void 320 1.1 xtraeme arc_minphys(struct buf *bp) 321 1.1 xtraeme { 322 1.1 xtraeme if (bp->b_bcount > MAXPHYS) 323 1.1 xtraeme bp->b_bcount = MAXPHYS; 324 1.1 xtraeme minphys(bp); 325 1.1 xtraeme } 326 1.1 xtraeme 327 1.1 xtraeme static int 328 1.1 xtraeme arc_intr(void *arg) 329 1.1 xtraeme { 330 1.1 xtraeme struct arc_softc *sc = arg; 331 1.1 xtraeme struct arc_ccb *ccb = NULL; 332 1.1 xtraeme char *kva = ARC_DMA_KVA(sc->sc_requests); 333 1.1 xtraeme struct arc_io_cmd *cmd; 334 1.1 xtraeme uint32_t reg, intrstat; 335 1.1 xtraeme 336 1.7 xtraeme mutex_spin_enter(&sc->sc_mutex); 337 1.1 xtraeme intrstat = arc_read(sc, ARC_REG_INTRSTAT); 338 1.3 xtraeme if (intrstat == 0x0) { 339 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 340 1.1 xtraeme return 0; 341 1.3 xtraeme } 342 1.1 xtraeme 343 1.1 xtraeme intrstat &= ARC_REG_INTRSTAT_POSTQUEUE | ARC_REG_INTRSTAT_DOORBELL; 344 1.1 xtraeme arc_write(sc, ARC_REG_INTRSTAT, intrstat); 345 1.1 xtraeme 346 1.1 xtraeme if (intrstat & ARC_REG_INTRSTAT_DOORBELL) { 347 1.1 xtraeme if (sc->sc_talking) { 348 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, 349 1.1 xtraeme ~ARC_REG_INTRMASK_POSTQUEUE); 350 1.3 xtraeme cv_broadcast(&sc->sc_condvar); 351 1.1 xtraeme } else { 352 1.1 xtraeme /* otherwise drop it */ 353 1.1 xtraeme reg = arc_read(sc, ARC_REG_OUTB_DOORBELL); 354 1.1 xtraeme arc_write(sc, ARC_REG_OUTB_DOORBELL, reg); 355 1.1 xtraeme if (reg & ARC_REG_OUTB_DOORBELL_WRITE_OK) 356 1.1 xtraeme arc_write(sc, ARC_REG_INB_DOORBELL, 357 1.1 xtraeme ARC_REG_INB_DOORBELL_READ_OK); 358 1.1 xtraeme } 359 1.1 xtraeme } 360 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 361 1.1 xtraeme 362 1.1 xtraeme while ((reg = arc_pop(sc)) != 0xffffffff) { 363 1.1 xtraeme cmd = (struct arc_io_cmd *)(kva + 364 1.1 xtraeme ((reg << ARC_REG_REPLY_QUEUE_ADDR_SHIFT) - 365 1.1 xtraeme (uint32_t)ARC_DMA_DVA(sc->sc_requests))); 366 1.1 xtraeme ccb = &sc->sc_ccbs[htole32(cmd->cmd.context)]; 367 1.1 xtraeme 368 1.1 xtraeme bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests), 369 1.1 xtraeme ccb->ccb_offset, ARC_MAX_IOCMDLEN, 370 1.1 xtraeme BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 371 1.1 xtraeme 372 1.1 xtraeme arc_scsi_cmd_done(sc, ccb, reg); 373 1.1 xtraeme } 374 1.1 xtraeme 375 1.9 xtraeme 376 1.1 xtraeme return 1; 377 1.1 xtraeme } 378 1.1 xtraeme 379 1.1 xtraeme void 380 1.1 xtraeme arc_scsi_cmd(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg) 381 1.1 xtraeme { 382 1.1 xtraeme struct scsipi_periph *periph; 383 1.1 xtraeme struct scsipi_xfer *xs; 384 1.1 xtraeme struct scsipi_adapter *adapt = chan->chan_adapter; 385 1.1 xtraeme struct arc_softc *sc = device_private(adapt->adapt_dev); 386 1.1 xtraeme struct arc_ccb *ccb; 387 1.1 xtraeme struct arc_msg_scsicmd *cmd; 388 1.1 xtraeme uint32_t reg; 389 1.1 xtraeme uint8_t target; 390 1.1 xtraeme 391 1.1 xtraeme switch (req) { 392 1.1 xtraeme case ADAPTER_REQ_GROW_RESOURCES: 393 1.1 xtraeme /* Not supported. */ 394 1.1 xtraeme return; 395 1.1 xtraeme case ADAPTER_REQ_SET_XFER_MODE: 396 1.1 xtraeme /* Not supported. */ 397 1.1 xtraeme return; 398 1.1 xtraeme case ADAPTER_REQ_RUN_XFER: 399 1.1 xtraeme break; 400 1.1 xtraeme } 401 1.1 xtraeme 402 1.7 xtraeme mutex_spin_enter(&sc->sc_mutex); 403 1.7 xtraeme 404 1.1 xtraeme xs = arg; 405 1.1 xtraeme periph = xs->xs_periph; 406 1.1 xtraeme target = periph->periph_target; 407 1.1 xtraeme 408 1.1 xtraeme if (xs->cmdlen > ARC_MSG_CDBLEN) { 409 1.1 xtraeme memset(&xs->sense, 0, sizeof(xs->sense)); 410 1.1 xtraeme xs->sense.scsi_sense.response_code = SSD_RCODE_VALID | 0x70; 411 1.1 xtraeme xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST; 412 1.1 xtraeme xs->sense.scsi_sense.asc = 0x20; 413 1.1 xtraeme xs->error = XS_SENSE; 414 1.1 xtraeme xs->status = SCSI_CHECK; 415 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 416 1.1 xtraeme scsipi_done(xs); 417 1.3 xtraeme return; 418 1.1 xtraeme } 419 1.1 xtraeme 420 1.1 xtraeme ccb = arc_get_ccb(sc); 421 1.1 xtraeme if (ccb == NULL) { 422 1.1 xtraeme xs->error = XS_RESOURCE_SHORTAGE; 423 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 424 1.1 xtraeme scsipi_done(xs); 425 1.3 xtraeme return; 426 1.1 xtraeme } 427 1.1 xtraeme 428 1.1 xtraeme ccb->ccb_xs = xs; 429 1.1 xtraeme 430 1.1 xtraeme if (arc_load_xs(ccb) != 0) { 431 1.1 xtraeme xs->error = XS_DRIVER_STUFFUP; 432 1.1 xtraeme arc_put_ccb(sc, ccb); 433 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 434 1.1 xtraeme scsipi_done(xs); 435 1.3 xtraeme return; 436 1.1 xtraeme } 437 1.1 xtraeme 438 1.1 xtraeme cmd = &ccb->ccb_cmd->cmd; 439 1.1 xtraeme reg = ccb->ccb_cmd_post; 440 1.1 xtraeme 441 1.1 xtraeme /* bus is always 0 */ 442 1.1 xtraeme cmd->target = target; 443 1.1 xtraeme cmd->lun = periph->periph_lun; 444 1.1 xtraeme cmd->function = 1; /* XXX magic number */ 445 1.1 xtraeme 446 1.1 xtraeme cmd->cdb_len = xs->cmdlen; 447 1.1 xtraeme cmd->sgl_len = ccb->ccb_dmamap->dm_nsegs; 448 1.1 xtraeme if (xs->xs_control & XS_CTL_DATA_OUT) 449 1.1 xtraeme cmd->flags = ARC_MSG_SCSICMD_FLAG_WRITE; 450 1.1 xtraeme if (ccb->ccb_dmamap->dm_nsegs > ARC_SGL_256LEN) { 451 1.1 xtraeme cmd->flags |= ARC_MSG_SCSICMD_FLAG_SGL_BSIZE_512; 452 1.1 xtraeme reg |= ARC_REG_POST_QUEUE_BIGFRAME; 453 1.1 xtraeme } 454 1.1 xtraeme 455 1.1 xtraeme cmd->context = htole32(ccb->ccb_id); 456 1.1 xtraeme cmd->data_len = htole32(xs->datalen); 457 1.1 xtraeme 458 1.1 xtraeme memcpy(cmd->cdb, xs->cmd, xs->cmdlen); 459 1.1 xtraeme 460 1.1 xtraeme /* we've built the command, let's put it on the hw */ 461 1.1 xtraeme bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests), 462 1.1 xtraeme ccb->ccb_offset, ARC_MAX_IOCMDLEN, 463 1.1 xtraeme BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 464 1.1 xtraeme 465 1.1 xtraeme arc_push(sc, reg); 466 1.1 xtraeme if (xs->xs_control & XS_CTL_POLL) { 467 1.1 xtraeme if (arc_complete(sc, ccb, xs->timeout) != 0) { 468 1.1 xtraeme xs->error = XS_DRIVER_STUFFUP; 469 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 470 1.1 xtraeme scsipi_done(xs); 471 1.7 xtraeme return; 472 1.1 xtraeme } 473 1.1 xtraeme } 474 1.7 xtraeme 475 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 476 1.1 xtraeme } 477 1.1 xtraeme 478 1.1 xtraeme int 479 1.1 xtraeme arc_load_xs(struct arc_ccb *ccb) 480 1.1 xtraeme { 481 1.1 xtraeme struct arc_softc *sc = ccb->ccb_sc; 482 1.1 xtraeme struct scsipi_xfer *xs = ccb->ccb_xs; 483 1.1 xtraeme bus_dmamap_t dmap = ccb->ccb_dmamap; 484 1.1 xtraeme struct arc_sge *sgl = ccb->ccb_cmd->sgl, *sge; 485 1.1 xtraeme uint64_t addr; 486 1.1 xtraeme int i, error; 487 1.1 xtraeme 488 1.1 xtraeme if (xs->datalen == 0) 489 1.1 xtraeme return 0; 490 1.1 xtraeme 491 1.1 xtraeme error = bus_dmamap_load(sc->sc_dmat, dmap, 492 1.1 xtraeme xs->data, xs->datalen, NULL, 493 1.1 xtraeme (xs->xs_control & XS_CTL_NOSLEEP) ? 494 1.1 xtraeme BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 495 1.1 xtraeme if (error != 0) { 496 1.1 xtraeme aprint_error("%s: error %d loading dmamap\n", 497 1.19 xtraeme device_xname(sc->sc_dev), error); 498 1.1 xtraeme return 1; 499 1.1 xtraeme } 500 1.1 xtraeme 501 1.1 xtraeme for (i = 0; i < dmap->dm_nsegs; i++) { 502 1.1 xtraeme sge = &sgl[i]; 503 1.1 xtraeme 504 1.1 xtraeme sge->sg_hdr = htole32(ARC_SGE_64BIT | dmap->dm_segs[i].ds_len); 505 1.1 xtraeme addr = dmap->dm_segs[i].ds_addr; 506 1.1 xtraeme sge->sg_hi_addr = htole32((uint32_t)(addr >> 32)); 507 1.1 xtraeme sge->sg_lo_addr = htole32((uint32_t)addr); 508 1.1 xtraeme } 509 1.1 xtraeme 510 1.1 xtraeme bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize, 511 1.1 xtraeme (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD : 512 1.1 xtraeme BUS_DMASYNC_PREWRITE); 513 1.1 xtraeme 514 1.1 xtraeme return 0; 515 1.1 xtraeme } 516 1.1 xtraeme 517 1.1 xtraeme void 518 1.1 xtraeme arc_scsi_cmd_done(struct arc_softc *sc, struct arc_ccb *ccb, uint32_t reg) 519 1.1 xtraeme { 520 1.1 xtraeme struct scsipi_xfer *xs = ccb->ccb_xs; 521 1.1 xtraeme struct arc_msg_scsicmd *cmd; 522 1.1 xtraeme 523 1.1 xtraeme if (xs->datalen != 0) { 524 1.1 xtraeme bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0, 525 1.1 xtraeme ccb->ccb_dmamap->dm_mapsize, 526 1.1 xtraeme (xs->xs_control & XS_CTL_DATA_IN) ? 527 1.1 xtraeme BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 528 1.1 xtraeme bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap); 529 1.1 xtraeme } 530 1.1 xtraeme 531 1.1 xtraeme /* timeout_del */ 532 1.1 xtraeme xs->status |= XS_STS_DONE; 533 1.1 xtraeme 534 1.1 xtraeme if (reg & ARC_REG_REPLY_QUEUE_ERR) { 535 1.1 xtraeme cmd = &ccb->ccb_cmd->cmd; 536 1.1 xtraeme 537 1.1 xtraeme switch (cmd->status) { 538 1.1 xtraeme case ARC_MSG_STATUS_SELTIMEOUT: 539 1.1 xtraeme case ARC_MSG_STATUS_ABORTED: 540 1.1 xtraeme case ARC_MSG_STATUS_INIT_FAIL: 541 1.1 xtraeme xs->status = SCSI_OK; 542 1.1 xtraeme xs->error = XS_SELTIMEOUT; 543 1.1 xtraeme break; 544 1.1 xtraeme 545 1.1 xtraeme case SCSI_CHECK: 546 1.1 xtraeme memset(&xs->sense, 0, sizeof(xs->sense)); 547 1.1 xtraeme memcpy(&xs->sense, cmd->sense_data, 548 1.38 riastrad uimin(ARC_MSG_SENSELEN, sizeof(xs->sense))); 549 1.1 xtraeme xs->sense.scsi_sense.response_code = 550 1.1 xtraeme SSD_RCODE_VALID | 0x70; 551 1.1 xtraeme xs->status = SCSI_CHECK; 552 1.1 xtraeme xs->error = XS_SENSE; 553 1.1 xtraeme xs->resid = 0; 554 1.1 xtraeme break; 555 1.1 xtraeme 556 1.1 xtraeme default: 557 1.1 xtraeme /* unknown device status */ 558 1.1 xtraeme xs->error = XS_BUSY; /* try again later? */ 559 1.1 xtraeme xs->status = SCSI_BUSY; 560 1.1 xtraeme break; 561 1.1 xtraeme } 562 1.1 xtraeme } else { 563 1.1 xtraeme xs->status = SCSI_OK; 564 1.1 xtraeme xs->error = XS_NOERROR; 565 1.1 xtraeme xs->resid = 0; 566 1.1 xtraeme } 567 1.1 xtraeme 568 1.1 xtraeme arc_put_ccb(sc, ccb); 569 1.1 xtraeme scsipi_done(xs); 570 1.1 xtraeme } 571 1.1 xtraeme 572 1.1 xtraeme int 573 1.1 xtraeme arc_complete(struct arc_softc *sc, struct arc_ccb *nccb, int timeout) 574 1.1 xtraeme { 575 1.1 xtraeme struct arc_ccb *ccb = NULL; 576 1.1 xtraeme char *kva = ARC_DMA_KVA(sc->sc_requests); 577 1.1 xtraeme struct arc_io_cmd *cmd; 578 1.1 xtraeme uint32_t reg; 579 1.1 xtraeme 580 1.1 xtraeme do { 581 1.1 xtraeme reg = arc_pop(sc); 582 1.1 xtraeme if (reg == 0xffffffff) { 583 1.1 xtraeme if (timeout-- == 0) 584 1.1 xtraeme return 1; 585 1.1 xtraeme 586 1.1 xtraeme delay(1000); 587 1.1 xtraeme continue; 588 1.1 xtraeme } 589 1.1 xtraeme 590 1.1 xtraeme cmd = (struct arc_io_cmd *)(kva + 591 1.1 xtraeme ((reg << ARC_REG_REPLY_QUEUE_ADDR_SHIFT) - 592 1.1 xtraeme ARC_DMA_DVA(sc->sc_requests))); 593 1.1 xtraeme ccb = &sc->sc_ccbs[htole32(cmd->cmd.context)]; 594 1.1 xtraeme 595 1.1 xtraeme bus_dmamap_sync(sc->sc_dmat, ARC_DMA_MAP(sc->sc_requests), 596 1.1 xtraeme ccb->ccb_offset, ARC_MAX_IOCMDLEN, 597 1.1 xtraeme BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 598 1.1 xtraeme 599 1.1 xtraeme arc_scsi_cmd_done(sc, ccb, reg); 600 1.1 xtraeme } while (nccb != ccb); 601 1.1 xtraeme 602 1.1 xtraeme return 0; 603 1.1 xtraeme } 604 1.1 xtraeme 605 1.1 xtraeme int 606 1.19 xtraeme arc_map_pci_resources(device_t self, struct pci_attach_args *pa) 607 1.1 xtraeme { 608 1.19 xtraeme struct arc_softc *sc = device_private(self); 609 1.1 xtraeme pcireg_t memtype; 610 1.1 xtraeme pci_intr_handle_t ih; 611 1.31 christos char intrbuf[PCI_INTRSTR_LEN]; 612 1.1 xtraeme 613 1.1 xtraeme sc->sc_pc = pa->pa_pc; 614 1.1 xtraeme sc->sc_tag = pa->pa_tag; 615 1.1 xtraeme sc->sc_dmat = pa->pa_dmat; 616 1.1 xtraeme 617 1.1 xtraeme memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, ARC_PCI_BAR); 618 1.1 xtraeme if (pci_mapreg_map(pa, ARC_PCI_BAR, memtype, 0, &sc->sc_iot, 619 1.1 xtraeme &sc->sc_ioh, NULL, &sc->sc_ios) != 0) { 620 1.1 xtraeme aprint_error(": unable to map system interface register\n"); 621 1.1 xtraeme return 1; 622 1.1 xtraeme } 623 1.1 xtraeme 624 1.1 xtraeme if (pci_intr_map(pa, &ih) != 0) { 625 1.1 xtraeme aprint_error(": unable to map interrupt\n"); 626 1.1 xtraeme goto unmap; 627 1.1 xtraeme } 628 1.1 xtraeme 629 1.37 mlelstv pci_intr_setattr(pa->pa_pc, &ih, PCI_INTR_MPSAFE, true); 630 1.37 mlelstv 631 1.39 jdolecek sc->sc_ih = pci_intr_establish_xname(pa->pa_pc, ih, IPL_BIO, 632 1.39 jdolecek arc_intr, sc, device_xname(self)); 633 1.1 xtraeme if (sc->sc_ih == NULL) { 634 1.1 xtraeme aprint_error(": unable to map interrupt [2]\n"); 635 1.1 xtraeme goto unmap; 636 1.1 xtraeme } 637 1.10 xtraeme 638 1.10 xtraeme aprint_normal("\n"); 639 1.19 xtraeme aprint_normal_dev(self, "interrupting at %s\n", 640 1.31 christos pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf))); 641 1.1 xtraeme 642 1.1 xtraeme return 0; 643 1.1 xtraeme 644 1.1 xtraeme unmap: 645 1.1 xtraeme bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 646 1.1 xtraeme sc->sc_ios = 0; 647 1.1 xtraeme return 1; 648 1.1 xtraeme } 649 1.1 xtraeme 650 1.1 xtraeme void 651 1.1 xtraeme arc_unmap_pci_resources(struct arc_softc *sc) 652 1.1 xtraeme { 653 1.1 xtraeme pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 654 1.1 xtraeme bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 655 1.1 xtraeme sc->sc_ios = 0; 656 1.1 xtraeme } 657 1.1 xtraeme 658 1.1 xtraeme int 659 1.19 xtraeme arc_query_firmware(device_t self) 660 1.1 xtraeme { 661 1.19 xtraeme struct arc_softc *sc = device_private(self); 662 1.1 xtraeme struct arc_msg_firmware_info fwinfo; 663 1.1 xtraeme char string[81]; /* sizeof(vendor)*2+1 */ 664 1.1 xtraeme 665 1.1 xtraeme if (arc_wait_eq(sc, ARC_REG_OUTB_ADDR1, ARC_REG_OUTB_ADDR1_FIRMWARE_OK, 666 1.1 xtraeme ARC_REG_OUTB_ADDR1_FIRMWARE_OK) != 0) { 667 1.19 xtraeme aprint_debug_dev(self, "timeout waiting for firmware ok\n"); 668 1.1 xtraeme return 1; 669 1.1 xtraeme } 670 1.1 xtraeme 671 1.1 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_GET_CONFIG) != 0) { 672 1.19 xtraeme aprint_debug_dev(self, "timeout waiting for get config\n"); 673 1.3 xtraeme return 1; 674 1.3 xtraeme } 675 1.3 xtraeme 676 1.3 xtraeme if (arc_msg0(sc, ARC_REG_INB_MSG0_START_BGRB) != 0) { 677 1.19 xtraeme aprint_debug_dev(self, "timeout waiting to start bg rebuild\n"); 678 1.1 xtraeme return 1; 679 1.1 xtraeme } 680 1.1 xtraeme 681 1.1 xtraeme arc_read_region(sc, ARC_REG_MSGBUF, &fwinfo, sizeof(fwinfo)); 682 1.1 xtraeme 683 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: signature: 0x%08x\n", 684 1.19 xtraeme device_xname(self), htole32(fwinfo.signature)); 685 1.1 xtraeme 686 1.1 xtraeme if (htole32(fwinfo.signature) != ARC_FWINFO_SIGNATURE_GET_CONFIG) { 687 1.19 xtraeme aprint_error_dev(self, "invalid firmware info from iop\n"); 688 1.1 xtraeme return 1; 689 1.1 xtraeme } 690 1.1 xtraeme 691 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: request_len: %d\n", 692 1.19 xtraeme device_xname(self), htole32(fwinfo.request_len)); 693 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: queue_len: %d\n", 694 1.19 xtraeme device_xname(self), htole32(fwinfo.queue_len)); 695 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: sdram_size: %d\n", 696 1.19 xtraeme device_xname(self), htole32(fwinfo.sdram_size)); 697 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: sata_ports: %d\n", 698 1.19 xtraeme device_xname(self), htole32(fwinfo.sata_ports)); 699 1.1 xtraeme 700 1.33 christos strnvisx(string, sizeof(string), fwinfo.vendor, sizeof(fwinfo.vendor), 701 1.33 christos VIS_TRIM|VIS_SAFE|VIS_OCTAL); 702 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: vendor: \"%s\"\n", 703 1.19 xtraeme device_xname(self), string); 704 1.1 xtraeme 705 1.33 christos strnvisx(string, sizeof(string), fwinfo.model, sizeof(fwinfo.model), 706 1.33 christos VIS_TRIM|VIS_SAFE|VIS_OCTAL); 707 1.19 xtraeme aprint_normal_dev(self, "Areca %s Host Adapter RAID controller\n", 708 1.19 xtraeme string); 709 1.1 xtraeme 710 1.33 christos strnvisx(string, sizeof(string), fwinfo.fw_version, 711 1.33 christos sizeof(fwinfo.fw_version), VIS_TRIM|VIS_SAFE|VIS_OCTAL); 712 1.1 xtraeme DNPRINTF(ARC_D_INIT, "%s: version: \"%s\"\n", 713 1.19 xtraeme device_xname(self), string); 714 1.1 xtraeme 715 1.19 xtraeme aprint_normal_dev(self, "%d ports, %dMB SDRAM, firmware <%s>\n", 716 1.19 xtraeme htole32(fwinfo.sata_ports), htole32(fwinfo.sdram_size), string); 717 1.9 xtraeme 718 1.1 xtraeme if (htole32(fwinfo.request_len) != ARC_MAX_IOCMDLEN) { 719 1.19 xtraeme aprint_error_dev(self, 720 1.19 xtraeme "unexpected request frame size (%d != %d)\n", 721 1.1 xtraeme htole32(fwinfo.request_len), ARC_MAX_IOCMDLEN); 722 1.1 xtraeme return 1; 723 1.1 xtraeme } 724 1.1 xtraeme 725 1.1 xtraeme sc->sc_req_count = htole32(fwinfo.queue_len); 726 1.1 xtraeme 727 1.1 xtraeme return 0; 728 1.1 xtraeme } 729 1.1 xtraeme 730 1.1 xtraeme #if NBIO > 0 731 1.1 xtraeme static int 732 1.19 xtraeme arc_bioctl(device_t self, u_long cmd, void *addr) 733 1.1 xtraeme { 734 1.1 xtraeme struct arc_softc *sc = device_private(self); 735 1.1 xtraeme int error = 0; 736 1.1 xtraeme 737 1.1 xtraeme switch (cmd) { 738 1.1 xtraeme case BIOCINQ: 739 1.1 xtraeme error = arc_bio_inq(sc, (struct bioc_inq *)addr); 740 1.1 xtraeme break; 741 1.1 xtraeme 742 1.1 xtraeme case BIOCVOL: 743 1.1 xtraeme error = arc_bio_vol(sc, (struct bioc_vol *)addr); 744 1.1 xtraeme break; 745 1.1 xtraeme 746 1.1 xtraeme case BIOCDISK: 747 1.9 xtraeme error = arc_bio_disk_volume(sc, (struct bioc_disk *)addr); 748 1.9 xtraeme break; 749 1.9 xtraeme 750 1.9 xtraeme case BIOCDISK_NOVOL: 751 1.9 xtraeme error = arc_bio_disk_novol(sc, (struct bioc_disk *)addr); 752 1.1 xtraeme break; 753 1.1 xtraeme 754 1.1 xtraeme case BIOCALARM: 755 1.1 xtraeme error = arc_bio_alarm(sc, (struct bioc_alarm *)addr); 756 1.1 xtraeme break; 757 1.1 xtraeme 758 1.9 xtraeme case BIOCSETSTATE: 759 1.9 xtraeme error = arc_bio_setstate(sc, (struct bioc_setstate *)addr); 760 1.9 xtraeme break; 761 1.9 xtraeme 762 1.9 xtraeme case BIOCVOLOPS: 763 1.9 xtraeme error = arc_bio_volops(sc, (struct bioc_volops *)addr); 764 1.9 xtraeme break; 765 1.9 xtraeme 766 1.1 xtraeme default: 767 1.1 xtraeme error = ENOTTY; 768 1.1 xtraeme break; 769 1.1 xtraeme } 770 1.1 xtraeme 771 1.1 xtraeme return error; 772 1.1 xtraeme } 773 1.1 xtraeme 774 1.1 xtraeme static int 775 1.9 xtraeme arc_fw_parse_status_code(struct arc_softc *sc, uint8_t *reply) 776 1.9 xtraeme { 777 1.9 xtraeme switch (*reply) { 778 1.9 xtraeme case ARC_FW_CMD_RAIDINVAL: 779 1.9 xtraeme printf("%s: firmware error (invalid raid set)\n", 780 1.19 xtraeme device_xname(sc->sc_dev)); 781 1.9 xtraeme return EINVAL; 782 1.9 xtraeme case ARC_FW_CMD_VOLINVAL: 783 1.9 xtraeme printf("%s: firmware error (invalid volume set)\n", 784 1.19 xtraeme device_xname(sc->sc_dev)); 785 1.9 xtraeme return EINVAL; 786 1.9 xtraeme case ARC_FW_CMD_NORAID: 787 1.9 xtraeme printf("%s: firmware error (unexistent raid set)\n", 788 1.19 xtraeme device_xname(sc->sc_dev)); 789 1.9 xtraeme return ENODEV; 790 1.9 xtraeme case ARC_FW_CMD_NOVOLUME: 791 1.9 xtraeme printf("%s: firmware error (unexistent volume set)\n", 792 1.19 xtraeme device_xname(sc->sc_dev)); 793 1.9 xtraeme return ENODEV; 794 1.9 xtraeme case ARC_FW_CMD_NOPHYSDRV: 795 1.9 xtraeme printf("%s: firmware error (unexistent physical drive)\n", 796 1.19 xtraeme device_xname(sc->sc_dev)); 797 1.9 xtraeme return ENODEV; 798 1.9 xtraeme case ARC_FW_CMD_PARAM_ERR: 799 1.9 xtraeme printf("%s: firmware error (parameter error)\n", 800 1.19 xtraeme device_xname(sc->sc_dev)); 801 1.9 xtraeme return EINVAL; 802 1.9 xtraeme case ARC_FW_CMD_UNSUPPORTED: 803 1.9 xtraeme printf("%s: firmware error (unsupported command)\n", 804 1.19 xtraeme device_xname(sc->sc_dev)); 805 1.9 xtraeme return EOPNOTSUPP; 806 1.9 xtraeme case ARC_FW_CMD_DISKCFG_CHGD: 807 1.9 xtraeme printf("%s: firmware error (disk configuration changed)\n", 808 1.19 xtraeme device_xname(sc->sc_dev)); 809 1.9 xtraeme return EINVAL; 810 1.9 xtraeme case ARC_FW_CMD_PASS_INVAL: 811 1.9 xtraeme printf("%s: firmware error (invalid password)\n", 812 1.19 xtraeme device_xname(sc->sc_dev)); 813 1.9 xtraeme return EINVAL; 814 1.9 xtraeme case ARC_FW_CMD_NODISKSPACE: 815 1.9 xtraeme printf("%s: firmware error (no disk space available)\n", 816 1.19 xtraeme device_xname(sc->sc_dev)); 817 1.9 xtraeme return EOPNOTSUPP; 818 1.9 xtraeme case ARC_FW_CMD_CHECKSUM_ERR: 819 1.9 xtraeme printf("%s: firmware error (checksum error)\n", 820 1.19 xtraeme device_xname(sc->sc_dev)); 821 1.9 xtraeme return EINVAL; 822 1.9 xtraeme case ARC_FW_CMD_PASS_REQD: 823 1.9 xtraeme printf("%s: firmware error (password required)\n", 824 1.19 xtraeme device_xname(sc->sc_dev)); 825 1.9 xtraeme return EPERM; 826 1.9 xtraeme case ARC_FW_CMD_OK: 827 1.9 xtraeme default: 828 1.9 xtraeme return 0; 829 1.9 xtraeme } 830 1.9 xtraeme } 831 1.9 xtraeme 832 1.9 xtraeme static int 833 1.1 xtraeme arc_bio_alarm(struct arc_softc *sc, struct bioc_alarm *ba) 834 1.1 xtraeme { 835 1.1 xtraeme uint8_t request[2], reply[1]; 836 1.1 xtraeme size_t len; 837 1.1 xtraeme int error = 0; 838 1.1 xtraeme 839 1.1 xtraeme switch (ba->ba_opcode) { 840 1.1 xtraeme case BIOC_SAENABLE: 841 1.1 xtraeme case BIOC_SADISABLE: 842 1.1 xtraeme request[0] = ARC_FW_SET_ALARM; 843 1.1 xtraeme request[1] = (ba->ba_opcode == BIOC_SAENABLE) ? 844 1.1 xtraeme ARC_FW_SET_ALARM_ENABLE : ARC_FW_SET_ALARM_DISABLE; 845 1.1 xtraeme len = sizeof(request); 846 1.1 xtraeme 847 1.1 xtraeme break; 848 1.1 xtraeme 849 1.1 xtraeme case BIOC_SASILENCE: 850 1.1 xtraeme request[0] = ARC_FW_MUTE_ALARM; 851 1.1 xtraeme len = 1; 852 1.1 xtraeme 853 1.1 xtraeme break; 854 1.1 xtraeme 855 1.1 xtraeme case BIOC_GASTATUS: 856 1.1 xtraeme /* system info is too big/ugly to deal with here */ 857 1.1 xtraeme return arc_bio_alarm_state(sc, ba); 858 1.1 xtraeme 859 1.1 xtraeme default: 860 1.1 xtraeme return EOPNOTSUPP; 861 1.1 xtraeme } 862 1.1 xtraeme 863 1.1 xtraeme error = arc_msgbuf(sc, request, len, reply, sizeof(reply)); 864 1.1 xtraeme if (error != 0) 865 1.1 xtraeme return error; 866 1.1 xtraeme 867 1.9 xtraeme return arc_fw_parse_status_code(sc, &reply[0]); 868 1.1 xtraeme } 869 1.1 xtraeme 870 1.1 xtraeme static int 871 1.1 xtraeme arc_bio_alarm_state(struct arc_softc *sc, struct bioc_alarm *ba) 872 1.1 xtraeme { 873 1.1 xtraeme struct arc_fw_sysinfo *sysinfo; 874 1.9 xtraeme uint8_t request; 875 1.1 xtraeme int error = 0; 876 1.1 xtraeme 877 1.10 xtraeme sysinfo = kmem_zalloc(sizeof(*sysinfo), KM_SLEEP); 878 1.1 xtraeme 879 1.1 xtraeme request = ARC_FW_SYSINFO; 880 1.1 xtraeme error = arc_msgbuf(sc, &request, sizeof(request), 881 1.1 xtraeme sysinfo, sizeof(struct arc_fw_sysinfo)); 882 1.1 xtraeme 883 1.1 xtraeme if (error != 0) 884 1.1 xtraeme goto out; 885 1.1 xtraeme 886 1.1 xtraeme ba->ba_status = sysinfo->alarm; 887 1.1 xtraeme 888 1.1 xtraeme out: 889 1.7 xtraeme kmem_free(sysinfo, sizeof(*sysinfo)); 890 1.1 xtraeme return error; 891 1.1 xtraeme } 892 1.1 xtraeme 893 1.9 xtraeme static int 894 1.9 xtraeme arc_bio_volops(struct arc_softc *sc, struct bioc_volops *bc) 895 1.9 xtraeme { 896 1.9 xtraeme /* to create a raid set */ 897 1.9 xtraeme struct req_craidset { 898 1.9 xtraeme uint8_t cmdcode; 899 1.9 xtraeme uint32_t devmask; 900 1.9 xtraeme uint8_t raidset_name[16]; 901 1.9 xtraeme } __packed; 902 1.9 xtraeme 903 1.9 xtraeme /* to create a volume set */ 904 1.9 xtraeme struct req_cvolset { 905 1.9 xtraeme uint8_t cmdcode; 906 1.9 xtraeme uint8_t raidset; 907 1.9 xtraeme uint8_t volset_name[16]; 908 1.9 xtraeme uint64_t capacity; 909 1.9 xtraeme uint8_t raidlevel; 910 1.9 xtraeme uint8_t stripe; 911 1.9 xtraeme uint8_t scsi_chan; 912 1.9 xtraeme uint8_t scsi_target; 913 1.9 xtraeme uint8_t scsi_lun; 914 1.9 xtraeme uint8_t tagqueue; 915 1.9 xtraeme uint8_t cache; 916 1.9 xtraeme uint8_t speed; 917 1.9 xtraeme uint8_t quick_init; 918 1.9 xtraeme } __packed; 919 1.9 xtraeme 920 1.9 xtraeme struct scsibus_softc *scsibus_sc = NULL; 921 1.9 xtraeme struct req_craidset req_craidset; 922 1.9 xtraeme struct req_cvolset req_cvolset; 923 1.9 xtraeme uint8_t request[2]; 924 1.9 xtraeme uint8_t reply[1]; 925 1.9 xtraeme int error = 0; 926 1.9 xtraeme 927 1.9 xtraeme switch (bc->bc_opcode) { 928 1.9 xtraeme case BIOC_VCREATE_VOLUME: 929 1.9 xtraeme { 930 1.9 xtraeme /* 931 1.9 xtraeme * Zero out the structs so that we use some defaults 932 1.9 xtraeme * in raid and volume sets. 933 1.9 xtraeme */ 934 1.9 xtraeme memset(&req_craidset, 0, sizeof(req_craidset)); 935 1.9 xtraeme memset(&req_cvolset, 0, sizeof(req_cvolset)); 936 1.9 xtraeme 937 1.9 xtraeme /* 938 1.9 xtraeme * Firstly we have to create the raid set and 939 1.9 xtraeme * use the default name for all them. 940 1.9 xtraeme */ 941 1.9 xtraeme req_craidset.cmdcode = ARC_FW_CREATE_RAIDSET; 942 1.9 xtraeme req_craidset.devmask = bc->bc_devmask; 943 1.9 xtraeme error = arc_msgbuf(sc, &req_craidset, sizeof(req_craidset), 944 1.9 xtraeme reply, sizeof(reply)); 945 1.9 xtraeme if (error != 0) 946 1.9 xtraeme return error; 947 1.9 xtraeme 948 1.9 xtraeme error = arc_fw_parse_status_code(sc, &reply[0]); 949 1.9 xtraeme if (error) { 950 1.9 xtraeme printf("%s: create raidset%d failed\n", 951 1.19 xtraeme device_xname(sc->sc_dev), bc->bc_volid); 952 1.9 xtraeme return error; 953 1.9 xtraeme } 954 1.9 xtraeme 955 1.9 xtraeme /* 956 1.9 xtraeme * At this point the raid set was created, so it's 957 1.9 xtraeme * time to create the volume set. 958 1.9 xtraeme */ 959 1.9 xtraeme req_cvolset.cmdcode = ARC_FW_CREATE_VOLUME; 960 1.9 xtraeme req_cvolset.raidset = bc->bc_volid; 961 1.9 xtraeme req_cvolset.capacity = bc->bc_size * ARC_BLOCKSIZE; 962 1.9 xtraeme 963 1.9 xtraeme /* 964 1.9 xtraeme * Set the RAID level. 965 1.9 xtraeme */ 966 1.9 xtraeme switch (bc->bc_level) { 967 1.9 xtraeme case 0: 968 1.9 xtraeme case 1: 969 1.9 xtraeme req_cvolset.raidlevel = bc->bc_level; 970 1.9 xtraeme break; 971 1.18 xtraeme case BIOC_SVOL_RAID10: 972 1.18 xtraeme req_cvolset.raidlevel = 1; 973 1.18 xtraeme break; 974 1.9 xtraeme case 3: 975 1.9 xtraeme req_cvolset.raidlevel = ARC_FW_VOL_RAIDLEVEL_3; 976 1.9 xtraeme break; 977 1.9 xtraeme case 5: 978 1.9 xtraeme req_cvolset.raidlevel = ARC_FW_VOL_RAIDLEVEL_5; 979 1.9 xtraeme break; 980 1.9 xtraeme case 6: 981 1.9 xtraeme req_cvolset.raidlevel = ARC_FW_VOL_RAIDLEVEL_6; 982 1.9 xtraeme break; 983 1.9 xtraeme default: 984 1.9 xtraeme return EOPNOTSUPP; 985 1.9 xtraeme } 986 1.9 xtraeme 987 1.9 xtraeme /* 988 1.9 xtraeme * Set the stripe size. 989 1.9 xtraeme */ 990 1.9 xtraeme switch (bc->bc_stripe) { 991 1.9 xtraeme case 4: 992 1.9 xtraeme req_cvolset.stripe = 0; 993 1.9 xtraeme break; 994 1.9 xtraeme case 8: 995 1.9 xtraeme req_cvolset.stripe = 1; 996 1.9 xtraeme break; 997 1.9 xtraeme case 16: 998 1.9 xtraeme req_cvolset.stripe = 2; 999 1.9 xtraeme break; 1000 1.9 xtraeme case 32: 1001 1.9 xtraeme req_cvolset.stripe = 3; 1002 1.9 xtraeme break; 1003 1.9 xtraeme case 64: 1004 1.9 xtraeme req_cvolset.stripe = 4; 1005 1.9 xtraeme break; 1006 1.9 xtraeme case 128: 1007 1.9 xtraeme req_cvolset.stripe = 5; 1008 1.9 xtraeme break; 1009 1.9 xtraeme default: 1010 1.9 xtraeme req_cvolset.stripe = 4; /* by default 64K */ 1011 1.9 xtraeme break; 1012 1.9 xtraeme } 1013 1.9 xtraeme 1014 1.9 xtraeme req_cvolset.scsi_chan = bc->bc_channel; 1015 1.9 xtraeme req_cvolset.scsi_target = bc->bc_target; 1016 1.9 xtraeme req_cvolset.scsi_lun = bc->bc_lun; 1017 1.9 xtraeme req_cvolset.tagqueue = 1; /* always enabled */ 1018 1.9 xtraeme req_cvolset.cache = 1; /* always enabled */ 1019 1.9 xtraeme req_cvolset.speed = 4; /* always max speed */ 1020 1.9 xtraeme 1021 1.18 xtraeme /* RAID 1 and 1+0 levels need foreground initialization */ 1022 1.18 xtraeme if (bc->bc_level == 1 || bc->bc_level == BIOC_SVOL_RAID10) 1023 1.17 xtraeme req_cvolset.quick_init = 1; /* foreground init */ 1024 1.17 xtraeme 1025 1.9 xtraeme error = arc_msgbuf(sc, &req_cvolset, sizeof(req_cvolset), 1026 1.9 xtraeme reply, sizeof(reply)); 1027 1.9 xtraeme if (error != 0) 1028 1.9 xtraeme return error; 1029 1.9 xtraeme 1030 1.9 xtraeme error = arc_fw_parse_status_code(sc, &reply[0]); 1031 1.9 xtraeme if (error) { 1032 1.9 xtraeme printf("%s: create volumeset%d failed\n", 1033 1.19 xtraeme device_xname(sc->sc_dev), bc->bc_volid); 1034 1.9 xtraeme return error; 1035 1.9 xtraeme } 1036 1.9 xtraeme 1037 1.9 xtraeme /* 1038 1.17 xtraeme * If we are creating a RAID 1 or RAID 1+0 volume, 1039 1.17 xtraeme * the volume will be created immediately but it won't 1040 1.17 xtraeme * be available until the initialization is done... so 1041 1.17 xtraeme * don't bother attaching the sd(4) device. 1042 1.17 xtraeme */ 1043 1.18 xtraeme if (bc->bc_level == 1 || bc->bc_level == BIOC_SVOL_RAID10) 1044 1.17 xtraeme break; 1045 1.17 xtraeme 1046 1.17 xtraeme /* 1047 1.9 xtraeme * Do a rescan on the bus to attach the device associated 1048 1.9 xtraeme * with the new volume. 1049 1.9 xtraeme */ 1050 1.9 xtraeme scsibus_sc = device_private(sc->sc_scsibus_dv); 1051 1.9 xtraeme (void)scsi_probe_bus(scsibus_sc, bc->bc_target, bc->bc_lun); 1052 1.9 xtraeme 1053 1.9 xtraeme break; 1054 1.9 xtraeme } 1055 1.9 xtraeme case BIOC_VREMOVE_VOLUME: 1056 1.9 xtraeme { 1057 1.9 xtraeme /* 1058 1.9 xtraeme * Remove the volume set specified in bc_volid. 1059 1.9 xtraeme */ 1060 1.9 xtraeme request[0] = ARC_FW_DELETE_VOLUME; 1061 1.9 xtraeme request[1] = bc->bc_volid; 1062 1.9 xtraeme error = arc_msgbuf(sc, request, sizeof(request), 1063 1.9 xtraeme reply, sizeof(reply)); 1064 1.9 xtraeme if (error != 0) 1065 1.9 xtraeme return error; 1066 1.9 xtraeme 1067 1.9 xtraeme error = arc_fw_parse_status_code(sc, &reply[0]); 1068 1.9 xtraeme if (error) { 1069 1.9 xtraeme printf("%s: delete volumeset%d failed\n", 1070 1.19 xtraeme device_xname(sc->sc_dev), bc->bc_volid); 1071 1.9 xtraeme return error; 1072 1.9 xtraeme } 1073 1.9 xtraeme 1074 1.9 xtraeme /* 1075 1.9 xtraeme * Detach the sd(4) device associated with the volume, 1076 1.9 xtraeme * but if there's an error don't make it a priority. 1077 1.9 xtraeme */ 1078 1.9 xtraeme error = scsipi_target_detach(&sc->sc_chan, bc->bc_target, 1079 1.9 xtraeme bc->bc_lun, 0); 1080 1.9 xtraeme if (error) 1081 1.9 xtraeme printf("%s: couldn't detach sd device for volume %d " 1082 1.9 xtraeme "at %u:%u.%u (error=%d)\n", 1083 1.19 xtraeme device_xname(sc->sc_dev), bc->bc_volid, 1084 1.9 xtraeme bc->bc_channel, bc->bc_target, bc->bc_lun, error); 1085 1.9 xtraeme 1086 1.9 xtraeme /* 1087 1.9 xtraeme * and remove the raid set specified in bc_volid, 1088 1.9 xtraeme * we only care about volumes. 1089 1.9 xtraeme */ 1090 1.9 xtraeme request[0] = ARC_FW_DELETE_RAIDSET; 1091 1.9 xtraeme request[1] = bc->bc_volid; 1092 1.9 xtraeme error = arc_msgbuf(sc, request, sizeof(request), 1093 1.9 xtraeme reply, sizeof(reply)); 1094 1.9 xtraeme if (error != 0) 1095 1.9 xtraeme return error; 1096 1.9 xtraeme 1097 1.9 xtraeme error = arc_fw_parse_status_code(sc, &reply[0]); 1098 1.9 xtraeme if (error) { 1099 1.9 xtraeme printf("%s: delete raidset%d failed\n", 1100 1.19 xtraeme device_xname(sc->sc_dev), bc->bc_volid); 1101 1.9 xtraeme return error; 1102 1.9 xtraeme } 1103 1.9 xtraeme 1104 1.9 xtraeme break; 1105 1.9 xtraeme } 1106 1.9 xtraeme default: 1107 1.9 xtraeme return EOPNOTSUPP; 1108 1.9 xtraeme } 1109 1.9 xtraeme 1110 1.9 xtraeme return error; 1111 1.9 xtraeme } 1112 1.9 xtraeme 1113 1.9 xtraeme static int 1114 1.9 xtraeme arc_bio_setstate(struct arc_softc *sc, struct bioc_setstate *bs) 1115 1.9 xtraeme { 1116 1.9 xtraeme /* for a hotspare disk */ 1117 1.9 xtraeme struct request_hs { 1118 1.9 xtraeme uint8_t cmdcode; 1119 1.9 xtraeme uint32_t devmask; 1120 1.9 xtraeme } __packed; 1121 1.9 xtraeme 1122 1.9 xtraeme /* for a pass-through disk */ 1123 1.9 xtraeme struct request_pt { 1124 1.9 xtraeme uint8_t cmdcode; 1125 1.9 xtraeme uint8_t devid; 1126 1.9 xtraeme uint8_t scsi_chan; 1127 1.9 xtraeme uint8_t scsi_id; 1128 1.9 xtraeme uint8_t scsi_lun; 1129 1.9 xtraeme uint8_t tagged_queue; 1130 1.9 xtraeme uint8_t cache_mode; 1131 1.9 xtraeme uint8_t max_speed; 1132 1.9 xtraeme } __packed; 1133 1.9 xtraeme 1134 1.9 xtraeme struct scsibus_softc *scsibus_sc = NULL; 1135 1.9 xtraeme struct request_hs req_hs; /* to add/remove hotspare */ 1136 1.9 xtraeme struct request_pt req_pt; /* to add a pass-through */ 1137 1.9 xtraeme uint8_t req_gen[2]; 1138 1.9 xtraeme uint8_t reply[1]; 1139 1.9 xtraeme int error = 0; 1140 1.9 xtraeme 1141 1.9 xtraeme switch (bs->bs_status) { 1142 1.9 xtraeme case BIOC_SSHOTSPARE: 1143 1.9 xtraeme { 1144 1.9 xtraeme req_hs.cmdcode = ARC_FW_CREATE_HOTSPARE; 1145 1.9 xtraeme req_hs.devmask = (1 << bs->bs_target); 1146 1.9 xtraeme goto hotspare; 1147 1.9 xtraeme } 1148 1.9 xtraeme case BIOC_SSDELHOTSPARE: 1149 1.9 xtraeme { 1150 1.9 xtraeme req_hs.cmdcode = ARC_FW_DELETE_HOTSPARE; 1151 1.9 xtraeme req_hs.devmask = (1 << bs->bs_target); 1152 1.9 xtraeme goto hotspare; 1153 1.9 xtraeme } 1154 1.9 xtraeme case BIOC_SSPASSTHRU: 1155 1.9 xtraeme { 1156 1.9 xtraeme req_pt.cmdcode = ARC_FW_CREATE_PASSTHRU; 1157 1.9 xtraeme req_pt.devid = bs->bs_other_id; /* this wants device# */ 1158 1.9 xtraeme req_pt.scsi_chan = bs->bs_channel; 1159 1.9 xtraeme req_pt.scsi_id = bs->bs_target; 1160 1.9 xtraeme req_pt.scsi_lun = bs->bs_lun; 1161 1.9 xtraeme req_pt.tagged_queue = 1; /* always enabled */ 1162 1.9 xtraeme req_pt.cache_mode = 1; /* always enabled */ 1163 1.9 xtraeme req_pt.max_speed = 4; /* always max speed */ 1164 1.9 xtraeme 1165 1.9 xtraeme error = arc_msgbuf(sc, &req_pt, sizeof(req_pt), 1166 1.9 xtraeme reply, sizeof(reply)); 1167 1.9 xtraeme if (error != 0) 1168 1.9 xtraeme return error; 1169 1.9 xtraeme 1170 1.9 xtraeme /* 1171 1.9 xtraeme * Do a rescan on the bus to attach the new device 1172 1.9 xtraeme * associated with the pass-through disk. 1173 1.9 xtraeme */ 1174 1.9 xtraeme scsibus_sc = device_private(sc->sc_scsibus_dv); 1175 1.9 xtraeme (void)scsi_probe_bus(scsibus_sc, bs->bs_target, bs->bs_lun); 1176 1.9 xtraeme 1177 1.9 xtraeme goto out; 1178 1.9 xtraeme } 1179 1.9 xtraeme case BIOC_SSDELPASSTHRU: 1180 1.9 xtraeme { 1181 1.9 xtraeme req_gen[0] = ARC_FW_DELETE_PASSTHRU; 1182 1.9 xtraeme req_gen[1] = bs->bs_target; 1183 1.9 xtraeme error = arc_msgbuf(sc, &req_gen, sizeof(req_gen), 1184 1.9 xtraeme reply, sizeof(reply)); 1185 1.9 xtraeme if (error != 0) 1186 1.9 xtraeme return error; 1187 1.9 xtraeme 1188 1.9 xtraeme /* 1189 1.9 xtraeme * Detach the sd device associated with this pass-through disk. 1190 1.9 xtraeme */ 1191 1.9 xtraeme error = scsipi_target_detach(&sc->sc_chan, bs->bs_target, 1192 1.9 xtraeme bs->bs_lun, 0); 1193 1.9 xtraeme if (error) 1194 1.9 xtraeme printf("%s: couldn't detach sd device for the " 1195 1.9 xtraeme "pass-through disk at %u:%u.%u (error=%d)\n", 1196 1.19 xtraeme device_xname(sc->sc_dev), 1197 1.9 xtraeme bs->bs_channel, bs->bs_target, bs->bs_lun, error); 1198 1.9 xtraeme 1199 1.9 xtraeme goto out; 1200 1.9 xtraeme } 1201 1.9 xtraeme case BIOC_SSCHECKSTART_VOL: 1202 1.9 xtraeme { 1203 1.9 xtraeme req_gen[0] = ARC_FW_START_CHECKVOL; 1204 1.9 xtraeme req_gen[1] = bs->bs_volid; 1205 1.9 xtraeme error = arc_msgbuf(sc, &req_gen, sizeof(req_gen), 1206 1.9 xtraeme reply, sizeof(reply)); 1207 1.9 xtraeme if (error != 0) 1208 1.9 xtraeme return error; 1209 1.9 xtraeme 1210 1.9 xtraeme goto out; 1211 1.9 xtraeme } 1212 1.9 xtraeme case BIOC_SSCHECKSTOP_VOL: 1213 1.9 xtraeme { 1214 1.9 xtraeme uint8_t req = ARC_FW_STOP_CHECKVOL; 1215 1.9 xtraeme error = arc_msgbuf(sc, &req, 1, reply, sizeof(reply)); 1216 1.9 xtraeme if (error != 0) 1217 1.9 xtraeme return error; 1218 1.9 xtraeme 1219 1.9 xtraeme goto out; 1220 1.9 xtraeme } 1221 1.9 xtraeme default: 1222 1.9 xtraeme return EOPNOTSUPP; 1223 1.9 xtraeme } 1224 1.9 xtraeme 1225 1.9 xtraeme hotspare: 1226 1.9 xtraeme error = arc_msgbuf(sc, &req_hs, sizeof(req_hs), 1227 1.9 xtraeme reply, sizeof(reply)); 1228 1.9 xtraeme if (error != 0) 1229 1.9 xtraeme return error; 1230 1.9 xtraeme 1231 1.9 xtraeme out: 1232 1.9 xtraeme return arc_fw_parse_status_code(sc, &reply[0]); 1233 1.9 xtraeme } 1234 1.1 xtraeme 1235 1.1 xtraeme static int 1236 1.1 xtraeme arc_bio_inq(struct arc_softc *sc, struct bioc_inq *bi) 1237 1.1 xtraeme { 1238 1.1 xtraeme uint8_t request[2]; 1239 1.15 xtraeme struct arc_fw_sysinfo *sysinfo = NULL; 1240 1.9 xtraeme struct arc_fw_raidinfo *raidinfo; 1241 1.14 xtraeme int nvols = 0, i; 1242 1.1 xtraeme int error = 0; 1243 1.1 xtraeme 1244 1.10 xtraeme raidinfo = kmem_zalloc(sizeof(*raidinfo), KM_SLEEP); 1245 1.1 xtraeme 1246 1.15 xtraeme if (!sc->sc_maxraidset || !sc->sc_maxvolset || !sc->sc_cchans) { 1247 1.15 xtraeme sysinfo = kmem_zalloc(sizeof(*sysinfo), KM_SLEEP); 1248 1.15 xtraeme 1249 1.15 xtraeme request[0] = ARC_FW_SYSINFO; 1250 1.15 xtraeme error = arc_msgbuf(sc, request, 1, sysinfo, 1251 1.15 xtraeme sizeof(struct arc_fw_sysinfo)); 1252 1.15 xtraeme if (error != 0) 1253 1.15 xtraeme goto out; 1254 1.1 xtraeme 1255 1.15 xtraeme sc->sc_maxraidset = sysinfo->max_raid_set; 1256 1.15 xtraeme sc->sc_maxvolset = sysinfo->max_volume_set; 1257 1.15 xtraeme sc->sc_cchans = sysinfo->ide_channels; 1258 1.15 xtraeme } 1259 1.1 xtraeme 1260 1.9 xtraeme request[0] = ARC_FW_RAIDINFO; 1261 1.14 xtraeme for (i = 0; i < sc->sc_maxraidset; i++) { 1262 1.1 xtraeme request[1] = i; 1263 1.9 xtraeme error = arc_msgbuf(sc, request, sizeof(request), raidinfo, 1264 1.9 xtraeme sizeof(struct arc_fw_raidinfo)); 1265 1.1 xtraeme if (error != 0) 1266 1.1 xtraeme goto out; 1267 1.1 xtraeme 1268 1.22 christos nvols += raidinfo->volumes; 1269 1.1 xtraeme } 1270 1.1 xtraeme 1271 1.19 xtraeme strlcpy(bi->bi_dev, device_xname(sc->sc_dev), sizeof(bi->bi_dev)); 1272 1.1 xtraeme bi->bi_novol = nvols; 1273 1.14 xtraeme bi->bi_nodisk = sc->sc_cchans; 1274 1.9 xtraeme 1275 1.1 xtraeme out: 1276 1.15 xtraeme if (sysinfo) 1277 1.15 xtraeme kmem_free(sysinfo, sizeof(*sysinfo)); 1278 1.9 xtraeme kmem_free(raidinfo, sizeof(*raidinfo)); 1279 1.1 xtraeme return error; 1280 1.1 xtraeme } 1281 1.1 xtraeme 1282 1.1 xtraeme static int 1283 1.1 xtraeme arc_bio_getvol(struct arc_softc *sc, int vol, struct arc_fw_volinfo *volinfo) 1284 1.1 xtraeme { 1285 1.1 xtraeme uint8_t request[2]; 1286 1.1 xtraeme int error = 0; 1287 1.14 xtraeme int nvols = 0, i; 1288 1.1 xtraeme 1289 1.1 xtraeme request[0] = ARC_FW_VOLINFO; 1290 1.14 xtraeme for (i = 0; i < sc->sc_maxvolset; i++) { 1291 1.1 xtraeme request[1] = i; 1292 1.1 xtraeme error = arc_msgbuf(sc, request, sizeof(request), volinfo, 1293 1.1 xtraeme sizeof(struct arc_fw_volinfo)); 1294 1.1 xtraeme if (error != 0) 1295 1.1 xtraeme goto out; 1296 1.1 xtraeme 1297 1.9 xtraeme if (volinfo->capacity == 0 && volinfo->capacity2 == 0) 1298 1.1 xtraeme continue; 1299 1.1 xtraeme 1300 1.1 xtraeme if (nvols == vol) 1301 1.1 xtraeme break; 1302 1.1 xtraeme 1303 1.1 xtraeme nvols++; 1304 1.1 xtraeme } 1305 1.1 xtraeme 1306 1.1 xtraeme if (nvols != vol || 1307 1.9 xtraeme (volinfo->capacity == 0 && volinfo->capacity2 == 0)) { 1308 1.1 xtraeme error = ENODEV; 1309 1.1 xtraeme goto out; 1310 1.1 xtraeme } 1311 1.1 xtraeme 1312 1.1 xtraeme out: 1313 1.1 xtraeme return error; 1314 1.1 xtraeme } 1315 1.1 xtraeme 1316 1.1 xtraeme static int 1317 1.1 xtraeme arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv) 1318 1.1 xtraeme { 1319 1.1 xtraeme struct arc_fw_volinfo *volinfo; 1320 1.1 xtraeme uint64_t blocks; 1321 1.1 xtraeme uint32_t status; 1322 1.1 xtraeme int error = 0; 1323 1.1 xtraeme 1324 1.10 xtraeme volinfo = kmem_zalloc(sizeof(*volinfo), KM_SLEEP); 1325 1.1 xtraeme 1326 1.1 xtraeme error = arc_bio_getvol(sc, bv->bv_volid, volinfo); 1327 1.1 xtraeme if (error != 0) 1328 1.1 xtraeme goto out; 1329 1.1 xtraeme 1330 1.1 xtraeme bv->bv_percent = -1; 1331 1.1 xtraeme bv->bv_seconds = 0; 1332 1.1 xtraeme 1333 1.1 xtraeme status = htole32(volinfo->volume_status); 1334 1.1 xtraeme if (status == 0x0) { 1335 1.1 xtraeme if (htole32(volinfo->fail_mask) == 0x0) 1336 1.1 xtraeme bv->bv_status = BIOC_SVONLINE; 1337 1.1 xtraeme else 1338 1.1 xtraeme bv->bv_status = BIOC_SVDEGRADED; 1339 1.1 xtraeme } else if (status & ARC_FW_VOL_STATUS_NEED_REGEN) { 1340 1.1 xtraeme bv->bv_status = BIOC_SVDEGRADED; 1341 1.1 xtraeme } else if (status & ARC_FW_VOL_STATUS_FAILED) { 1342 1.1 xtraeme bv->bv_status = BIOC_SVOFFLINE; 1343 1.1 xtraeme } else if (status & ARC_FW_VOL_STATUS_INITTING) { 1344 1.1 xtraeme bv->bv_status = BIOC_SVBUILDING; 1345 1.9 xtraeme bv->bv_percent = htole32(volinfo->progress); 1346 1.1 xtraeme } else if (status & ARC_FW_VOL_STATUS_REBUILDING) { 1347 1.1 xtraeme bv->bv_status = BIOC_SVREBUILD; 1348 1.9 xtraeme bv->bv_percent = htole32(volinfo->progress); 1349 1.8 xtraeme } else if (status & ARC_FW_VOL_STATUS_MIGRATING) { 1350 1.8 xtraeme bv->bv_status = BIOC_SVMIGRATING; 1351 1.9 xtraeme bv->bv_percent = htole32(volinfo->progress); 1352 1.9 xtraeme } else if (status & ARC_FW_VOL_STATUS_CHECKING) { 1353 1.9 xtraeme bv->bv_status = BIOC_SVCHECKING; 1354 1.9 xtraeme bv->bv_percent = htole32(volinfo->progress); 1355 1.17 xtraeme } else if (status & ARC_FW_VOL_STATUS_NEED_INIT) { 1356 1.17 xtraeme bv->bv_status = BIOC_SVOFFLINE; 1357 1.17 xtraeme } else { 1358 1.17 xtraeme printf("%s: volume %d status 0x%x\n", 1359 1.19 xtraeme device_xname(sc->sc_dev), bv->bv_volid, status); 1360 1.1 xtraeme } 1361 1.1 xtraeme 1362 1.1 xtraeme blocks = (uint64_t)htole32(volinfo->capacity2) << 32; 1363 1.1 xtraeme blocks += (uint64_t)htole32(volinfo->capacity); 1364 1.1 xtraeme bv->bv_size = blocks * ARC_BLOCKSIZE; /* XXX */ 1365 1.1 xtraeme 1366 1.1 xtraeme switch (volinfo->raid_level) { 1367 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_0: 1368 1.1 xtraeme bv->bv_level = 0; 1369 1.1 xtraeme break; 1370 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_1: 1371 1.18 xtraeme if (volinfo->member_disks > 2) 1372 1.18 xtraeme bv->bv_level = BIOC_SVOL_RAID10; 1373 1.18 xtraeme else 1374 1.18 xtraeme bv->bv_level = 1; 1375 1.1 xtraeme break; 1376 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_3: 1377 1.1 xtraeme bv->bv_level = 3; 1378 1.1 xtraeme break; 1379 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_5: 1380 1.1 xtraeme bv->bv_level = 5; 1381 1.1 xtraeme break; 1382 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_6: 1383 1.1 xtraeme bv->bv_level = 6; 1384 1.1 xtraeme break; 1385 1.1 xtraeme case ARC_FW_VOL_RAIDLEVEL_PASSTHRU: 1386 1.9 xtraeme bv->bv_level = BIOC_SVOL_PASSTHRU; 1387 1.9 xtraeme break; 1388 1.1 xtraeme default: 1389 1.1 xtraeme bv->bv_level = -1; 1390 1.1 xtraeme break; 1391 1.1 xtraeme } 1392 1.1 xtraeme 1393 1.1 xtraeme bv->bv_nodisk = volinfo->member_disks; 1394 1.9 xtraeme bv->bv_stripe_size = volinfo->stripe_size / 2; 1395 1.9 xtraeme snprintf(bv->bv_dev, sizeof(bv->bv_dev), "sd%d", bv->bv_volid); 1396 1.33 christos strnvisx(bv->bv_vendor, sizeof(bv->bv_vendor), volinfo->set_name, 1397 1.33 christos sizeof(volinfo->set_name), VIS_TRIM|VIS_SAFE|VIS_OCTAL); 1398 1.1 xtraeme 1399 1.1 xtraeme out: 1400 1.7 xtraeme kmem_free(volinfo, sizeof(*volinfo)); 1401 1.1 xtraeme return error; 1402 1.1 xtraeme } 1403 1.1 xtraeme 1404 1.1 xtraeme static int 1405 1.9 xtraeme arc_bio_disk_novol(struct arc_softc *sc, struct bioc_disk *bd) 1406 1.1 xtraeme { 1407 1.9 xtraeme struct arc_fw_diskinfo *diskinfo; 1408 1.1 xtraeme uint8_t request[2]; 1409 1.1 xtraeme int error = 0; 1410 1.9 xtraeme 1411 1.10 xtraeme diskinfo = kmem_zalloc(sizeof(*diskinfo), KM_SLEEP); 1412 1.9 xtraeme 1413 1.14 xtraeme if (bd->bd_diskid >= sc->sc_cchans) { 1414 1.9 xtraeme error = ENODEV; 1415 1.9 xtraeme goto out; 1416 1.9 xtraeme } 1417 1.9 xtraeme 1418 1.9 xtraeme request[0] = ARC_FW_DISKINFO; 1419 1.9 xtraeme request[1] = bd->bd_diskid; 1420 1.9 xtraeme error = arc_msgbuf(sc, request, sizeof(request), 1421 1.9 xtraeme diskinfo, sizeof(struct arc_fw_diskinfo)); 1422 1.9 xtraeme if (error != 0) 1423 1.12 xtraeme goto out; 1424 1.9 xtraeme 1425 1.9 xtraeme /* skip disks with no capacity */ 1426 1.9 xtraeme if (htole32(diskinfo->capacity) == 0 && 1427 1.9 xtraeme htole32(diskinfo->capacity2) == 0) 1428 1.9 xtraeme goto out; 1429 1.9 xtraeme 1430 1.9 xtraeme bd->bd_disknovol = true; 1431 1.9 xtraeme arc_bio_disk_filldata(sc, bd, diskinfo, bd->bd_diskid); 1432 1.9 xtraeme 1433 1.9 xtraeme out: 1434 1.9 xtraeme kmem_free(diskinfo, sizeof(*diskinfo)); 1435 1.9 xtraeme return error; 1436 1.9 xtraeme } 1437 1.9 xtraeme 1438 1.9 xtraeme static void 1439 1.9 xtraeme arc_bio_disk_filldata(struct arc_softc *sc, struct bioc_disk *bd, 1440 1.9 xtraeme struct arc_fw_diskinfo *diskinfo, int diskid) 1441 1.9 xtraeme { 1442 1.1 xtraeme uint64_t blocks; 1443 1.1 xtraeme char model[81]; 1444 1.1 xtraeme char serial[41]; 1445 1.1 xtraeme char rev[17]; 1446 1.1 xtraeme 1447 1.22 christos /* Ignore bit zero for now, we don't know what it means */ 1448 1.22 christos diskinfo->device_state &= ~0x1; 1449 1.22 christos 1450 1.20 xtraeme switch (diskinfo->device_state) { 1451 1.22 christos case ARC_FW_DISK_FAILED: 1452 1.22 christos bd->bd_status = BIOC_SDFAILED; 1453 1.22 christos break; 1454 1.9 xtraeme case ARC_FW_DISK_PASSTHRU: 1455 1.9 xtraeme bd->bd_status = BIOC_SDPASSTHRU; 1456 1.9 xtraeme break; 1457 1.22 christos case ARC_FW_DISK_NORMAL: 1458 1.9 xtraeme bd->bd_status = BIOC_SDONLINE; 1459 1.9 xtraeme break; 1460 1.9 xtraeme case ARC_FW_DISK_HOTSPARE: 1461 1.9 xtraeme bd->bd_status = BIOC_SDHOTSPARE; 1462 1.9 xtraeme break; 1463 1.9 xtraeme case ARC_FW_DISK_UNUSED: 1464 1.9 xtraeme bd->bd_status = BIOC_SDUNUSED; 1465 1.9 xtraeme break; 1466 1.14 xtraeme case 0: 1467 1.14 xtraeme /* disk has been disconnected */ 1468 1.14 xtraeme bd->bd_status = BIOC_SDOFFLINE; 1469 1.14 xtraeme bd->bd_channel = 1; 1470 1.14 xtraeme bd->bd_target = 0; 1471 1.14 xtraeme bd->bd_lun = 0; 1472 1.14 xtraeme strlcpy(bd->bd_vendor, "disk missing", sizeof(bd->bd_vendor)); 1473 1.14 xtraeme break; 1474 1.9 xtraeme default: 1475 1.9 xtraeme printf("%s: unknown disk device_state: 0x%x\n", __func__, 1476 1.20 xtraeme diskinfo->device_state); 1477 1.9 xtraeme bd->bd_status = BIOC_SDINVALID; 1478 1.9 xtraeme return; 1479 1.9 xtraeme } 1480 1.9 xtraeme 1481 1.9 xtraeme blocks = (uint64_t)htole32(diskinfo->capacity2) << 32; 1482 1.9 xtraeme blocks += (uint64_t)htole32(diskinfo->capacity); 1483 1.9 xtraeme bd->bd_size = blocks * ARC_BLOCKSIZE; /* XXX */ 1484 1.9 xtraeme 1485 1.33 christos strnvisx(model, sizeof(model), diskinfo->model, 1486 1.33 christos sizeof(diskinfo->model), VIS_TRIM|VIS_SAFE|VIS_OCTAL); 1487 1.33 christos strnvisx(serial, sizeof(serial), diskinfo->serial, 1488 1.33 christos sizeof(diskinfo->serial), VIS_TRIM|VIS_SAFE|VIS_OCTAL); 1489 1.33 christos strnvisx(rev, sizeof(rev), diskinfo->firmware_rev, 1490 1.33 christos sizeof(diskinfo->firmware_rev), VIS_TRIM|VIS_SAFE|VIS_OCTAL); 1491 1.9 xtraeme 1492 1.9 xtraeme snprintf(bd->bd_vendor, sizeof(bd->bd_vendor), "%s %s", model, rev); 1493 1.9 xtraeme strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial)); 1494 1.9 xtraeme 1495 1.9 xtraeme #if 0 1496 1.9 xtraeme bd->bd_channel = diskinfo->scsi_attr.channel; 1497 1.9 xtraeme bd->bd_target = diskinfo->scsi_attr.target; 1498 1.9 xtraeme bd->bd_lun = diskinfo->scsi_attr.lun; 1499 1.9 xtraeme #endif 1500 1.9 xtraeme 1501 1.9 xtraeme /* 1502 1.45 andvar * the firmware doesn't seem to fill scsi_attr in, so fake it with 1503 1.9 xtraeme * the diskid. 1504 1.9 xtraeme */ 1505 1.9 xtraeme bd->bd_channel = 0; 1506 1.9 xtraeme bd->bd_target = diskid; 1507 1.9 xtraeme bd->bd_lun = 0; 1508 1.9 xtraeme } 1509 1.9 xtraeme 1510 1.9 xtraeme static int 1511 1.9 xtraeme arc_bio_disk_volume(struct arc_softc *sc, struct bioc_disk *bd) 1512 1.9 xtraeme { 1513 1.9 xtraeme struct arc_fw_raidinfo *raidinfo; 1514 1.9 xtraeme struct arc_fw_volinfo *volinfo; 1515 1.9 xtraeme struct arc_fw_diskinfo *diskinfo; 1516 1.14 xtraeme uint8_t request[2]; 1517 1.9 xtraeme int error = 0; 1518 1.9 xtraeme 1519 1.10 xtraeme volinfo = kmem_zalloc(sizeof(*volinfo), KM_SLEEP); 1520 1.10 xtraeme raidinfo = kmem_zalloc(sizeof(*raidinfo), KM_SLEEP); 1521 1.10 xtraeme diskinfo = kmem_zalloc(sizeof(*diskinfo), KM_SLEEP); 1522 1.1 xtraeme 1523 1.1 xtraeme error = arc_bio_getvol(sc, bd->bd_volid, volinfo); 1524 1.1 xtraeme if (error != 0) 1525 1.1 xtraeme goto out; 1526 1.1 xtraeme 1527 1.1 xtraeme request[0] = ARC_FW_RAIDINFO; 1528 1.1 xtraeme request[1] = volinfo->raid_set_number; 1529 1.7 xtraeme 1530 1.1 xtraeme error = arc_msgbuf(sc, request, sizeof(request), raidinfo, 1531 1.1 xtraeme sizeof(struct arc_fw_raidinfo)); 1532 1.1 xtraeme if (error != 0) 1533 1.1 xtraeme goto out; 1534 1.1 xtraeme 1535 1.14 xtraeme if (bd->bd_diskid >= sc->sc_cchans || 1536 1.14 xtraeme bd->bd_diskid >= raidinfo->member_devices) { 1537 1.1 xtraeme error = ENODEV; 1538 1.1 xtraeme goto out; 1539 1.1 xtraeme } 1540 1.1 xtraeme 1541 1.14 xtraeme if (raidinfo->device_array[bd->bd_diskid] == 0xff) { 1542 1.14 xtraeme /* 1543 1.14 xtraeme * The disk has been disconnected, mark it offline 1544 1.14 xtraeme * and put it on another bus. 1545 1.14 xtraeme */ 1546 1.14 xtraeme bd->bd_channel = 1; 1547 1.14 xtraeme bd->bd_target = 0; 1548 1.14 xtraeme bd->bd_lun = 0; 1549 1.14 xtraeme bd->bd_status = BIOC_SDOFFLINE; 1550 1.14 xtraeme strlcpy(bd->bd_vendor, "disk missing", sizeof(bd->bd_vendor)); 1551 1.14 xtraeme goto out; 1552 1.14 xtraeme } 1553 1.14 xtraeme 1554 1.1 xtraeme request[0] = ARC_FW_DISKINFO; 1555 1.1 xtraeme request[1] = raidinfo->device_array[bd->bd_diskid]; 1556 1.1 xtraeme error = arc_msgbuf(sc, request, sizeof(request), diskinfo, 1557 1.1 xtraeme sizeof(struct arc_fw_diskinfo)); 1558 1.1 xtraeme if (error != 0) 1559 1.1 xtraeme goto out; 1560 1.1 xtraeme 1561 1.9 xtraeme /* now fill our bio disk with data from the firmware */ 1562 1.9 xtraeme arc_bio_disk_filldata(sc, bd, diskinfo, 1563 1.9 xtraeme raidinfo->device_array[bd->bd_diskid]); 1564 1.1 xtraeme 1565 1.1 xtraeme out: 1566 1.7 xtraeme kmem_free(raidinfo, sizeof(*raidinfo)); 1567 1.7 xtraeme kmem_free(volinfo, sizeof(*volinfo)); 1568 1.9 xtraeme kmem_free(diskinfo, sizeof(*diskinfo)); 1569 1.1 xtraeme return error; 1570 1.1 xtraeme } 1571 1.1 xtraeme 1572 1.35 dholland static uint8_t 1573 1.1 xtraeme arc_msg_cksum(void *cmd, uint16_t len) 1574 1.1 xtraeme { 1575 1.1 xtraeme uint8_t *buf = cmd; 1576 1.1 xtraeme uint8_t cksum; 1577 1.1 xtraeme int i; 1578 1.1 xtraeme 1579 1.1 xtraeme cksum = (uint8_t)(len >> 8) + (uint8_t)len; 1580 1.1 xtraeme for (i = 0; i < len; i++) 1581 1.1 xtraeme cksum += buf[i]; 1582 1.1 xtraeme 1583 1.1 xtraeme return cksum; 1584 1.1 xtraeme } 1585 1.1 xtraeme 1586 1.1 xtraeme 1587 1.35 dholland static int 1588 1.1 xtraeme arc_msgbuf(struct arc_softc *sc, void *wptr, size_t wbuflen, void *rptr, 1589 1.1 xtraeme size_t rbuflen) 1590 1.1 xtraeme { 1591 1.1 xtraeme uint8_t rwbuf[ARC_REG_IOC_RWBUF_MAXLEN]; 1592 1.1 xtraeme uint8_t *wbuf, *rbuf; 1593 1.1 xtraeme int wlen, wdone = 0, rlen, rdone = 0; 1594 1.1 xtraeme struct arc_fw_bufhdr *bufhdr; 1595 1.1 xtraeme uint32_t reg, rwlen; 1596 1.1 xtraeme int error = 0; 1597 1.1 xtraeme #ifdef ARC_DEBUG 1598 1.1 xtraeme int i; 1599 1.1 xtraeme #endif 1600 1.1 xtraeme 1601 1.7 xtraeme wbuf = rbuf = NULL; 1602 1.7 xtraeme 1603 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: arc_msgbuf wbuflen: %d rbuflen: %d\n", 1604 1.19 xtraeme device_xname(sc->sc_dev), wbuflen, rbuflen); 1605 1.1 xtraeme 1606 1.1 xtraeme wlen = sizeof(struct arc_fw_bufhdr) + wbuflen + 1; /* 1 for cksum */ 1607 1.7 xtraeme wbuf = kmem_alloc(wlen, KM_SLEEP); 1608 1.1 xtraeme 1609 1.1 xtraeme rlen = sizeof(struct arc_fw_bufhdr) + rbuflen + 1; /* 1 for cksum */ 1610 1.7 xtraeme rbuf = kmem_alloc(rlen, KM_SLEEP); 1611 1.1 xtraeme 1612 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: arc_msgbuf wlen: %d rlen: %d\n", 1613 1.19 xtraeme device_xname(sc->sc_dev), wlen, rlen); 1614 1.1 xtraeme 1615 1.1 xtraeme bufhdr = (struct arc_fw_bufhdr *)wbuf; 1616 1.1 xtraeme bufhdr->hdr = arc_fw_hdr; 1617 1.1 xtraeme bufhdr->len = htole16(wbuflen); 1618 1.1 xtraeme memcpy(wbuf + sizeof(struct arc_fw_bufhdr), wptr, wbuflen); 1619 1.1 xtraeme wbuf[wlen - 1] = arc_msg_cksum(wptr, wbuflen); 1620 1.1 xtraeme 1621 1.7 xtraeme arc_lock(sc); 1622 1.7 xtraeme if (arc_read(sc, ARC_REG_OUTB_DOORBELL) != 0) { 1623 1.7 xtraeme error = EBUSY; 1624 1.7 xtraeme goto out; 1625 1.7 xtraeme } 1626 1.7 xtraeme 1627 1.1 xtraeme reg = ARC_REG_OUTB_DOORBELL_READ_OK; 1628 1.1 xtraeme 1629 1.1 xtraeme do { 1630 1.1 xtraeme if ((reg & ARC_REG_OUTB_DOORBELL_READ_OK) && wdone < wlen) { 1631 1.1 xtraeme memset(rwbuf, 0, sizeof(rwbuf)); 1632 1.1 xtraeme rwlen = (wlen - wdone) % sizeof(rwbuf); 1633 1.1 xtraeme memcpy(rwbuf, &wbuf[wdone], rwlen); 1634 1.1 xtraeme 1635 1.1 xtraeme #ifdef ARC_DEBUG 1636 1.1 xtraeme if (arcdebug & ARC_D_DB) { 1637 1.1 xtraeme printf("%s: write %d:", 1638 1.19 xtraeme device_xname(sc->sc_dev), rwlen); 1639 1.1 xtraeme for (i = 0; i < rwlen; i++) 1640 1.1 xtraeme printf(" 0x%02x", rwbuf[i]); 1641 1.1 xtraeme printf("\n"); 1642 1.1 xtraeme } 1643 1.1 xtraeme #endif 1644 1.1 xtraeme 1645 1.1 xtraeme /* copy the chunk to the hw */ 1646 1.1 xtraeme arc_write(sc, ARC_REG_IOC_WBUF_LEN, rwlen); 1647 1.1 xtraeme arc_write_region(sc, ARC_REG_IOC_WBUF, rwbuf, 1648 1.1 xtraeme sizeof(rwbuf)); 1649 1.1 xtraeme 1650 1.1 xtraeme /* say we have a buffer for the hw */ 1651 1.1 xtraeme arc_write(sc, ARC_REG_INB_DOORBELL, 1652 1.1 xtraeme ARC_REG_INB_DOORBELL_WRITE_OK); 1653 1.1 xtraeme 1654 1.1 xtraeme wdone += rwlen; 1655 1.1 xtraeme } 1656 1.1 xtraeme 1657 1.1 xtraeme while ((reg = arc_read(sc, ARC_REG_OUTB_DOORBELL)) == 0) 1658 1.1 xtraeme arc_wait(sc); 1659 1.9 xtraeme 1660 1.1 xtraeme arc_write(sc, ARC_REG_OUTB_DOORBELL, reg); 1661 1.1 xtraeme 1662 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: reg: 0x%08x\n", 1663 1.19 xtraeme device_xname(sc->sc_dev), reg); 1664 1.1 xtraeme 1665 1.1 xtraeme if ((reg & ARC_REG_OUTB_DOORBELL_WRITE_OK) && rdone < rlen) { 1666 1.1 xtraeme rwlen = arc_read(sc, ARC_REG_IOC_RBUF_LEN); 1667 1.1 xtraeme if (rwlen > sizeof(rwbuf)) { 1668 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: rwlen too big\n", 1669 1.19 xtraeme device_xname(sc->sc_dev)); 1670 1.1 xtraeme error = EIO; 1671 1.1 xtraeme goto out; 1672 1.1 xtraeme } 1673 1.1 xtraeme 1674 1.1 xtraeme arc_read_region(sc, ARC_REG_IOC_RBUF, rwbuf, 1675 1.1 xtraeme sizeof(rwbuf)); 1676 1.1 xtraeme 1677 1.1 xtraeme arc_write(sc, ARC_REG_INB_DOORBELL, 1678 1.1 xtraeme ARC_REG_INB_DOORBELL_READ_OK); 1679 1.1 xtraeme 1680 1.1 xtraeme #ifdef ARC_DEBUG 1681 1.1 xtraeme printf("%s: len: %d+%d=%d/%d\n", 1682 1.19 xtraeme device_xname(sc->sc_dev), 1683 1.1 xtraeme rwlen, rdone, rwlen + rdone, rlen); 1684 1.1 xtraeme if (arcdebug & ARC_D_DB) { 1685 1.1 xtraeme printf("%s: read:", 1686 1.19 xtraeme device_xname(sc->sc_dev)); 1687 1.1 xtraeme for (i = 0; i < rwlen; i++) 1688 1.1 xtraeme printf(" 0x%02x", rwbuf[i]); 1689 1.1 xtraeme printf("\n"); 1690 1.1 xtraeme } 1691 1.1 xtraeme #endif 1692 1.1 xtraeme 1693 1.1 xtraeme if ((rdone + rwlen) > rlen) { 1694 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: rwbuf too big\n", 1695 1.19 xtraeme device_xname(sc->sc_dev)); 1696 1.1 xtraeme error = EIO; 1697 1.1 xtraeme goto out; 1698 1.1 xtraeme } 1699 1.1 xtraeme 1700 1.1 xtraeme memcpy(&rbuf[rdone], rwbuf, rwlen); 1701 1.1 xtraeme rdone += rwlen; 1702 1.1 xtraeme } 1703 1.1 xtraeme } while (rdone != rlen); 1704 1.1 xtraeme 1705 1.1 xtraeme bufhdr = (struct arc_fw_bufhdr *)rbuf; 1706 1.1 xtraeme if (memcmp(&bufhdr->hdr, &arc_fw_hdr, sizeof(bufhdr->hdr)) != 0 || 1707 1.1 xtraeme bufhdr->len != htole16(rbuflen)) { 1708 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: rbuf hdr is wrong\n", 1709 1.19 xtraeme device_xname(sc->sc_dev)); 1710 1.1 xtraeme error = EIO; 1711 1.1 xtraeme goto out; 1712 1.1 xtraeme } 1713 1.1 xtraeme 1714 1.1 xtraeme memcpy(rptr, rbuf + sizeof(struct arc_fw_bufhdr), rbuflen); 1715 1.1 xtraeme 1716 1.1 xtraeme if (rbuf[rlen - 1] != arc_msg_cksum(rptr, rbuflen)) { 1717 1.1 xtraeme DNPRINTF(ARC_D_DB, "%s: invalid cksum\n", 1718 1.19 xtraeme device_xname(sc->sc_dev)); 1719 1.1 xtraeme error = EIO; 1720 1.1 xtraeme goto out; 1721 1.1 xtraeme } 1722 1.1 xtraeme 1723 1.1 xtraeme out: 1724 1.7 xtraeme arc_unlock(sc); 1725 1.7 xtraeme kmem_free(wbuf, wlen); 1726 1.7 xtraeme kmem_free(rbuf, rlen); 1727 1.1 xtraeme 1728 1.1 xtraeme return error; 1729 1.1 xtraeme } 1730 1.1 xtraeme 1731 1.35 dholland static void 1732 1.1 xtraeme arc_lock(struct arc_softc *sc) 1733 1.5 xtraeme { 1734 1.5 xtraeme rw_enter(&sc->sc_rwlock, RW_WRITER); 1735 1.7 xtraeme mutex_spin_enter(&sc->sc_mutex); 1736 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE); 1737 1.1 xtraeme sc->sc_talking = 1; 1738 1.1 xtraeme } 1739 1.1 xtraeme 1740 1.35 dholland static void 1741 1.1 xtraeme arc_unlock(struct arc_softc *sc) 1742 1.1 xtraeme { 1743 1.3 xtraeme KASSERT(mutex_owned(&sc->sc_mutex)); 1744 1.1 xtraeme 1745 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, 1746 1.1 xtraeme ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL)); 1747 1.9 xtraeme sc->sc_talking = 0; 1748 1.7 xtraeme mutex_spin_exit(&sc->sc_mutex); 1749 1.5 xtraeme rw_exit(&sc->sc_rwlock); 1750 1.1 xtraeme } 1751 1.1 xtraeme 1752 1.35 dholland static void 1753 1.1 xtraeme arc_wait(struct arc_softc *sc) 1754 1.1 xtraeme { 1755 1.3 xtraeme KASSERT(mutex_owned(&sc->sc_mutex)); 1756 1.1 xtraeme 1757 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, 1758 1.1 xtraeme ~(ARC_REG_INTRMASK_POSTQUEUE|ARC_REG_INTRMASK_DOORBELL)); 1759 1.9 xtraeme if (cv_timedwait(&sc->sc_condvar, &sc->sc_mutex, hz) == EWOULDBLOCK) 1760 1.1 xtraeme arc_write(sc, ARC_REG_INTRMASK, ~ARC_REG_INTRMASK_POSTQUEUE); 1761 1.1 xtraeme } 1762 1.1 xtraeme 1763 1.35 dholland 1764 1.1 xtraeme static void 1765 1.1 xtraeme arc_create_sensors(void *arg) 1766 1.1 xtraeme { 1767 1.1 xtraeme struct arc_softc *sc = arg; 1768 1.1 xtraeme struct bioc_inq bi; 1769 1.1 xtraeme struct bioc_vol bv; 1770 1.10 xtraeme int i, j; 1771 1.10 xtraeme size_t slen, count = 0; 1772 1.1 xtraeme 1773 1.1 xtraeme memset(&bi, 0, sizeof(bi)); 1774 1.1 xtraeme if (arc_bio_inq(sc, &bi) != 0) { 1775 1.1 xtraeme aprint_error("%s: unable to query firmware for sensor info\n", 1776 1.19 xtraeme device_xname(sc->sc_dev)); 1777 1.1 xtraeme kthread_exit(0); 1778 1.1 xtraeme } 1779 1.1 xtraeme 1780 1.10 xtraeme /* There's no point to continue if there are no volumes */ 1781 1.10 xtraeme if (!bi.bi_novol) 1782 1.1 xtraeme kthread_exit(0); 1783 1.1 xtraeme 1784 1.10 xtraeme for (i = 0; i < bi.bi_novol; i++) { 1785 1.10 xtraeme memset(&bv, 0, sizeof(bv)); 1786 1.10 xtraeme bv.bv_volid = i; 1787 1.10 xtraeme if (arc_bio_vol(sc, &bv) != 0) 1788 1.10 xtraeme kthread_exit(0); 1789 1.10 xtraeme 1790 1.10 xtraeme /* Skip passthrough volumes */ 1791 1.10 xtraeme if (bv.bv_level == BIOC_SVOL_PASSTHRU) 1792 1.10 xtraeme continue; 1793 1.10 xtraeme 1794 1.10 xtraeme /* new volume found */ 1795 1.10 xtraeme sc->sc_nsensors++; 1796 1.10 xtraeme /* new disk in a volume found */ 1797 1.10 xtraeme sc->sc_nsensors+= bv.bv_nodisk; 1798 1.10 xtraeme } 1799 1.10 xtraeme 1800 1.16 xtraeme /* No valid volumes */ 1801 1.16 xtraeme if (!sc->sc_nsensors) 1802 1.16 xtraeme kthread_exit(0); 1803 1.16 xtraeme 1804 1.1 xtraeme sc->sc_sme = sysmon_envsys_create(); 1805 1.28 pgoyette slen = sizeof(arc_edata_t) * sc->sc_nsensors; 1806 1.28 pgoyette sc->sc_arc_sensors = kmem_zalloc(slen, KM_SLEEP); 1807 1.1 xtraeme 1808 1.10 xtraeme /* Attach sensors for volumes and disks */ 1809 1.10 xtraeme for (i = 0; i < bi.bi_novol; i++) { 1810 1.1 xtraeme memset(&bv, 0, sizeof(bv)); 1811 1.1 xtraeme bv.bv_volid = i; 1812 1.1 xtraeme if (arc_bio_vol(sc, &bv) != 0) 1813 1.1 xtraeme goto bad; 1814 1.1 xtraeme 1815 1.28 pgoyette sc->sc_arc_sensors[count].arc_sensor.units = ENVSYS_DRIVE; 1816 1.29 pgoyette sc->sc_arc_sensors[count].arc_sensor.state = ENVSYS_SINVALID; 1817 1.30 pgoyette sc->sc_arc_sensors[count].arc_sensor.value_cur = 1818 1.30 pgoyette ENVSYS_DRIVE_EMPTY; 1819 1.28 pgoyette sc->sc_arc_sensors[count].arc_sensor.flags = 1820 1.28 pgoyette ENVSYS_FMONSTCHANGED; 1821 1.10 xtraeme 1822 1.10 xtraeme /* Skip passthrough volumes */ 1823 1.10 xtraeme if (bv.bv_level == BIOC_SVOL_PASSTHRU) 1824 1.10 xtraeme continue; 1825 1.10 xtraeme 1826 1.18 xtraeme if (bv.bv_level == BIOC_SVOL_RAID10) 1827 1.28 pgoyette snprintf(sc->sc_arc_sensors[count].arc_sensor.desc, 1828 1.28 pgoyette sizeof(sc->sc_arc_sensors[count].arc_sensor.desc), 1829 1.18 xtraeme "RAID 1+0 volume%d (%s)", i, bv.bv_dev); 1830 1.18 xtraeme else 1831 1.28 pgoyette snprintf(sc->sc_arc_sensors[count].arc_sensor.desc, 1832 1.28 pgoyette sizeof(sc->sc_arc_sensors[count].arc_sensor.desc), 1833 1.18 xtraeme "RAID %d volume%d (%s)", bv.bv_level, i, 1834 1.18 xtraeme bv.bv_dev); 1835 1.18 xtraeme 1836 1.28 pgoyette sc->sc_arc_sensors[count].arc_volid = i; 1837 1.10 xtraeme 1838 1.10 xtraeme if (sysmon_envsys_sensor_attach(sc->sc_sme, 1839 1.28 pgoyette &sc->sc_arc_sensors[count].arc_sensor)) 1840 1.1 xtraeme goto bad; 1841 1.10 xtraeme 1842 1.10 xtraeme count++; 1843 1.10 xtraeme 1844 1.10 xtraeme /* Attach disk sensors for this volume */ 1845 1.10 xtraeme for (j = 0; j < bv.bv_nodisk; j++) { 1846 1.29 pgoyette sc->sc_arc_sensors[count].arc_sensor.state = 1847 1.29 pgoyette ENVSYS_SINVALID; 1848 1.28 pgoyette sc->sc_arc_sensors[count].arc_sensor.units = 1849 1.28 pgoyette ENVSYS_DRIVE; 1850 1.30 pgoyette sc->sc_arc_sensors[count].arc_sensor.value_cur = 1851 1.30 pgoyette ENVSYS_DRIVE_EMPTY; 1852 1.28 pgoyette sc->sc_arc_sensors[count].arc_sensor.flags = 1853 1.28 pgoyette ENVSYS_FMONSTCHANGED; 1854 1.10 xtraeme 1855 1.28 pgoyette snprintf(sc->sc_arc_sensors[count].arc_sensor.desc, 1856 1.28 pgoyette sizeof(sc->sc_arc_sensors[count].arc_sensor.desc), 1857 1.10 xtraeme "disk%d volume%d (%s)", j, i, bv.bv_dev); 1858 1.28 pgoyette sc->sc_arc_sensors[count].arc_volid = i; 1859 1.28 pgoyette sc->sc_arc_sensors[count].arc_diskid = j + 10; 1860 1.10 xtraeme 1861 1.10 xtraeme if (sysmon_envsys_sensor_attach(sc->sc_sme, 1862 1.28 pgoyette &sc->sc_arc_sensors[count].arc_sensor)) 1863 1.10 xtraeme goto bad; 1864 1.10 xtraeme 1865 1.10 xtraeme count++; 1866 1.10 xtraeme } 1867 1.1 xtraeme } 1868 1.1 xtraeme 1869 1.10 xtraeme /* 1870 1.10 xtraeme * Register our envsys driver with the framework now that the 1871 1.10 xtraeme * sensors were all attached. 1872 1.10 xtraeme */ 1873 1.19 xtraeme sc->sc_sme->sme_name = device_xname(sc->sc_dev); 1874 1.2 xtraeme sc->sc_sme->sme_cookie = sc; 1875 1.2 xtraeme sc->sc_sme->sme_refresh = arc_refresh_sensors; 1876 1.10 xtraeme 1877 1.1 xtraeme if (sysmon_envsys_register(sc->sc_sme)) { 1878 1.1 xtraeme aprint_debug("%s: unable to register with sysmon\n", 1879 1.19 xtraeme device_xname(sc->sc_dev)); 1880 1.1 xtraeme goto bad; 1881 1.1 xtraeme } 1882 1.1 xtraeme kthread_exit(0); 1883 1.1 xtraeme 1884 1.1 xtraeme bad: 1885 1.25 jruoho sysmon_envsys_destroy(sc->sc_sme); 1886 1.42 mlelstv sc->sc_sme = NULL; 1887 1.42 mlelstv 1888 1.28 pgoyette kmem_free(sc->sc_arc_sensors, slen); 1889 1.28 pgoyette sc->sc_arc_sensors = NULL; 1890 1.25 jruoho 1891 1.1 xtraeme kthread_exit(0); 1892 1.1 xtraeme } 1893 1.1 xtraeme 1894 1.1 xtraeme static void 1895 1.2 xtraeme arc_refresh_sensors(struct sysmon_envsys *sme, envsys_data_t *edata) 1896 1.1 xtraeme { 1897 1.2 xtraeme struct arc_softc *sc = sme->sme_cookie; 1898 1.1 xtraeme struct bioc_vol bv; 1899 1.10 xtraeme struct bioc_disk bd; 1900 1.28 pgoyette arc_edata_t *arcdata = (arc_edata_t *)edata; 1901 1.10 xtraeme 1902 1.10 xtraeme /* sanity check */ 1903 1.10 xtraeme if (edata->units != ENVSYS_DRIVE) 1904 1.10 xtraeme return; 1905 1.1 xtraeme 1906 1.1 xtraeme memset(&bv, 0, sizeof(bv)); 1907 1.28 pgoyette bv.bv_volid = arcdata->arc_volid; 1908 1.2 xtraeme 1909 1.2 xtraeme if (arc_bio_vol(sc, &bv)) { 1910 1.32 christos bv.bv_status = BIOC_SVINVALID; 1911 1.32 christos bio_vol_to_envsys(edata, &bv); 1912 1.2 xtraeme return; 1913 1.2 xtraeme } 1914 1.1 xtraeme 1915 1.28 pgoyette if (arcdata->arc_diskid) { 1916 1.32 christos /* Current sensor is handling a disk volume member */ 1917 1.10 xtraeme memset(&bd, 0, sizeof(bd)); 1918 1.28 pgoyette bd.bd_volid = arcdata->arc_volid; 1919 1.28 pgoyette bd.bd_diskid = arcdata->arc_diskid - 10; 1920 1.10 xtraeme 1921 1.32 christos if (arc_bio_disk_volume(sc, &bd)) 1922 1.32 christos bd.bd_status = BIOC_SDOFFLINE; 1923 1.32 christos bio_disk_to_envsys(edata, &bd); 1924 1.32 christos } else { 1925 1.32 christos /* Current sensor is handling a volume */ 1926 1.32 christos bio_vol_to_envsys(edata, &bv); 1927 1.1 xtraeme } 1928 1.1 xtraeme } 1929 1.1 xtraeme #endif /* NBIO > 0 */ 1930 1.1 xtraeme 1931 1.34 christos static uint32_t 1932 1.1 xtraeme arc_read(struct arc_softc *sc, bus_size_t r) 1933 1.1 xtraeme { 1934 1.1 xtraeme uint32_t v; 1935 1.1 xtraeme 1936 1.1 xtraeme bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1937 1.1 xtraeme BUS_SPACE_BARRIER_READ); 1938 1.1 xtraeme v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 1939 1.1 xtraeme 1940 1.1 xtraeme DNPRINTF(ARC_D_RW, "%s: arc_read 0x%lx 0x%08x\n", 1941 1.19 xtraeme device_xname(sc->sc_dev), r, v); 1942 1.1 xtraeme 1943 1.1 xtraeme return v; 1944 1.1 xtraeme } 1945 1.1 xtraeme 1946 1.34 christos static void 1947 1.1 xtraeme arc_read_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len) 1948 1.1 xtraeme { 1949 1.1 xtraeme bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len, 1950 1.1 xtraeme BUS_SPACE_BARRIER_READ); 1951 1.1 xtraeme bus_space_read_region_4(sc->sc_iot, sc->sc_ioh, r, 1952 1.1 xtraeme (uint32_t *)buf, len >> 2); 1953 1.1 xtraeme } 1954 1.1 xtraeme 1955 1.34 christos static void 1956 1.1 xtraeme arc_write(struct arc_softc *sc, bus_size_t r, uint32_t v) 1957 1.1 xtraeme { 1958 1.1 xtraeme DNPRINTF(ARC_D_RW, "%s: arc_write 0x%lx 0x%08x\n", 1959 1.19 xtraeme device_xname(sc->sc_dev), r, v); 1960 1.1 xtraeme 1961 1.1 xtraeme bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v); 1962 1.1 xtraeme bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4, 1963 1.1 xtraeme BUS_SPACE_BARRIER_WRITE); 1964 1.1 xtraeme } 1965 1.1 xtraeme 1966 1.36 dholland #if NBIO > 0 1967 1.34 christos static void 1968 1.1 xtraeme arc_write_region(struct arc_softc *sc, bus_size_t r, void *buf, size_t len) 1969 1.1 xtraeme { 1970 1.1 xtraeme bus_space_write_region_4(sc->sc_iot, sc->sc_ioh, r, 1971 1.1 xtraeme (const uint32_t *)buf, len >> 2); 1972 1.1 xtraeme bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, len, 1973 1.1 xtraeme BUS_SPACE_BARRIER_WRITE); 1974 1.1 xtraeme } 1975 1.36 dholland #endif /* NBIO > 0 */ 1976 1.1 xtraeme 1977 1.34 christos static int 1978 1.1 xtraeme arc_wait_eq(struct arc_softc *sc, bus_size_t r, uint32_t mask, 1979 1.1 xtraeme uint32_t target) 1980 1.1 xtraeme { 1981 1.1 xtraeme int i; 1982 1.1 xtraeme 1983 1.1 xtraeme DNPRINTF(ARC_D_RW, "%s: arc_wait_eq 0x%lx 0x%08x 0x%08x\n", 1984 1.19 xtraeme device_xname(sc->sc_dev), r, mask, target); 1985 1.1 xtraeme 1986 1.1 xtraeme for (i = 0; i < 10000; i++) { 1987 1.1 xtraeme if ((arc_read(sc, r) & mask) == target) 1988 1.1 xtraeme return 0; 1989 1.1 xtraeme delay(1000); 1990 1.1 xtraeme } 1991 1.1 xtraeme 1992 1.1 xtraeme return 1; 1993 1.1 xtraeme } 1994 1.1 xtraeme 1995 1.34 christos #if unused 1996 1.34 christos static int 1997 1.1 xtraeme arc_wait_ne(struct arc_softc *sc, bus_size_t r, uint32_t mask, 1998 1.1 xtraeme uint32_t target) 1999 1.1 xtraeme { 2000 1.1 xtraeme int i; 2001 1.1 xtraeme 2002 1.1 xtraeme DNPRINTF(ARC_D_RW, "%s: arc_wait_ne 0x%lx 0x%08x 0x%08x\n", 2003 1.19 xtraeme device_xname(sc->sc_dev), r, mask, target); 2004 1.1 xtraeme 2005 1.1 xtraeme for (i = 0; i < 10000; i++) { 2006 1.1 xtraeme if ((arc_read(sc, r) & mask) != target) 2007 1.1 xtraeme return 0; 2008 1.1 xtraeme delay(1000); 2009 1.1 xtraeme } 2010 1.1 xtraeme 2011 1.1 xtraeme return 1; 2012 1.1 xtraeme } 2013 1.34 christos #endif 2014 1.1 xtraeme 2015 1.34 christos static int 2016 1.1 xtraeme arc_msg0(struct arc_softc *sc, uint32_t m) 2017 1.1 xtraeme { 2018 1.1 xtraeme /* post message */ 2019 1.1 xtraeme arc_write(sc, ARC_REG_INB_MSG0, m); 2020 1.1 xtraeme /* wait for the fw to do it */ 2021 1.1 xtraeme if (arc_wait_eq(sc, ARC_REG_INTRSTAT, ARC_REG_INTRSTAT_MSG0, 2022 1.1 xtraeme ARC_REG_INTRSTAT_MSG0) != 0) 2023 1.1 xtraeme return 1; 2024 1.1 xtraeme 2025 1.1 xtraeme /* ack it */ 2026 1.1 xtraeme arc_write(sc, ARC_REG_INTRSTAT, ARC_REG_INTRSTAT_MSG0); 2027 1.1 xtraeme 2028 1.1 xtraeme return 0; 2029 1.1 xtraeme } 2030 1.1 xtraeme 2031 1.34 christos static struct arc_dmamem * 2032 1.1 xtraeme arc_dmamem_alloc(struct arc_softc *sc, size_t size) 2033 1.1 xtraeme { 2034 1.1 xtraeme struct arc_dmamem *adm; 2035 1.1 xtraeme int nsegs; 2036 1.1 xtraeme 2037 1.40 chs adm = kmem_zalloc(sizeof(*adm), KM_SLEEP); 2038 1.1 xtraeme adm->adm_size = size; 2039 1.1 xtraeme 2040 1.1 xtraeme if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 2041 1.1 xtraeme BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &adm->adm_map) != 0) 2042 1.1 xtraeme goto admfree; 2043 1.1 xtraeme 2044 1.1 xtraeme if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &adm->adm_seg, 2045 1.1 xtraeme 1, &nsegs, BUS_DMA_NOWAIT) != 0) 2046 1.1 xtraeme goto destroy; 2047 1.1 xtraeme 2048 1.1 xtraeme if (bus_dmamem_map(sc->sc_dmat, &adm->adm_seg, nsegs, size, 2049 1.1 xtraeme &adm->adm_kva, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) != 0) 2050 1.1 xtraeme goto free; 2051 1.1 xtraeme 2052 1.1 xtraeme if (bus_dmamap_load(sc->sc_dmat, adm->adm_map, adm->adm_kva, size, 2053 1.1 xtraeme NULL, BUS_DMA_NOWAIT) != 0) 2054 1.1 xtraeme goto unmap; 2055 1.1 xtraeme 2056 1.1 xtraeme memset(adm->adm_kva, 0, size); 2057 1.1 xtraeme 2058 1.1 xtraeme return adm; 2059 1.1 xtraeme 2060 1.1 xtraeme unmap: 2061 1.1 xtraeme bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, size); 2062 1.1 xtraeme free: 2063 1.1 xtraeme bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1); 2064 1.1 xtraeme destroy: 2065 1.1 xtraeme bus_dmamap_destroy(sc->sc_dmat, adm->adm_map); 2066 1.1 xtraeme admfree: 2067 1.7 xtraeme kmem_free(adm, sizeof(*adm)); 2068 1.1 xtraeme 2069 1.1 xtraeme return NULL; 2070 1.1 xtraeme } 2071 1.1 xtraeme 2072 1.34 christos static void 2073 1.1 xtraeme arc_dmamem_free(struct arc_softc *sc, struct arc_dmamem *adm) 2074 1.1 xtraeme { 2075 1.1 xtraeme bus_dmamap_unload(sc->sc_dmat, adm->adm_map); 2076 1.1 xtraeme bus_dmamem_unmap(sc->sc_dmat, adm->adm_kva, adm->adm_size); 2077 1.1 xtraeme bus_dmamem_free(sc->sc_dmat, &adm->adm_seg, 1); 2078 1.1 xtraeme bus_dmamap_destroy(sc->sc_dmat, adm->adm_map); 2079 1.7 xtraeme kmem_free(adm, sizeof(*adm)); 2080 1.1 xtraeme } 2081 1.1 xtraeme 2082 1.34 christos static int 2083 1.19 xtraeme arc_alloc_ccbs(device_t self) 2084 1.1 xtraeme { 2085 1.19 xtraeme struct arc_softc *sc = device_private(self); 2086 1.1 xtraeme struct arc_ccb *ccb; 2087 1.1 xtraeme uint8_t *cmd; 2088 1.1 xtraeme int i; 2089 1.7 xtraeme size_t ccbslen; 2090 1.1 xtraeme 2091 1.1 xtraeme TAILQ_INIT(&sc->sc_ccb_free); 2092 1.1 xtraeme 2093 1.7 xtraeme ccbslen = sizeof(struct arc_ccb) * sc->sc_req_count; 2094 1.7 xtraeme sc->sc_ccbs = kmem_zalloc(ccbslen, KM_SLEEP); 2095 1.1 xtraeme 2096 1.1 xtraeme sc->sc_requests = arc_dmamem_alloc(sc, 2097 1.1 xtraeme ARC_MAX_IOCMDLEN * sc->sc_req_count); 2098 1.1 xtraeme if (sc->sc_requests == NULL) { 2099 1.19 xtraeme aprint_error_dev(self, "unable to allocate ccb dmamem\n"); 2100 1.1 xtraeme goto free_ccbs; 2101 1.1 xtraeme } 2102 1.1 xtraeme cmd = ARC_DMA_KVA(sc->sc_requests); 2103 1.1 xtraeme 2104 1.1 xtraeme for (i = 0; i < sc->sc_req_count; i++) { 2105 1.1 xtraeme ccb = &sc->sc_ccbs[i]; 2106 1.1 xtraeme 2107 1.1 xtraeme if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, ARC_SGL_MAXLEN, 2108 1.1 xtraeme MAXPHYS, 0, 0, &ccb->ccb_dmamap) != 0) { 2109 1.19 xtraeme aprint_error_dev(self, 2110 1.19 xtraeme "unable to create dmamap for ccb %d\n", i); 2111 1.1 xtraeme goto free_maps; 2112 1.1 xtraeme } 2113 1.1 xtraeme 2114 1.1 xtraeme ccb->ccb_sc = sc; 2115 1.1 xtraeme ccb->ccb_id = i; 2116 1.1 xtraeme ccb->ccb_offset = ARC_MAX_IOCMDLEN * i; 2117 1.1 xtraeme 2118 1.1 xtraeme ccb->ccb_cmd = (struct arc_io_cmd *)&cmd[ccb->ccb_offset]; 2119 1.1 xtraeme ccb->ccb_cmd_post = (ARC_DMA_DVA(sc->sc_requests) + 2120 1.1 xtraeme ccb->ccb_offset) >> ARC_REG_POST_QUEUE_ADDR_SHIFT; 2121 1.1 xtraeme 2122 1.1 xtraeme arc_put_ccb(sc, ccb); 2123 1.1 xtraeme } 2124 1.1 xtraeme 2125 1.1 xtraeme return 0; 2126 1.1 xtraeme 2127 1.1 xtraeme free_maps: 2128 1.1 xtraeme while ((ccb = arc_get_ccb(sc)) != NULL) 2129 1.1 xtraeme bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); 2130 1.1 xtraeme arc_dmamem_free(sc, sc->sc_requests); 2131 1.1 xtraeme 2132 1.1 xtraeme free_ccbs: 2133 1.7 xtraeme kmem_free(sc->sc_ccbs, ccbslen); 2134 1.1 xtraeme 2135 1.1 xtraeme return 1; 2136 1.1 xtraeme } 2137 1.1 xtraeme 2138 1.34 christos static struct arc_ccb * 2139 1.1 xtraeme arc_get_ccb(struct arc_softc *sc) 2140 1.1 xtraeme { 2141 1.1 xtraeme struct arc_ccb *ccb; 2142 1.1 xtraeme 2143 1.1 xtraeme ccb = TAILQ_FIRST(&sc->sc_ccb_free); 2144 1.1 xtraeme if (ccb != NULL) 2145 1.1 xtraeme TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link); 2146 1.3 xtraeme 2147 1.1 xtraeme return ccb; 2148 1.1 xtraeme } 2149 1.1 xtraeme 2150 1.34 christos static void 2151 1.1 xtraeme arc_put_ccb(struct arc_softc *sc, struct arc_ccb *ccb) 2152 1.1 xtraeme { 2153 1.1 xtraeme ccb->ccb_xs = NULL; 2154 1.1 xtraeme memset(ccb->ccb_cmd, 0, ARC_MAX_IOCMDLEN); 2155 1.1 xtraeme TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link); 2156 1.1 xtraeme } 2157