1 1.56 andvar /* $NetBSD: mly.c,v 1.56 2021/09/03 22:33:17 andvar Exp $ */ 2 1.1 ad 3 1.1 ad /*- 4 1.1 ad * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 1.1 ad * All rights reserved. 6 1.1 ad * 7 1.1 ad * This code is derived from software contributed to The NetBSD Foundation 8 1.1 ad * by Andrew Doran, Thor Lancelot Simon, and Eric Haszlakiewicz. 9 1.1 ad * 10 1.1 ad * Redistribution and use in source and binary forms, with or without 11 1.1 ad * modification, are permitted provided that the following conditions 12 1.1 ad * are met: 13 1.1 ad * 1. Redistributions of source code must retain the above copyright 14 1.1 ad * notice, this list of conditions and the following disclaimer. 15 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 ad * notice, this list of conditions and the following disclaimer in the 17 1.1 ad * documentation and/or other materials provided with the distribution. 18 1.1 ad * 19 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 ad * POSSIBILITY OF SUCH DAMAGE. 30 1.1 ad */ 31 1.1 ad 32 1.1 ad /*- 33 1.1 ad * Copyright (c) 2000, 2001 Michael Smith 34 1.1 ad * Copyright (c) 2000 BSDi 35 1.1 ad * All rights reserved. 36 1.1 ad * 37 1.1 ad * Redistribution and use in source and binary forms, with or without 38 1.1 ad * modification, are permitted provided that the following conditions 39 1.1 ad * are met: 40 1.1 ad * 1. Redistributions of source code must retain the above copyright 41 1.1 ad * notice, this list of conditions and the following disclaimer. 42 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright 43 1.1 ad * notice, this list of conditions and the following disclaimer in the 44 1.1 ad * documentation and/or other materials provided with the distribution. 45 1.1 ad * 46 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 47 1.1 ad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 1.1 ad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 1.1 ad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 50 1.1 ad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 1.1 ad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 1.1 ad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 1.1 ad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 1.1 ad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 1.1 ad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 1.1 ad * SUCH DAMAGE. 57 1.1 ad * 58 1.1 ad * from FreeBSD: mly.c,v 1.8 2001/07/14 00:12:22 msmith Exp 59 1.1 ad */ 60 1.1 ad 61 1.1 ad /* 62 1.1 ad * Driver for the Mylex AcceleRAID and eXtremeRAID family with v6 firmware. 63 1.1 ad * 64 1.1 ad * TODO: 65 1.1 ad * 66 1.1 ad * o Make mly->mly_btl a hash, then MLY_BTL_RESCAN becomes a SIMPLEQ. 67 1.1 ad * o Handle FC and multiple LUNs. 68 1.1 ad * o Fix mmbox usage. 69 1.1 ad * o Fix transfer speed fudge. 70 1.1 ad */ 71 1.8 lukem 72 1.8 lukem #include <sys/cdefs.h> 73 1.56 andvar __KERNEL_RCSID(0, "$NetBSD: mly.c,v 1.56 2021/09/03 22:33:17 andvar Exp $"); 74 1.1 ad 75 1.1 ad #include <sys/param.h> 76 1.1 ad #include <sys/systm.h> 77 1.1 ad #include <sys/device.h> 78 1.1 ad #include <sys/kernel.h> 79 1.1 ad #include <sys/queue.h> 80 1.1 ad #include <sys/buf.h> 81 1.1 ad #include <sys/endian.h> 82 1.1 ad #include <sys/conf.h> 83 1.1 ad #include <sys/malloc.h> 84 1.1 ad #include <sys/ioctl.h> 85 1.1 ad #include <sys/scsiio.h> 86 1.1 ad #include <sys/kthread.h> 87 1.31 elad #include <sys/kauth.h> 88 1.1 ad 89 1.36 ad #include <sys/bus.h> 90 1.1 ad 91 1.1 ad #include <dev/scsipi/scsi_all.h> 92 1.1 ad #include <dev/scsipi/scsipi_all.h> 93 1.1 ad #include <dev/scsipi/scsiconf.h> 94 1.1 ad 95 1.1 ad #include <dev/pci/pcireg.h> 96 1.1 ad #include <dev/pci/pcivar.h> 97 1.1 ad #include <dev/pci/pcidevs.h> 98 1.1 ad 99 1.1 ad #include <dev/pci/mlyreg.h> 100 1.1 ad #include <dev/pci/mlyio.h> 101 1.1 ad #include <dev/pci/mlyvar.h> 102 1.1 ad #include <dev/pci/mly_tables.h> 103 1.1 ad 104 1.41 cegger static void mly_attach(device_t, device_t, void *); 105 1.41 cegger static int mly_match(device_t, cfdata_t, void *); 106 1.1 ad static const struct mly_ident *mly_find_ident(struct pci_attach_args *); 107 1.1 ad static int mly_fwhandshake(struct mly_softc *); 108 1.1 ad static int mly_flush(struct mly_softc *); 109 1.1 ad static int mly_intr(void *); 110 1.1 ad static void mly_shutdown(void *); 111 1.1 ad 112 1.1 ad static int mly_alloc_ccbs(struct mly_softc *); 113 1.1 ad static void mly_check_event(struct mly_softc *); 114 1.1 ad static void mly_complete_event(struct mly_softc *, struct mly_ccb *); 115 1.1 ad static void mly_complete_rescan(struct mly_softc *, struct mly_ccb *); 116 1.23 perry static int mly_dmamem_alloc(struct mly_softc *, int, bus_dmamap_t *, 117 1.34 christos void **, bus_addr_t *, bus_dma_segment_t *); 118 1.23 perry static void mly_dmamem_free(struct mly_softc *, int, bus_dmamap_t, 119 1.34 christos void *, bus_dma_segment_t *); 120 1.1 ad static int mly_enable_mmbox(struct mly_softc *); 121 1.1 ad static void mly_fetch_event(struct mly_softc *); 122 1.1 ad static int mly_get_controllerinfo(struct mly_softc *); 123 1.1 ad static int mly_get_eventstatus(struct mly_softc *); 124 1.1 ad static int mly_ioctl(struct mly_softc *, struct mly_cmd_ioctl *, 125 1.1 ad void **, size_t, void *, size_t *); 126 1.1 ad static void mly_padstr(char *, const char *, int); 127 1.1 ad static void mly_process_event(struct mly_softc *, struct mly_event *); 128 1.1 ad static void mly_release_ccbs(struct mly_softc *); 129 1.1 ad static int mly_scan_btl(struct mly_softc *, int, int); 130 1.1 ad static void mly_scan_channel(struct mly_softc *, int); 131 1.1 ad static void mly_thread(void *); 132 1.1 ad 133 1.1 ad static int mly_ccb_alloc(struct mly_softc *, struct mly_ccb **); 134 1.1 ad static void mly_ccb_complete(struct mly_softc *, struct mly_ccb *); 135 1.1 ad static void mly_ccb_enqueue(struct mly_softc *, struct mly_ccb *); 136 1.1 ad static void mly_ccb_free(struct mly_softc *, struct mly_ccb *); 137 1.1 ad static int mly_ccb_map(struct mly_softc *, struct mly_ccb *); 138 1.1 ad static int mly_ccb_poll(struct mly_softc *, struct mly_ccb *, int); 139 1.1 ad static int mly_ccb_submit(struct mly_softc *, struct mly_ccb *); 140 1.1 ad static void mly_ccb_unmap(struct mly_softc *, struct mly_ccb *); 141 1.1 ad static int mly_ccb_wait(struct mly_softc *, struct mly_ccb *, int); 142 1.1 ad 143 1.23 perry static void mly_get_xfer_mode(struct mly_softc *, int, 144 1.1 ad struct scsipi_xfer_mode *); 145 1.1 ad static void mly_scsipi_complete(struct mly_softc *, struct mly_ccb *); 146 1.34 christos static int mly_scsipi_ioctl(struct scsipi_channel *, u_long, void *, 147 1.1 ad int, struct proc *); 148 1.1 ad static void mly_scsipi_minphys(struct buf *); 149 1.1 ad static void mly_scsipi_request(struct scsipi_channel *, 150 1.1 ad scsipi_adapter_req_t, void *); 151 1.1 ad 152 1.1 ad static int mly_user_command(struct mly_softc *, struct mly_user_command *); 153 1.1 ad static int mly_user_health(struct mly_softc *, struct mly_user_health *); 154 1.1 ad 155 1.1 ad extern struct cfdriver mly_cd; 156 1.1 ad 157 1.45 chs CFATTACH_DECL_NEW(mly, sizeof(struct mly_softc), 158 1.14 thorpej mly_match, mly_attach, NULL, NULL); 159 1.11 gehenna 160 1.11 gehenna dev_type_open(mlyopen); 161 1.11 gehenna dev_type_close(mlyclose); 162 1.11 gehenna dev_type_ioctl(mlyioctl); 163 1.11 gehenna 164 1.11 gehenna const struct cdevsw mly_cdevsw = { 165 1.47 dholland .d_open = mlyopen, 166 1.47 dholland .d_close = mlyclose, 167 1.47 dholland .d_read = noread, 168 1.47 dholland .d_write = nowrite, 169 1.47 dholland .d_ioctl = mlyioctl, 170 1.47 dholland .d_stop = nostop, 171 1.47 dholland .d_tty = notty, 172 1.47 dholland .d_poll = nopoll, 173 1.47 dholland .d_mmap = nommap, 174 1.47 dholland .d_kqfilter = nokqfilter, 175 1.49 dholland .d_discard = nodiscard, 176 1.47 dholland .d_flag = D_OTHER 177 1.1 ad }; 178 1.1 ad 179 1.29 christos static struct mly_ident { 180 1.1 ad u_short vendor; 181 1.1 ad u_short product; 182 1.1 ad u_short subvendor; 183 1.1 ad u_short subproduct; 184 1.1 ad int hwif; 185 1.1 ad const char *desc; 186 1.29 christos } const mly_ident[] = { 187 1.1 ad { 188 1.1 ad PCI_VENDOR_MYLEX, 189 1.1 ad PCI_PRODUCT_MYLEX_EXTREMERAID, 190 1.1 ad PCI_VENDOR_MYLEX, 191 1.1 ad 0x0040, 192 1.1 ad MLY_HWIF_STRONGARM, 193 1.1 ad "eXtremeRAID 2000" 194 1.1 ad }, 195 1.1 ad { 196 1.1 ad PCI_VENDOR_MYLEX, 197 1.1 ad PCI_PRODUCT_MYLEX_EXTREMERAID, 198 1.1 ad PCI_VENDOR_MYLEX, 199 1.1 ad 0x0030, 200 1.1 ad MLY_HWIF_STRONGARM, 201 1.1 ad "eXtremeRAID 3000" 202 1.1 ad }, 203 1.1 ad { 204 1.1 ad PCI_VENDOR_MYLEX, 205 1.1 ad PCI_PRODUCT_MYLEX_ACCELERAID, 206 1.1 ad PCI_VENDOR_MYLEX, 207 1.1 ad 0x0050, 208 1.1 ad MLY_HWIF_I960RX, 209 1.1 ad "AcceleRAID 352" 210 1.1 ad }, 211 1.1 ad { 212 1.1 ad PCI_VENDOR_MYLEX, 213 1.1 ad PCI_PRODUCT_MYLEX_ACCELERAID, 214 1.1 ad PCI_VENDOR_MYLEX, 215 1.1 ad 0x0052, 216 1.1 ad MLY_HWIF_I960RX, 217 1.1 ad "AcceleRAID 170" 218 1.1 ad }, 219 1.1 ad { 220 1.1 ad PCI_VENDOR_MYLEX, 221 1.1 ad PCI_PRODUCT_MYLEX_ACCELERAID, 222 1.1 ad PCI_VENDOR_MYLEX, 223 1.1 ad 0x0054, 224 1.1 ad MLY_HWIF_I960RX, 225 1.1 ad "AcceleRAID 160" 226 1.1 ad }, 227 1.1 ad }; 228 1.1 ad 229 1.1 ad static void *mly_sdh; 230 1.1 ad 231 1.1 ad /* 232 1.1 ad * Try to find a `mly_ident' entry corresponding to this board. 233 1.1 ad */ 234 1.1 ad static const struct mly_ident * 235 1.1 ad mly_find_ident(struct pci_attach_args *pa) 236 1.1 ad { 237 1.1 ad const struct mly_ident *mpi, *maxmpi; 238 1.1 ad pcireg_t reg; 239 1.1 ad 240 1.1 ad mpi = mly_ident; 241 1.1 ad maxmpi = mpi + sizeof(mly_ident) / sizeof(mly_ident[0]); 242 1.2 ad 243 1.2 ad if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O) 244 1.2 ad return (NULL); 245 1.1 ad 246 1.1 ad for (; mpi < maxmpi; mpi++) { 247 1.1 ad if (PCI_VENDOR(pa->pa_id) != mpi->vendor || 248 1.1 ad PCI_PRODUCT(pa->pa_id) != mpi->product) 249 1.1 ad continue; 250 1.1 ad 251 1.1 ad if (mpi->subvendor == 0x0000) 252 1.1 ad return (mpi); 253 1.1 ad 254 1.1 ad reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 255 1.1 ad 256 1.1 ad if (PCI_VENDOR(reg) == mpi->subvendor && 257 1.1 ad PCI_PRODUCT(reg) == mpi->subproduct) 258 1.1 ad return (mpi); 259 1.1 ad } 260 1.1 ad 261 1.1 ad return (NULL); 262 1.1 ad } 263 1.1 ad 264 1.1 ad /* 265 1.1 ad * Match a supported board. 266 1.1 ad */ 267 1.1 ad static int 268 1.41 cegger mly_match(device_t parent, cfdata_t cfdata, void *aux) 269 1.1 ad { 270 1.1 ad 271 1.1 ad return (mly_find_ident(aux) != NULL); 272 1.1 ad } 273 1.1 ad 274 1.1 ad /* 275 1.1 ad * Attach a supported board. 276 1.1 ad */ 277 1.1 ad static void 278 1.41 cegger mly_attach(device_t parent, device_t self, void *aux) 279 1.1 ad { 280 1.1 ad struct pci_attach_args *pa; 281 1.1 ad struct mly_softc *mly; 282 1.1 ad struct mly_ioctl_getcontrollerinfo *mi; 283 1.1 ad const struct mly_ident *ident; 284 1.1 ad pci_chipset_tag_t pc; 285 1.1 ad pci_intr_handle_t ih; 286 1.1 ad bus_space_handle_t memh, ioh; 287 1.1 ad bus_space_tag_t memt, iot; 288 1.1 ad pcireg_t reg; 289 1.1 ad const char *intrstr; 290 1.1 ad int ior, memr, i, rv, state; 291 1.1 ad struct scsipi_adapter *adapt; 292 1.1 ad struct scsipi_channel *chan; 293 1.48 christos char intrbuf[PCI_INTRSTR_LEN]; 294 1.1 ad 295 1.42 cegger mly = device_private(self); 296 1.45 chs mly->mly_dv = self; 297 1.1 ad pa = aux; 298 1.1 ad pc = pa->pa_pc; 299 1.1 ad ident = mly_find_ident(pa); 300 1.1 ad state = 0; 301 1.1 ad 302 1.1 ad mly->mly_dmat = pa->pa_dmat; 303 1.1 ad mly->mly_hwif = ident->hwif; 304 1.1 ad 305 1.1 ad printf(": Mylex %s\n", ident->desc); 306 1.1 ad 307 1.1 ad /* 308 1.1 ad * Map the PCI register window. 309 1.1 ad */ 310 1.1 ad memr = -1; 311 1.1 ad ior = -1; 312 1.1 ad 313 1.1 ad for (i = 0x10; i <= 0x14; i += 4) { 314 1.1 ad reg = pci_conf_read(pa->pa_pc, pa->pa_tag, i); 315 1.1 ad 316 1.1 ad if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) { 317 1.1 ad if (ior == -1 && PCI_MAPREG_IO_SIZE(reg) != 0) 318 1.1 ad ior = i; 319 1.1 ad } else { 320 1.1 ad if (memr == -1 && PCI_MAPREG_MEM_SIZE(reg) != 0) 321 1.1 ad memr = i; 322 1.1 ad } 323 1.1 ad } 324 1.1 ad 325 1.1 ad if (memr != -1) 326 1.1 ad if (pci_mapreg_map(pa, memr, PCI_MAPREG_TYPE_MEM, 0, 327 1.1 ad &memt, &memh, NULL, NULL)) 328 1.1 ad memr = -1; 329 1.1 ad if (ior != -1) 330 1.1 ad if (pci_mapreg_map(pa, ior, PCI_MAPREG_TYPE_IO, 0, 331 1.1 ad &iot, &ioh, NULL, NULL)) 332 1.1 ad ior = -1; 333 1.1 ad 334 1.1 ad if (memr != -1) { 335 1.1 ad mly->mly_iot = memt; 336 1.1 ad mly->mly_ioh = memh; 337 1.1 ad } else if (ior != -1) { 338 1.1 ad mly->mly_iot = iot; 339 1.1 ad mly->mly_ioh = ioh; 340 1.1 ad } else { 341 1.37 cegger aprint_error_dev(self, "can't map i/o or memory space\n"); 342 1.1 ad return; 343 1.1 ad } 344 1.1 ad 345 1.1 ad /* 346 1.1 ad * Enable the device. 347 1.1 ad */ 348 1.1 ad reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 349 1.1 ad pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 350 1.1 ad reg | PCI_COMMAND_MASTER_ENABLE); 351 1.1 ad 352 1.1 ad /* 353 1.1 ad * Map and establish the interrupt. 354 1.1 ad */ 355 1.1 ad if (pci_intr_map(pa, &ih)) { 356 1.37 cegger aprint_error_dev(self, "can't map interrupt\n"); 357 1.1 ad return; 358 1.1 ad } 359 1.48 christos intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 360 1.52 jdolecek mly->mly_ih = pci_intr_establish_xname(pc, ih, IPL_BIO, mly_intr, mly, 361 1.52 jdolecek device_xname(self)); 362 1.1 ad if (mly->mly_ih == NULL) { 363 1.37 cegger aprint_error_dev(self, "can't establish interrupt"); 364 1.1 ad if (intrstr != NULL) 365 1.43 njoly aprint_error(" at %s", intrstr); 366 1.43 njoly aprint_error("\n"); 367 1.1 ad return; 368 1.1 ad } 369 1.1 ad 370 1.1 ad if (intrstr != NULL) 371 1.50 msaitoh aprint_normal_dev(self, "interrupting at %s\n", intrstr); 372 1.1 ad 373 1.1 ad /* 374 1.1 ad * Take care of interface-specific tasks. 375 1.1 ad */ 376 1.1 ad switch (mly->mly_hwif) { 377 1.1 ad case MLY_HWIF_I960RX: 378 1.1 ad mly->mly_doorbell_true = 0x00; 379 1.1 ad mly->mly_cmd_mailbox = MLY_I960RX_COMMAND_MAILBOX; 380 1.1 ad mly->mly_status_mailbox = MLY_I960RX_STATUS_MAILBOX; 381 1.1 ad mly->mly_idbr = MLY_I960RX_IDBR; 382 1.1 ad mly->mly_odbr = MLY_I960RX_ODBR; 383 1.1 ad mly->mly_error_status = MLY_I960RX_ERROR_STATUS; 384 1.1 ad mly->mly_interrupt_status = MLY_I960RX_INTERRUPT_STATUS; 385 1.1 ad mly->mly_interrupt_mask = MLY_I960RX_INTERRUPT_MASK; 386 1.1 ad break; 387 1.1 ad 388 1.1 ad case MLY_HWIF_STRONGARM: 389 1.1 ad mly->mly_doorbell_true = 0xff; 390 1.1 ad mly->mly_cmd_mailbox = MLY_STRONGARM_COMMAND_MAILBOX; 391 1.1 ad mly->mly_status_mailbox = MLY_STRONGARM_STATUS_MAILBOX; 392 1.1 ad mly->mly_idbr = MLY_STRONGARM_IDBR; 393 1.1 ad mly->mly_odbr = MLY_STRONGARM_ODBR; 394 1.1 ad mly->mly_error_status = MLY_STRONGARM_ERROR_STATUS; 395 1.1 ad mly->mly_interrupt_status = MLY_STRONGARM_INTERRUPT_STATUS; 396 1.1 ad mly->mly_interrupt_mask = MLY_STRONGARM_INTERRUPT_MASK; 397 1.1 ad break; 398 1.1 ad } 399 1.1 ad 400 1.1 ad /* 401 1.1 ad * Allocate and map the scatter/gather lists. 402 1.1 ad */ 403 1.1 ad rv = mly_dmamem_alloc(mly, MLY_SGL_SIZE * MLY_MAX_CCBS, 404 1.34 christos &mly->mly_sg_dmamap, (void **)&mly->mly_sg, 405 1.1 ad &mly->mly_sg_busaddr, &mly->mly_sg_seg); 406 1.1 ad if (rv) { 407 1.1 ad printf("%s: unable to allocate S/G maps\n", 408 1.45 chs device_xname(self)); 409 1.1 ad goto bad; 410 1.1 ad } 411 1.1 ad state++; 412 1.1 ad 413 1.1 ad /* 414 1.1 ad * Allocate and map the memory mailbox. 415 1.1 ad */ 416 1.1 ad rv = mly_dmamem_alloc(mly, sizeof(struct mly_mmbox), 417 1.34 christos &mly->mly_mmbox_dmamap, (void **)&mly->mly_mmbox, 418 1.1 ad &mly->mly_mmbox_busaddr, &mly->mly_mmbox_seg); 419 1.1 ad if (rv) { 420 1.45 chs aprint_error_dev(self, "unable to allocate mailboxes\n"); 421 1.1 ad goto bad; 422 1.1 ad } 423 1.1 ad state++; 424 1.1 ad 425 1.1 ad /* 426 1.1 ad * Initialise per-controller queues. 427 1.1 ad */ 428 1.1 ad SLIST_INIT(&mly->mly_ccb_free); 429 1.1 ad SIMPLEQ_INIT(&mly->mly_ccb_queue); 430 1.1 ad 431 1.1 ad /* 432 1.1 ad * Disable interrupts before we start talking to the controller. 433 1.1 ad */ 434 1.1 ad mly_outb(mly, mly->mly_interrupt_mask, MLY_INTERRUPT_MASK_DISABLE); 435 1.1 ad 436 1.23 perry /* 437 1.1 ad * Wait for the controller to come ready, handshaking with the 438 1.1 ad * firmware if required. This is typically only necessary on 439 1.1 ad * platforms where the controller BIOS does not run. 440 1.1 ad */ 441 1.1 ad if (mly_fwhandshake(mly)) { 442 1.45 chs aprint_error_dev(self, "unable to bring controller online\n"); 443 1.1 ad goto bad; 444 1.1 ad } 445 1.1 ad 446 1.1 ad /* 447 1.1 ad * Allocate initial command buffers, obtain controller feature 448 1.1 ad * information, and then reallocate command buffers, since we'll 449 1.1 ad * know how many we want. 450 1.1 ad */ 451 1.1 ad if (mly_alloc_ccbs(mly)) { 452 1.45 chs aprint_error_dev(self, "unable to allocate CCBs\n"); 453 1.1 ad goto bad; 454 1.1 ad } 455 1.1 ad state++; 456 1.1 ad if (mly_get_controllerinfo(mly)) { 457 1.45 chs aprint_error_dev(self, "unable to retrieve controller info\n"); 458 1.1 ad goto bad; 459 1.1 ad } 460 1.1 ad mly_release_ccbs(mly); 461 1.1 ad if (mly_alloc_ccbs(mly)) { 462 1.45 chs aprint_error_dev(self, "unable to allocate CCBs\n"); 463 1.1 ad state--; 464 1.1 ad goto bad; 465 1.1 ad } 466 1.1 ad 467 1.1 ad /* 468 1.1 ad * Get the current event counter for health purposes, populate the 469 1.1 ad * initial health status buffer. 470 1.1 ad */ 471 1.1 ad if (mly_get_eventstatus(mly)) { 472 1.45 chs aprint_error_dev(self, "unable to retrieve event status\n"); 473 1.1 ad goto bad; 474 1.1 ad } 475 1.1 ad 476 1.1 ad /* 477 1.1 ad * Enable memory-mailbox mode. 478 1.1 ad */ 479 1.1 ad if (mly_enable_mmbox(mly)) { 480 1.45 chs aprint_error_dev(self, "unable to enable memory mailbox\n"); 481 1.1 ad goto bad; 482 1.1 ad } 483 1.1 ad 484 1.23 perry /* 485 1.1 ad * Print a little information about the controller. 486 1.1 ad */ 487 1.1 ad mi = mly->mly_controllerinfo; 488 1.1 ad 489 1.1 ad printf("%s: %d physical channel%s, firmware %d.%02d-%d-%02d " 490 1.45 chs "(%02d%02d%02d%02d), %dMB RAM\n", device_xname(self), 491 1.1 ad mi->physical_channels_present, 492 1.1 ad (mi->physical_channels_present) > 1 ? "s" : "", 493 1.1 ad mi->fw_major, mi->fw_minor, mi->fw_turn, mi->fw_build, 494 1.1 ad mi->fw_century, mi->fw_year, mi->fw_month, mi->fw_day, 495 1.1 ad le16toh(mi->memory_size)); 496 1.1 ad 497 1.1 ad /* 498 1.1 ad * Register our `shutdownhook'. 499 1.1 ad */ 500 1.1 ad if (mly_sdh == NULL) 501 1.1 ad shutdownhook_establish(mly_shutdown, NULL); 502 1.1 ad 503 1.1 ad /* 504 1.1 ad * Clear any previous BTL information. For each bus that scsipi 505 1.1 ad * wants to scan, we'll receive the SCBUSIOLLSCAN ioctl and retrieve 506 1.1 ad * all BTL info at that point. 507 1.1 ad */ 508 1.1 ad memset(&mly->mly_btl, 0, sizeof(mly->mly_btl)); 509 1.1 ad 510 1.1 ad mly->mly_nchans = mly->mly_controllerinfo->physical_channels_present + 511 1.1 ad mly->mly_controllerinfo->virtual_channels_present; 512 1.1 ad 513 1.1 ad /* 514 1.1 ad * Attach to scsipi. 515 1.1 ad */ 516 1.1 ad adapt = &mly->mly_adapt; 517 1.1 ad memset(adapt, 0, sizeof(*adapt)); 518 1.45 chs adapt->adapt_dev = self; 519 1.1 ad adapt->adapt_nchannels = mly->mly_nchans; 520 1.1 ad adapt->adapt_openings = mly->mly_ncmds - MLY_CCBS_RESV; 521 1.1 ad adapt->adapt_max_periph = mly->mly_ncmds - MLY_CCBS_RESV; 522 1.1 ad adapt->adapt_request = mly_scsipi_request; 523 1.1 ad adapt->adapt_minphys = mly_scsipi_minphys; 524 1.1 ad adapt->adapt_ioctl = mly_scsipi_ioctl; 525 1.1 ad 526 1.1 ad for (i = 0; i < mly->mly_nchans; i++) { 527 1.1 ad chan = &mly->mly_chans[i]; 528 1.1 ad memset(chan, 0, sizeof(*chan)); 529 1.1 ad chan->chan_adapter = adapt; 530 1.1 ad chan->chan_bustype = &scsi_bustype; 531 1.1 ad chan->chan_channel = i; 532 1.1 ad chan->chan_ntargets = MLY_MAX_TARGETS; 533 1.1 ad chan->chan_nluns = MLY_MAX_LUNS; 534 1.1 ad chan->chan_id = mly->mly_controllerparam->initiator_id; 535 1.1 ad chan->chan_flags = SCSIPI_CHAN_NOSETTLE; 536 1.55 thorpej config_found(self, chan, scsiprint, CFARGS_NONE); 537 1.1 ad } 538 1.1 ad 539 1.1 ad /* 540 1.1 ad * Now enable interrupts... 541 1.1 ad */ 542 1.1 ad mly_outb(mly, mly->mly_interrupt_mask, MLY_INTERRUPT_MASK_ENABLE); 543 1.1 ad 544 1.1 ad /* 545 1.1 ad * Finally, create our monitoring thread. 546 1.1 ad */ 547 1.1 ad mly->mly_state |= MLY_STATE_INITOK; 548 1.35 ad rv = kthread_create(PRI_NONE, 0, NULL, mly_thread, mly, 549 1.45 chs &mly->mly_thread, "%s", device_xname(self)); 550 1.35 ad if (rv != 0) 551 1.50 msaitoh aprint_error_dev(self, "unable to create thread (%d)\n", rv); 552 1.1 ad return; 553 1.1 ad 554 1.1 ad bad: 555 1.1 ad if (state > 2) 556 1.1 ad mly_release_ccbs(mly); 557 1.1 ad if (state > 1) 558 1.1 ad mly_dmamem_free(mly, sizeof(struct mly_mmbox), 559 1.34 christos mly->mly_mmbox_dmamap, (void *)mly->mly_mmbox, 560 1.1 ad &mly->mly_mmbox_seg); 561 1.1 ad if (state > 0) 562 1.1 ad mly_dmamem_free(mly, MLY_SGL_SIZE * MLY_MAX_CCBS, 563 1.34 christos mly->mly_sg_dmamap, (void *)mly->mly_sg, 564 1.1 ad &mly->mly_sg_seg); 565 1.1 ad } 566 1.1 ad 567 1.1 ad /* 568 1.1 ad * Scan all possible devices on the specified channel. 569 1.1 ad */ 570 1.1 ad static void 571 1.1 ad mly_scan_channel(struct mly_softc *mly, int bus) 572 1.1 ad { 573 1.3 ad int s, target; 574 1.1 ad 575 1.3 ad for (target = 0; target < MLY_MAX_TARGETS; target++) { 576 1.3 ad s = splbio(); 577 1.3 ad if (!mly_scan_btl(mly, bus, target)) { 578 1.3 ad tsleep(&mly->mly_btl[bus][target], PRIBIO, "mlyscan", 579 1.3 ad 0); 580 1.3 ad } 581 1.3 ad splx(s); 582 1.1 ad } 583 1.1 ad } 584 1.1 ad 585 1.1 ad /* 586 1.1 ad * Shut down all configured `mly' devices. 587 1.1 ad */ 588 1.1 ad static void 589 1.32 christos mly_shutdown(void *cookie) 590 1.1 ad { 591 1.1 ad struct mly_softc *mly; 592 1.1 ad int i; 593 1.1 ad 594 1.1 ad for (i = 0; i < mly_cd.cd_ndevs; i++) { 595 1.39 tsutsui if ((mly = device_lookup_private(&mly_cd, i)) == NULL) 596 1.1 ad continue; 597 1.1 ad 598 1.1 ad if (mly_flush(mly)) 599 1.45 chs aprint_error_dev(mly->mly_dv, "unable to flush cache\n"); 600 1.1 ad } 601 1.1 ad } 602 1.1 ad 603 1.1 ad /* 604 1.1 ad * Fill in the mly_controllerinfo and mly_controllerparam fields in the 605 1.1 ad * softc. 606 1.1 ad */ 607 1.1 ad static int 608 1.1 ad mly_get_controllerinfo(struct mly_softc *mly) 609 1.1 ad { 610 1.1 ad struct mly_cmd_ioctl mci; 611 1.1 ad int rv; 612 1.1 ad 613 1.1 ad /* 614 1.1 ad * Build the getcontrollerinfo ioctl and send it. 615 1.1 ad */ 616 1.1 ad memset(&mci, 0, sizeof(mci)); 617 1.1 ad mci.sub_ioctl = MDACIOCTL_GETCONTROLLERINFO; 618 1.1 ad rv = mly_ioctl(mly, &mci, (void **)&mly->mly_controllerinfo, 619 1.1 ad sizeof(*mly->mly_controllerinfo), NULL, NULL); 620 1.1 ad if (rv != 0) 621 1.1 ad return (rv); 622 1.1 ad 623 1.1 ad /* 624 1.1 ad * Build the getcontrollerparameter ioctl and send it. 625 1.1 ad */ 626 1.1 ad memset(&mci, 0, sizeof(mci)); 627 1.1 ad mci.sub_ioctl = MDACIOCTL_GETCONTROLLERPARAMETER; 628 1.1 ad rv = mly_ioctl(mly, &mci, (void **)&mly->mly_controllerparam, 629 1.1 ad sizeof(*mly->mly_controllerparam), NULL, NULL); 630 1.1 ad 631 1.1 ad return (rv); 632 1.1 ad } 633 1.1 ad 634 1.1 ad /* 635 1.1 ad * Rescan a device, possibly as a consequence of getting an event which 636 1.1 ad * suggests that it may have changed. Must be called with interrupts 637 1.1 ad * blocked. 638 1.1 ad */ 639 1.1 ad static int 640 1.1 ad mly_scan_btl(struct mly_softc *mly, int bus, int target) 641 1.1 ad { 642 1.1 ad struct mly_ccb *mc; 643 1.1 ad struct mly_cmd_ioctl *mci; 644 1.1 ad int rv; 645 1.1 ad 646 1.1 ad if (target == mly->mly_controllerparam->initiator_id) { 647 1.1 ad mly->mly_btl[bus][target].mb_flags = MLY_BTL_PROTECTED; 648 1.1 ad return (EIO); 649 1.1 ad } 650 1.1 ad 651 1.1 ad /* Don't re-scan if a scan is already in progress. */ 652 1.1 ad if ((mly->mly_btl[bus][target].mb_flags & MLY_BTL_SCANNING) != 0) 653 1.1 ad return (EBUSY); 654 1.1 ad 655 1.1 ad /* Get a command. */ 656 1.1 ad if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 657 1.1 ad return (rv); 658 1.1 ad 659 1.1 ad /* Set up the data buffer. */ 660 1.23 perry mc->mc_data = malloc(sizeof(union mly_devinfo), 661 1.9 tsutsui M_DEVBUF, M_NOWAIT|M_ZERO); 662 1.1 ad 663 1.1 ad mc->mc_flags |= MLY_CCB_DATAIN; 664 1.1 ad mc->mc_complete = mly_complete_rescan; 665 1.1 ad 666 1.23 perry /* 667 1.1 ad * Build the ioctl. 668 1.1 ad */ 669 1.1 ad mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 670 1.1 ad mci->opcode = MDACMD_IOCTL; 671 1.1 ad mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 672 1.1 ad memset(&mci->param, 0, sizeof(mci->param)); 673 1.1 ad 674 1.1 ad if (MLY_BUS_IS_VIRTUAL(mly, bus)) { 675 1.1 ad mc->mc_length = sizeof(struct mly_ioctl_getlogdevinfovalid); 676 1.1 ad mci->data_size = htole32(mc->mc_length); 677 1.1 ad mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID; 678 1.1 ad _lto3l(MLY_LOGADDR(0, MLY_LOGDEV_ID(mly, bus, target)), 679 1.1 ad mci->addr); 680 1.1 ad } else { 681 1.1 ad mc->mc_length = sizeof(struct mly_ioctl_getphysdevinfovalid); 682 1.1 ad mci->data_size = htole32(mc->mc_length); 683 1.1 ad mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID; 684 1.1 ad _lto3l(MLY_PHYADDR(0, bus, target, 0), mci->addr); 685 1.1 ad } 686 1.1 ad 687 1.1 ad /* 688 1.1 ad * Dispatch the command. 689 1.1 ad */ 690 1.3 ad if ((rv = mly_ccb_map(mly, mc)) != 0) { 691 1.3 ad free(mc->mc_data, M_DEVBUF); 692 1.3 ad mly_ccb_free(mly, mc); 693 1.3 ad return(rv); 694 1.3 ad } 695 1.3 ad 696 1.1 ad mly->mly_btl[bus][target].mb_flags |= MLY_BTL_SCANNING; 697 1.1 ad mly_ccb_enqueue(mly, mc); 698 1.1 ad return (0); 699 1.1 ad } 700 1.1 ad 701 1.1 ad /* 702 1.1 ad * Handle the completion of a rescan operation. 703 1.1 ad */ 704 1.1 ad static void 705 1.1 ad mly_complete_rescan(struct mly_softc *mly, struct mly_ccb *mc) 706 1.1 ad { 707 1.1 ad struct mly_ioctl_getlogdevinfovalid *ldi; 708 1.1 ad struct mly_ioctl_getphysdevinfovalid *pdi; 709 1.1 ad struct mly_cmd_ioctl *mci; 710 1.1 ad struct mly_btl btl, *btlp; 711 1.1 ad struct scsipi_xfer_mode xm; 712 1.1 ad int bus, target, rescan; 713 1.1 ad u_int tmp; 714 1.1 ad 715 1.1 ad mly_ccb_unmap(mly, mc); 716 1.1 ad 717 1.1 ad /* 718 1.1 ad * Recover the bus and target from the command. We need these even 719 1.1 ad * in the case where we don't have a useful response. 720 1.1 ad */ 721 1.1 ad mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 722 1.1 ad tmp = _3ltol(mci->addr); 723 1.1 ad rescan = 0; 724 1.1 ad 725 1.1 ad if (mci->sub_ioctl == MDACIOCTL_GETLOGDEVINFOVALID) { 726 1.1 ad bus = MLY_LOGDEV_BUS(mly, MLY_LOGADDR_DEV(tmp)); 727 1.1 ad target = MLY_LOGDEV_TARGET(mly, MLY_LOGADDR_DEV(tmp)); 728 1.1 ad } else { 729 1.1 ad bus = MLY_PHYADDR_CHANNEL(tmp); 730 1.1 ad target = MLY_PHYADDR_TARGET(tmp); 731 1.1 ad } 732 1.1 ad 733 1.1 ad btlp = &mly->mly_btl[bus][target]; 734 1.1 ad 735 1.1 ad /* The default result is 'no device'. */ 736 1.1 ad memset(&btl, 0, sizeof(btl)); 737 1.1 ad btl.mb_flags = MLY_BTL_PROTECTED; 738 1.1 ad 739 1.1 ad /* If the rescan completed OK, we have possibly-new BTL data. */ 740 1.1 ad if (mc->mc_status != 0) 741 1.1 ad goto out; 742 1.1 ad 743 1.1 ad if (mc->mc_length == sizeof(*ldi)) { 744 1.1 ad ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data; 745 1.1 ad tmp = le32toh(ldi->logical_device_number); 746 1.1 ad 747 1.1 ad if (MLY_LOGDEV_BUS(mly, tmp) != bus || 748 1.1 ad MLY_LOGDEV_TARGET(mly, tmp) != target) { 749 1.3 ad #ifdef MLYDEBUG 750 1.1 ad printf("%s: WARNING: BTL rescan (logical) for %d:%d " 751 1.23 perry "returned data for %d:%d instead\n", 752 1.45 chs device_xname(mly->mly_dv), bus, target, 753 1.1 ad MLY_LOGDEV_BUS(mly, tmp), 754 1.1 ad MLY_LOGDEV_TARGET(mly, tmp)); 755 1.1 ad #endif 756 1.1 ad goto out; 757 1.1 ad } 758 1.1 ad 759 1.1 ad btl.mb_flags = MLY_BTL_LOGICAL | MLY_BTL_TQING; 760 1.1 ad btl.mb_type = ldi->raid_level; 761 1.1 ad btl.mb_state = ldi->state; 762 1.1 ad } else if (mc->mc_length == sizeof(*pdi)) { 763 1.1 ad pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data; 764 1.1 ad 765 1.1 ad if (pdi->channel != bus || pdi->target != target) { 766 1.3 ad #ifdef MLYDEBUG 767 1.1 ad printf("%s: WARNING: BTL rescan (physical) for %d:%d " 768 1.23 perry " returned data for %d:%d instead\n", 769 1.45 chs device_xname(mly->mly_dv), 770 1.1 ad bus, target, pdi->channel, pdi->target); 771 1.1 ad #endif 772 1.1 ad goto out; 773 1.1 ad } 774 1.1 ad 775 1.1 ad btl.mb_flags = MLY_BTL_PHYSICAL; 776 1.1 ad btl.mb_type = MLY_DEVICE_TYPE_PHYSICAL; 777 1.1 ad btl.mb_state = pdi->state; 778 1.1 ad btl.mb_speed = pdi->speed; 779 1.1 ad btl.mb_width = pdi->width; 780 1.1 ad 781 1.1 ad if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED) 782 1.1 ad btl.mb_flags |= MLY_BTL_PROTECTED; 783 1.1 ad if (pdi->command_tags != 0) 784 1.1 ad btl.mb_flags |= MLY_BTL_TQING; 785 1.1 ad } else { 786 1.45 chs printf("%s: BTL rescan result invalid\n", device_xname(mly->mly_dv)); 787 1.1 ad goto out; 788 1.1 ad } 789 1.1 ad 790 1.1 ad /* Decide whether we need to rescan the device. */ 791 1.1 ad if (btl.mb_flags != btlp->mb_flags || 792 1.1 ad btl.mb_speed != btlp->mb_speed || 793 1.1 ad btl.mb_width != btlp->mb_width) 794 1.1 ad rescan = 1; 795 1.1 ad 796 1.1 ad out: 797 1.1 ad *btlp = btl; 798 1.1 ad 799 1.1 ad if (rescan && (btl.mb_flags & MLY_BTL_PROTECTED) == 0) { 800 1.1 ad xm.xm_target = target; 801 1.1 ad mly_get_xfer_mode(mly, bus, &xm); 802 1.1 ad /* XXX SCSI mid-layer rescan goes here. */ 803 1.1 ad } 804 1.1 ad 805 1.1 ad /* Wake anybody waiting on the device to be rescanned. */ 806 1.1 ad wakeup(btlp); 807 1.1 ad 808 1.1 ad free(mc->mc_data, M_DEVBUF); 809 1.1 ad mly_ccb_free(mly, mc); 810 1.1 ad } 811 1.1 ad 812 1.1 ad /* 813 1.1 ad * Get the current health status and set the 'next event' counter to suit. 814 1.1 ad */ 815 1.1 ad static int 816 1.1 ad mly_get_eventstatus(struct mly_softc *mly) 817 1.1 ad { 818 1.1 ad struct mly_cmd_ioctl mci; 819 1.1 ad struct mly_health_status *mh; 820 1.1 ad int rv; 821 1.1 ad 822 1.1 ad /* Build the gethealthstatus ioctl and send it. */ 823 1.1 ad memset(&mci, 0, sizeof(mci)); 824 1.1 ad mh = NULL; 825 1.1 ad mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS; 826 1.1 ad 827 1.16 thorpej rv = mly_ioctl(mly, &mci, (void *)&mh, sizeof(*mh), NULL, NULL); 828 1.1 ad if (rv) 829 1.1 ad return (rv); 830 1.1 ad 831 1.1 ad /* Get the event counter. */ 832 1.1 ad mly->mly_event_change = le32toh(mh->change_counter); 833 1.1 ad mly->mly_event_waiting = le32toh(mh->next_event); 834 1.1 ad mly->mly_event_counter = le32toh(mh->next_event); 835 1.1 ad 836 1.1 ad /* Save the health status into the memory mailbox */ 837 1.1 ad memcpy(&mly->mly_mmbox->mmm_health.status, mh, sizeof(*mh)); 838 1.1 ad 839 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 840 1.1 ad offsetof(struct mly_mmbox, mmm_health), 841 1.1 ad sizeof(mly->mly_mmbox->mmm_health), 842 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 843 1.1 ad 844 1.1 ad free(mh, M_DEVBUF); 845 1.1 ad return (0); 846 1.1 ad } 847 1.1 ad 848 1.1 ad /* 849 1.3 ad * Enable memory mailbox mode. 850 1.1 ad */ 851 1.1 ad static int 852 1.1 ad mly_enable_mmbox(struct mly_softc *mly) 853 1.1 ad { 854 1.1 ad struct mly_cmd_ioctl mci; 855 1.1 ad u_int8_t *sp; 856 1.1 ad u_int64_t tmp; 857 1.1 ad int rv; 858 1.1 ad 859 1.1 ad /* Build the ioctl and send it. */ 860 1.1 ad memset(&mci, 0, sizeof(mci)); 861 1.1 ad mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX; 862 1.1 ad 863 1.1 ad /* Set buffer addresses. */ 864 1.1 ad tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command); 865 1.1 ad mci.param.setmemorymailbox.command_mailbox_physaddr = htole64(tmp); 866 1.1 ad 867 1.1 ad tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status); 868 1.1 ad mci.param.setmemorymailbox.status_mailbox_physaddr = htole64(tmp); 869 1.1 ad 870 1.1 ad tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health); 871 1.1 ad mci.param.setmemorymailbox.health_buffer_physaddr = htole64(tmp); 872 1.1 ad 873 1.1 ad /* Set buffer sizes - abuse of data_size field is revolting. */ 874 1.1 ad sp = (u_int8_t *)&mci.data_size; 875 1.1 ad sp[0] = (sizeof(union mly_cmd_packet) * MLY_MMBOX_COMMANDS) >> 10; 876 1.1 ad sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) >> 10; 877 1.1 ad mci.param.setmemorymailbox.health_buffer_size = 878 1.1 ad sizeof(union mly_health_region) >> 10; 879 1.1 ad 880 1.1 ad rv = mly_ioctl(mly, &mci, NULL, 0, NULL, NULL); 881 1.1 ad if (rv) 882 1.1 ad return (rv); 883 1.1 ad 884 1.1 ad mly->mly_state |= MLY_STATE_MMBOX_ACTIVE; 885 1.1 ad return (0); 886 1.1 ad } 887 1.1 ad 888 1.1 ad /* 889 1.1 ad * Flush all pending I/O from the controller. 890 1.1 ad */ 891 1.1 ad static int 892 1.1 ad mly_flush(struct mly_softc *mly) 893 1.1 ad { 894 1.1 ad struct mly_cmd_ioctl mci; 895 1.1 ad 896 1.1 ad /* Build the ioctl */ 897 1.1 ad memset(&mci, 0, sizeof(mci)); 898 1.1 ad mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA; 899 1.1 ad mci.param.deviceoperation.operation_device = 900 1.1 ad MLY_OPDEVICE_PHYSICAL_CONTROLLER; 901 1.1 ad 902 1.1 ad /* Pass it off to the controller */ 903 1.1 ad return (mly_ioctl(mly, &mci, NULL, 0, NULL, NULL)); 904 1.1 ad } 905 1.1 ad 906 1.1 ad /* 907 1.1 ad * Perform an ioctl command. 908 1.1 ad * 909 1.3 ad * If (data) is not NULL, the command requires data transfer to the 910 1.3 ad * controller. If (*data) is NULL the command requires data transfer from 911 1.3 ad * the controller, and we will allocate a buffer for it. 912 1.1 ad */ 913 1.1 ad static int 914 1.1 ad mly_ioctl(struct mly_softc *mly, struct mly_cmd_ioctl *ioctl, void **data, 915 1.1 ad size_t datasize, void *sense_buffer, 916 1.1 ad size_t *sense_length) 917 1.1 ad { 918 1.1 ad struct mly_ccb *mc; 919 1.1 ad struct mly_cmd_ioctl *mci; 920 1.1 ad u_int8_t status; 921 1.1 ad int rv; 922 1.1 ad 923 1.1 ad mc = NULL; 924 1.1 ad if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 925 1.1 ad goto bad; 926 1.1 ad 927 1.1 ad /* 928 1.1 ad * Copy the ioctl structure, but save some important fields and then 929 1.1 ad * fixup. 930 1.1 ad */ 931 1.1 ad mci = &mc->mc_packet->ioctl; 932 1.1 ad ioctl->sense_buffer_address = htole64(mci->sense_buffer_address); 933 1.1 ad ioctl->maximum_sense_size = mci->maximum_sense_size; 934 1.1 ad *mci = *ioctl; 935 1.1 ad mci->opcode = MDACMD_IOCTL; 936 1.1 ad mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 937 1.1 ad 938 1.1 ad /* Handle the data buffer. */ 939 1.1 ad if (data != NULL) { 940 1.1 ad if (*data == NULL) { 941 1.1 ad /* Allocate data buffer */ 942 1.1 ad mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT); 943 1.1 ad mc->mc_flags |= MLY_CCB_DATAIN; 944 1.1 ad } else { 945 1.1 ad mc->mc_data = *data; 946 1.1 ad mc->mc_flags |= MLY_CCB_DATAOUT; 947 1.1 ad } 948 1.1 ad mc->mc_length = datasize; 949 1.1 ad mc->mc_packet->generic.data_size = htole32(datasize); 950 1.1 ad } 951 1.1 ad 952 1.1 ad /* Run the command. */ 953 1.1 ad if (datasize > 0) 954 1.1 ad if ((rv = mly_ccb_map(mly, mc)) != 0) 955 1.1 ad goto bad; 956 1.1 ad rv = mly_ccb_poll(mly, mc, 30000); 957 1.1 ad if (datasize > 0) 958 1.1 ad mly_ccb_unmap(mly, mc); 959 1.1 ad if (rv != 0) 960 1.1 ad goto bad; 961 1.1 ad 962 1.1 ad /* Clean up and return any data. */ 963 1.1 ad status = mc->mc_status; 964 1.1 ad 965 1.1 ad if (status != 0) 966 1.1 ad printf("mly_ioctl: command status %d\n", status); 967 1.1 ad 968 1.1 ad if (mc->mc_sense > 0 && sense_buffer != NULL) { 969 1.1 ad memcpy(sense_buffer, mc->mc_packet, mc->mc_sense); 970 1.1 ad *sense_length = mc->mc_sense; 971 1.1 ad goto bad; 972 1.1 ad } 973 1.1 ad 974 1.1 ad /* Should we return a data pointer? */ 975 1.1 ad if (data != NULL && *data == NULL) 976 1.1 ad *data = mc->mc_data; 977 1.1 ad 978 1.1 ad /* Command completed OK. */ 979 1.1 ad rv = (status != 0 ? EIO : 0); 980 1.1 ad 981 1.1 ad bad: 982 1.1 ad if (mc != NULL) { 983 1.1 ad /* Do we need to free a data buffer we allocated? */ 984 1.26 christos if (rv != 0 && mc->mc_data != NULL && 985 1.26 christos (data == NULL || *data == NULL)) 986 1.1 ad free(mc->mc_data, M_DEVBUF); 987 1.1 ad mly_ccb_free(mly, mc); 988 1.1 ad } 989 1.1 ad 990 1.1 ad return (rv); 991 1.1 ad } 992 1.1 ad 993 1.1 ad /* 994 1.1 ad * Check for event(s) outstanding in the controller. 995 1.1 ad */ 996 1.1 ad static void 997 1.1 ad mly_check_event(struct mly_softc *mly) 998 1.1 ad { 999 1.1 ad 1000 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1001 1.1 ad offsetof(struct mly_mmbox, mmm_health), 1002 1.1 ad sizeof(mly->mly_mmbox->mmm_health), 1003 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1004 1.1 ad 1005 1.1 ad /* 1006 1.1 ad * The controller may have updated the health status information, so 1007 1.1 ad * check for it here. Note that the counters are all in host 1008 1.1 ad * memory, so this check is very cheap. Also note that we depend on 1009 1.1 ad * checking on completion 1010 1.1 ad */ 1011 1.1 ad if (le32toh(mly->mly_mmbox->mmm_health.status.change_counter) != 1012 1.1 ad mly->mly_event_change) { 1013 1.1 ad mly->mly_event_change = 1014 1.1 ad le32toh(mly->mly_mmbox->mmm_health.status.change_counter); 1015 1.1 ad mly->mly_event_waiting = 1016 1.1 ad le32toh(mly->mly_mmbox->mmm_health.status.next_event); 1017 1.1 ad 1018 1.1 ad /* Wake up anyone that might be interested in this. */ 1019 1.1 ad wakeup(&mly->mly_event_change); 1020 1.1 ad } 1021 1.1 ad 1022 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1023 1.1 ad offsetof(struct mly_mmbox, mmm_health), 1024 1.1 ad sizeof(mly->mly_mmbox->mmm_health), 1025 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1026 1.1 ad 1027 1.1 ad if (mly->mly_event_counter != mly->mly_event_waiting) 1028 1.1 ad mly_fetch_event(mly); 1029 1.1 ad } 1030 1.1 ad 1031 1.1 ad /* 1032 1.1 ad * Fetch one event from the controller. If we fail due to resource 1033 1.1 ad * starvation, we'll be retried the next time a command completes. 1034 1.1 ad */ 1035 1.1 ad static void 1036 1.1 ad mly_fetch_event(struct mly_softc *mly) 1037 1.1 ad { 1038 1.1 ad struct mly_ccb *mc; 1039 1.1 ad struct mly_cmd_ioctl *mci; 1040 1.1 ad int s; 1041 1.1 ad u_int32_t event; 1042 1.1 ad 1043 1.1 ad /* Get a command. */ 1044 1.1 ad if (mly_ccb_alloc(mly, &mc)) 1045 1.1 ad return; 1046 1.1 ad 1047 1.1 ad /* Set up the data buffer. */ 1048 1.9 tsutsui mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, 1049 1.9 tsutsui M_NOWAIT|M_ZERO); 1050 1.1 ad 1051 1.1 ad mc->mc_length = sizeof(struct mly_event); 1052 1.1 ad mc->mc_flags |= MLY_CCB_DATAIN; 1053 1.1 ad mc->mc_complete = mly_complete_event; 1054 1.1 ad 1055 1.1 ad /* 1056 1.1 ad * Get an event number to fetch. It's possible that we've raced 1057 1.1 ad * with another context for the last event, in which case there will 1058 1.1 ad * be no more events. 1059 1.1 ad */ 1060 1.1 ad s = splbio(); 1061 1.1 ad if (mly->mly_event_counter == mly->mly_event_waiting) { 1062 1.1 ad splx(s); 1063 1.1 ad free(mc->mc_data, M_DEVBUF); 1064 1.1 ad mly_ccb_free(mly, mc); 1065 1.1 ad return; 1066 1.1 ad } 1067 1.1 ad event = mly->mly_event_counter++; 1068 1.1 ad splx(s); 1069 1.1 ad 1070 1.23 perry /* 1071 1.1 ad * Build the ioctl. 1072 1.1 ad * 1073 1.1 ad * At this point we are committed to sending this request, as it 1074 1.1 ad * will be the only one constructed for this particular event 1075 1.1 ad * number. 1076 1.1 ad */ 1077 1.1 ad mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 1078 1.1 ad mci->opcode = MDACMD_IOCTL; 1079 1.1 ad mci->data_size = htole32(sizeof(struct mly_event)); 1080 1.1 ad _lto3l(MLY_PHYADDR(0, 0, (event >> 16) & 0xff, (event >> 24) & 0xff), 1081 1.1 ad mci->addr); 1082 1.1 ad mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 1083 1.1 ad mci->sub_ioctl = MDACIOCTL_GETEVENT; 1084 1.1 ad mci->param.getevent.sequence_number_low = htole16(event & 0xffff); 1085 1.1 ad 1086 1.1 ad /* 1087 1.1 ad * Submit the command. 1088 1.1 ad */ 1089 1.1 ad if (mly_ccb_map(mly, mc) != 0) 1090 1.1 ad goto bad; 1091 1.1 ad mly_ccb_enqueue(mly, mc); 1092 1.1 ad return; 1093 1.1 ad 1094 1.1 ad bad: 1095 1.45 chs printf("%s: couldn't fetch event %u\n", device_xname(mly->mly_dv), event); 1096 1.1 ad free(mc->mc_data, M_DEVBUF); 1097 1.1 ad mly_ccb_free(mly, mc); 1098 1.1 ad } 1099 1.1 ad 1100 1.1 ad /* 1101 1.1 ad * Handle the completion of an event poll. 1102 1.1 ad */ 1103 1.1 ad static void 1104 1.1 ad mly_complete_event(struct mly_softc *mly, struct mly_ccb *mc) 1105 1.1 ad { 1106 1.1 ad struct mly_event *me; 1107 1.1 ad 1108 1.1 ad me = (struct mly_event *)mc->mc_data; 1109 1.1 ad mly_ccb_unmap(mly, mc); 1110 1.1 ad mly_ccb_free(mly, mc); 1111 1.1 ad 1112 1.1 ad /* If the event was successfully fetched, process it. */ 1113 1.1 ad if (mc->mc_status == SCSI_OK) 1114 1.1 ad mly_process_event(mly, me); 1115 1.1 ad else 1116 1.45 chs aprint_error_dev(mly->mly_dv, "unable to fetch event; status = 0x%x\n", 1117 1.37 cegger mc->mc_status); 1118 1.1 ad 1119 1.1 ad free(me, M_DEVBUF); 1120 1.1 ad 1121 1.1 ad /* Check for another event. */ 1122 1.1 ad mly_check_event(mly); 1123 1.1 ad } 1124 1.1 ad 1125 1.1 ad /* 1126 1.17 wiz * Process a controller event. Called with interrupts blocked (i.e., at 1127 1.1 ad * interrupt time). 1128 1.1 ad */ 1129 1.1 ad static void 1130 1.1 ad mly_process_event(struct mly_softc *mly, struct mly_event *me) 1131 1.1 ad { 1132 1.22 thorpej struct scsi_sense_data *ssd; 1133 1.1 ad int bus, target, event, class, action; 1134 1.1 ad const char *fp, *tp; 1135 1.1 ad 1136 1.22 thorpej ssd = (struct scsi_sense_data *)&me->sense[0]; 1137 1.1 ad 1138 1.23 perry /* 1139 1.1 ad * Errors can be reported using vendor-unique sense data. In this 1140 1.1 ad * case, the event code will be 0x1c (Request sense data present), 1141 1.1 ad * the sense key will be 0x09 (vendor specific), the MSB of the ASC 1142 1.1 ad * will be set, and the actual event code will be a 16-bit value 1143 1.1 ad * comprised of the ASCQ (low byte) and low seven bits of the ASC 1144 1.1 ad * (low seven bits of the high byte). 1145 1.1 ad */ 1146 1.1 ad if (le32toh(me->code) == 0x1c && 1147 1.22 thorpej SSD_SENSE_KEY(ssd->flags) == SKEY_VENDOR_SPECIFIC && 1148 1.22 thorpej (ssd->asc & 0x80) != 0) { 1149 1.22 thorpej event = ((int)(ssd->asc & ~0x80) << 8) + 1150 1.22 thorpej ssd->ascq; 1151 1.1 ad } else 1152 1.1 ad event = le32toh(me->code); 1153 1.1 ad 1154 1.1 ad /* Look up event, get codes. */ 1155 1.1 ad fp = mly_describe_code(mly_table_event, event); 1156 1.1 ad 1157 1.1 ad /* Quiet event? */ 1158 1.1 ad class = fp[0]; 1159 1.1 ad #ifdef notyet 1160 1.1 ad if (isupper(class) && bootverbose) 1161 1.1 ad class = tolower(class); 1162 1.1 ad #endif 1163 1.1 ad 1164 1.1 ad /* Get action code, text string. */ 1165 1.1 ad action = fp[1]; 1166 1.1 ad tp = fp + 3; 1167 1.1 ad 1168 1.1 ad /* 1169 1.1 ad * Print some information about the event. 1170 1.1 ad * 1171 1.1 ad * This code uses a table derived from the corresponding portion of 1172 1.1 ad * the Linux driver, and thus the parser is very similar. 1173 1.1 ad */ 1174 1.1 ad switch (class) { 1175 1.1 ad case 'p': 1176 1.1 ad /* 1177 1.1 ad * Error on physical drive. 1178 1.1 ad */ 1179 1.45 chs printf("%s: physical device %d:%d %s\n", device_xname(mly->mly_dv), 1180 1.1 ad me->channel, me->target, tp); 1181 1.1 ad if (action == 'r') 1182 1.1 ad mly->mly_btl[me->channel][me->target].mb_flags |= 1183 1.1 ad MLY_BTL_RESCAN; 1184 1.1 ad break; 1185 1.1 ad 1186 1.1 ad case 'l': 1187 1.1 ad case 'm': 1188 1.1 ad /* 1189 1.1 ad * Error on logical unit, or message about logical unit. 1190 1.1 ad */ 1191 1.1 ad bus = MLY_LOGDEV_BUS(mly, me->lun); 1192 1.1 ad target = MLY_LOGDEV_TARGET(mly, me->lun); 1193 1.45 chs printf("%s: logical device %d:%d %s\n", device_xname(mly->mly_dv), 1194 1.4 ad bus, target, tp); 1195 1.1 ad if (action == 'r') 1196 1.1 ad mly->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN; 1197 1.1 ad break; 1198 1.1 ad 1199 1.1 ad case 's': 1200 1.1 ad /* 1201 1.1 ad * Report of sense data. 1202 1.1 ad */ 1203 1.22 thorpej if ((SSD_SENSE_KEY(ssd->flags) == SKEY_NO_SENSE || 1204 1.23 perry SSD_SENSE_KEY(ssd->flags) == SKEY_NOT_READY) && 1205 1.23 perry ssd->asc == 0x04 && 1206 1.22 thorpej (ssd->ascq == 0x01 || 1207 1.22 thorpej ssd->ascq == 0x02)) { 1208 1.1 ad /* Ignore NO_SENSE or NOT_READY in one case */ 1209 1.1 ad break; 1210 1.1 ad } 1211 1.1 ad 1212 1.1 ad /* 1213 1.1 ad * XXX Should translate this if SCSIVERBOSE. 1214 1.1 ad */ 1215 1.45 chs printf("%s: physical device %d:%d %s\n", device_xname(mly->mly_dv), 1216 1.1 ad me->channel, me->target, tp); 1217 1.1 ad printf("%s: sense key %d asc %02x ascq %02x\n", 1218 1.45 chs device_xname(mly->mly_dv), SSD_SENSE_KEY(ssd->flags), 1219 1.22 thorpej ssd->asc, ssd->ascq); 1220 1.1 ad printf("%s: info %x%x%x%x csi %x%x%x%x\n", 1221 1.45 chs device_xname(mly->mly_dv), ssd->info[0], ssd->info[1], 1222 1.22 thorpej ssd->info[2], ssd->info[3], ssd->csi[0], 1223 1.22 thorpej ssd->csi[1], ssd->csi[2], 1224 1.22 thorpej ssd->csi[3]); 1225 1.1 ad if (action == 'r') 1226 1.1 ad mly->mly_btl[me->channel][me->target].mb_flags |= 1227 1.1 ad MLY_BTL_RESCAN; 1228 1.1 ad break; 1229 1.1 ad 1230 1.1 ad case 'e': 1231 1.45 chs printf("%s: ", device_xname(mly->mly_dv)); 1232 1.1 ad printf(tp, me->target, me->lun); 1233 1.1 ad break; 1234 1.1 ad 1235 1.1 ad case 'c': 1236 1.45 chs printf("%s: controller %s\n", device_xname(mly->mly_dv), tp); 1237 1.1 ad break; 1238 1.1 ad 1239 1.1 ad case '?': 1240 1.45 chs printf("%s: %s - %d\n", device_xname(mly->mly_dv), tp, event); 1241 1.1 ad break; 1242 1.1 ad 1243 1.1 ad default: 1244 1.1 ad /* Probably a 'noisy' event being ignored. */ 1245 1.1 ad break; 1246 1.1 ad } 1247 1.1 ad } 1248 1.1 ad 1249 1.1 ad /* 1250 1.1 ad * Perform periodic activities. 1251 1.1 ad */ 1252 1.1 ad static void 1253 1.1 ad mly_thread(void *cookie) 1254 1.1 ad { 1255 1.1 ad struct mly_softc *mly; 1256 1.1 ad struct mly_btl *btl; 1257 1.1 ad int s, bus, target, done; 1258 1.1 ad 1259 1.1 ad mly = (struct mly_softc *)cookie; 1260 1.1 ad 1261 1.1 ad for (;;) { 1262 1.1 ad /* Check for new events. */ 1263 1.1 ad mly_check_event(mly); 1264 1.1 ad 1265 1.1 ad /* Re-scan up to 1 device. */ 1266 1.1 ad s = splbio(); 1267 1.5 ad done = 0; 1268 1.1 ad for (bus = 0; bus < mly->mly_nchans && !done; bus++) { 1269 1.1 ad for (target = 0; target < MLY_MAX_TARGETS; target++) { 1270 1.1 ad /* Perform device rescan? */ 1271 1.1 ad btl = &mly->mly_btl[bus][target]; 1272 1.1 ad if ((btl->mb_flags & MLY_BTL_RESCAN) != 0) { 1273 1.1 ad btl->mb_flags ^= MLY_BTL_RESCAN; 1274 1.1 ad mly_scan_btl(mly, bus, target); 1275 1.1 ad done = 1; 1276 1.1 ad break; 1277 1.1 ad } 1278 1.1 ad } 1279 1.1 ad } 1280 1.1 ad splx(s); 1281 1.1 ad 1282 1.1 ad /* Sleep for N seconds. */ 1283 1.1 ad tsleep(mly_thread, PWAIT, "mlyzzz", 1284 1.1 ad hz * MLY_PERIODIC_INTERVAL); 1285 1.1 ad } 1286 1.1 ad } 1287 1.1 ad 1288 1.1 ad /* 1289 1.1 ad * Submit a command to the controller and poll on completion. Return 1290 1.1 ad * non-zero on timeout. 1291 1.1 ad */ 1292 1.1 ad static int 1293 1.1 ad mly_ccb_poll(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1294 1.1 ad { 1295 1.1 ad int rv; 1296 1.1 ad 1297 1.1 ad if ((rv = mly_ccb_submit(mly, mc)) != 0) 1298 1.1 ad return (rv); 1299 1.1 ad 1300 1.1 ad for (timo *= 10; timo != 0; timo--) { 1301 1.1 ad if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) 1302 1.1 ad break; 1303 1.1 ad mly_intr(mly); 1304 1.1 ad DELAY(100); 1305 1.1 ad } 1306 1.1 ad 1307 1.1 ad return (timo == 0); 1308 1.1 ad } 1309 1.1 ad 1310 1.1 ad /* 1311 1.1 ad * Submit a command to the controller and sleep on completion. Return 1312 1.1 ad * non-zero on timeout. 1313 1.1 ad */ 1314 1.1 ad static int 1315 1.1 ad mly_ccb_wait(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1316 1.1 ad { 1317 1.1 ad int rv, s; 1318 1.1 ad 1319 1.1 ad mly_ccb_enqueue(mly, mc); 1320 1.1 ad 1321 1.1 ad s = splbio(); 1322 1.1 ad if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) { 1323 1.1 ad splx(s); 1324 1.1 ad return (0); 1325 1.1 ad } 1326 1.1 ad rv = tsleep(mc, PRIBIO, "mlywccb", timo * hz / 1000); 1327 1.1 ad splx(s); 1328 1.1 ad 1329 1.1 ad return (rv); 1330 1.1 ad } 1331 1.1 ad 1332 1.1 ad /* 1333 1.1 ad * If a CCB is specified, enqueue it. Pull CCBs off the software queue in 1334 1.1 ad * the order that they were enqueued and try to submit their command blocks 1335 1.1 ad * to the controller for execution. 1336 1.1 ad */ 1337 1.1 ad void 1338 1.1 ad mly_ccb_enqueue(struct mly_softc *mly, struct mly_ccb *mc) 1339 1.1 ad { 1340 1.1 ad int s; 1341 1.1 ad 1342 1.1 ad s = splbio(); 1343 1.1 ad 1344 1.1 ad if (mc != NULL) 1345 1.1 ad SIMPLEQ_INSERT_TAIL(&mly->mly_ccb_queue, mc, mc_link.simpleq); 1346 1.1 ad 1347 1.1 ad while ((mc = SIMPLEQ_FIRST(&mly->mly_ccb_queue)) != NULL) { 1348 1.1 ad if (mly_ccb_submit(mly, mc)) 1349 1.1 ad break; 1350 1.10 lukem SIMPLEQ_REMOVE_HEAD(&mly->mly_ccb_queue, mc_link.simpleq); 1351 1.1 ad } 1352 1.1 ad 1353 1.1 ad splx(s); 1354 1.1 ad } 1355 1.1 ad 1356 1.1 ad /* 1357 1.1 ad * Deliver a command to the controller. 1358 1.1 ad */ 1359 1.1 ad static int 1360 1.1 ad mly_ccb_submit(struct mly_softc *mly, struct mly_ccb *mc) 1361 1.1 ad { 1362 1.1 ad union mly_cmd_packet *pkt; 1363 1.1 ad int s, off; 1364 1.1 ad 1365 1.1 ad mc->mc_packet->generic.command_id = htole16(mc->mc_slot); 1366 1.1 ad 1367 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1368 1.1 ad mc->mc_packetphys - mly->mly_pkt_busaddr, 1369 1.1 ad sizeof(union mly_cmd_packet), 1370 1.1 ad BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1371 1.1 ad 1372 1.1 ad s = splbio(); 1373 1.1 ad 1374 1.1 ad /* 1375 1.1 ad * Do we have to use the hardware mailbox? 1376 1.1 ad */ 1377 1.1 ad if ((mly->mly_state & MLY_STATE_MMBOX_ACTIVE) == 0) { 1378 1.1 ad /* 1379 1.1 ad * Check to see if the controller is ready for us. 1380 1.1 ad */ 1381 1.1 ad if (mly_idbr_true(mly, MLY_HM_CMDSENT)) { 1382 1.1 ad splx(s); 1383 1.1 ad return (EBUSY); 1384 1.1 ad } 1385 1.1 ad 1386 1.1 ad /* 1387 1.1 ad * It's ready, send the command. 1388 1.1 ad */ 1389 1.1 ad mly_outl(mly, mly->mly_cmd_mailbox, 1390 1.1 ad (u_int64_t)mc->mc_packetphys & 0xffffffff); 1391 1.1 ad mly_outl(mly, mly->mly_cmd_mailbox + 4, 1392 1.1 ad (u_int64_t)mc->mc_packetphys >> 32); 1393 1.1 ad mly_outb(mly, mly->mly_idbr, MLY_HM_CMDSENT); 1394 1.1 ad } else { 1395 1.1 ad pkt = &mly->mly_mmbox->mmm_command[mly->mly_mmbox_cmd_idx]; 1396 1.34 christos off = (char *)pkt - (char *)mly->mly_mmbox; 1397 1.1 ad 1398 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1399 1.1 ad off, sizeof(mly->mly_mmbox->mmm_command[0]), 1400 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1401 1.1 ad 1402 1.1 ad /* Check to see if the next index is free yet. */ 1403 1.1 ad if (pkt->mmbox.flag != 0) { 1404 1.1 ad splx(s); 1405 1.1 ad return (EBUSY); 1406 1.1 ad } 1407 1.1 ad 1408 1.1 ad /* Copy in new command */ 1409 1.1 ad memcpy(pkt->mmbox.data, mc->mc_packet->mmbox.data, 1410 1.1 ad sizeof(pkt->mmbox.data)); 1411 1.1 ad 1412 1.1 ad /* Copy flag last. */ 1413 1.1 ad pkt->mmbox.flag = mc->mc_packet->mmbox.flag; 1414 1.1 ad 1415 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1416 1.1 ad off, sizeof(mly->mly_mmbox->mmm_command[0]), 1417 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1418 1.1 ad 1419 1.1 ad /* Signal controller and update index. */ 1420 1.1 ad mly_outb(mly, mly->mly_idbr, MLY_AM_CMDSENT); 1421 1.1 ad mly->mly_mmbox_cmd_idx = 1422 1.1 ad (mly->mly_mmbox_cmd_idx + 1) % MLY_MMBOX_COMMANDS; 1423 1.1 ad } 1424 1.1 ad 1425 1.1 ad splx(s); 1426 1.1 ad return (0); 1427 1.1 ad } 1428 1.1 ad 1429 1.1 ad /* 1430 1.1 ad * Pick up completed commands from the controller and handle accordingly. 1431 1.1 ad */ 1432 1.1 ad int 1433 1.1 ad mly_intr(void *cookie) 1434 1.1 ad { 1435 1.1 ad struct mly_ccb *mc; 1436 1.1 ad union mly_status_packet *sp; 1437 1.1 ad u_int16_t slot; 1438 1.1 ad int forus, off; 1439 1.1 ad struct mly_softc *mly; 1440 1.1 ad 1441 1.1 ad mly = cookie; 1442 1.1 ad forus = 0; 1443 1.1 ad 1444 1.1 ad /* 1445 1.1 ad * Pick up hardware-mailbox commands. 1446 1.1 ad */ 1447 1.1 ad if (mly_odbr_true(mly, MLY_HM_STSREADY)) { 1448 1.1 ad slot = mly_inw(mly, mly->mly_status_mailbox); 1449 1.1 ad 1450 1.1 ad if (slot < MLY_SLOT_MAX) { 1451 1.1 ad mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1452 1.1 ad mc->mc_status = 1453 1.1 ad mly_inb(mly, mly->mly_status_mailbox + 2); 1454 1.1 ad mc->mc_sense = 1455 1.1 ad mly_inb(mly, mly->mly_status_mailbox + 3); 1456 1.1 ad mc->mc_resid = 1457 1.1 ad mly_inl(mly, mly->mly_status_mailbox + 4); 1458 1.1 ad 1459 1.1 ad mly_ccb_complete(mly, mc); 1460 1.1 ad } else { 1461 1.1 ad /* Slot 0xffff may mean "extremely bogus command". */ 1462 1.1 ad printf("%s: got HM completion for illegal slot %u\n", 1463 1.45 chs device_xname(mly->mly_dv), slot); 1464 1.1 ad } 1465 1.1 ad 1466 1.1 ad /* Unconditionally acknowledge status. */ 1467 1.1 ad mly_outb(mly, mly->mly_odbr, MLY_HM_STSREADY); 1468 1.1 ad mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 1469 1.1 ad forus = 1; 1470 1.1 ad } 1471 1.1 ad 1472 1.1 ad /* 1473 1.1 ad * Pick up memory-mailbox commands. 1474 1.1 ad */ 1475 1.1 ad if (mly_odbr_true(mly, MLY_AM_STSREADY)) { 1476 1.1 ad for (;;) { 1477 1.1 ad sp = &mly->mly_mmbox->mmm_status[mly->mly_mmbox_sts_idx]; 1478 1.34 christos off = (char *)sp - (char *)mly->mly_mmbox; 1479 1.1 ad 1480 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1481 1.1 ad off, sizeof(mly->mly_mmbox->mmm_command[0]), 1482 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1483 1.1 ad 1484 1.1 ad /* Check for more status. */ 1485 1.1 ad if (sp->mmbox.flag == 0) 1486 1.1 ad break; 1487 1.1 ad 1488 1.1 ad /* Get slot number. */ 1489 1.1 ad slot = le16toh(sp->status.command_id); 1490 1.1 ad if (slot < MLY_SLOT_MAX) { 1491 1.1 ad mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1492 1.1 ad mc->mc_status = sp->status.status; 1493 1.1 ad mc->mc_sense = sp->status.sense_length; 1494 1.1 ad mc->mc_resid = le32toh(sp->status.residue); 1495 1.1 ad mly_ccb_complete(mly, mc); 1496 1.1 ad } else { 1497 1.1 ad /* 1498 1.1 ad * Slot 0xffff may mean "extremely bogus 1499 1.1 ad * command". 1500 1.1 ad */ 1501 1.1 ad printf("%s: got AM completion for illegal " 1502 1.45 chs "slot %u at %d\n", device_xname(mly->mly_dv), 1503 1.1 ad slot, mly->mly_mmbox_sts_idx); 1504 1.1 ad } 1505 1.1 ad 1506 1.1 ad /* Clear and move to next index. */ 1507 1.1 ad sp->mmbox.flag = 0; 1508 1.1 ad mly->mly_mmbox_sts_idx = 1509 1.1 ad (mly->mly_mmbox_sts_idx + 1) % MLY_MMBOX_STATUS; 1510 1.1 ad } 1511 1.1 ad 1512 1.1 ad /* Acknowledge that we have collected status value(s). */ 1513 1.1 ad mly_outb(mly, mly->mly_odbr, MLY_AM_STSREADY); 1514 1.1 ad forus = 1; 1515 1.1 ad } 1516 1.1 ad 1517 1.1 ad /* 1518 1.1 ad * Run the queue. 1519 1.1 ad */ 1520 1.10 lukem if (forus && ! SIMPLEQ_EMPTY(&mly->mly_ccb_queue)) 1521 1.1 ad mly_ccb_enqueue(mly, NULL); 1522 1.1 ad 1523 1.1 ad return (forus); 1524 1.1 ad } 1525 1.1 ad 1526 1.1 ad /* 1527 1.1 ad * Process completed commands 1528 1.1 ad */ 1529 1.1 ad static void 1530 1.1 ad mly_ccb_complete(struct mly_softc *mly, struct mly_ccb *mc) 1531 1.1 ad { 1532 1.1 ad void (*complete)(struct mly_softc *, struct mly_ccb *); 1533 1.1 ad 1534 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1535 1.1 ad mc->mc_packetphys - mly->mly_pkt_busaddr, 1536 1.1 ad sizeof(union mly_cmd_packet), 1537 1.1 ad BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1538 1.1 ad 1539 1.1 ad complete = mc->mc_complete; 1540 1.1 ad mc->mc_flags |= MLY_CCB_COMPLETE; 1541 1.1 ad 1542 1.23 perry /* 1543 1.1 ad * Call completion handler or wake up sleeping consumer. 1544 1.1 ad */ 1545 1.1 ad if (complete != NULL) 1546 1.1 ad (*complete)(mly, mc); 1547 1.1 ad else 1548 1.1 ad wakeup(mc); 1549 1.1 ad } 1550 1.1 ad 1551 1.1 ad /* 1552 1.1 ad * Allocate a command. 1553 1.1 ad */ 1554 1.1 ad int 1555 1.1 ad mly_ccb_alloc(struct mly_softc *mly, struct mly_ccb **mcp) 1556 1.1 ad { 1557 1.1 ad struct mly_ccb *mc; 1558 1.1 ad int s; 1559 1.1 ad 1560 1.1 ad s = splbio(); 1561 1.1 ad mc = SLIST_FIRST(&mly->mly_ccb_free); 1562 1.1 ad if (mc != NULL) 1563 1.1 ad SLIST_REMOVE_HEAD(&mly->mly_ccb_free, mc_link.slist); 1564 1.1 ad splx(s); 1565 1.1 ad 1566 1.1 ad *mcp = mc; 1567 1.1 ad return (mc == NULL ? EAGAIN : 0); 1568 1.1 ad } 1569 1.1 ad 1570 1.1 ad /* 1571 1.1 ad * Release a command back to the freelist. 1572 1.1 ad */ 1573 1.1 ad void 1574 1.1 ad mly_ccb_free(struct mly_softc *mly, struct mly_ccb *mc) 1575 1.1 ad { 1576 1.1 ad int s; 1577 1.1 ad 1578 1.1 ad /* 1579 1.1 ad * Fill in parts of the command that may cause confusion if a 1580 1.1 ad * consumer doesn't when we are later allocated. 1581 1.1 ad */ 1582 1.1 ad mc->mc_data = NULL; 1583 1.1 ad mc->mc_flags = 0; 1584 1.1 ad mc->mc_complete = NULL; 1585 1.1 ad mc->mc_private = NULL; 1586 1.3 ad mc->mc_packet->generic.command_control = 0; 1587 1.1 ad 1588 1.1 ad /* 1589 1.1 ad * By default, we set up to overwrite the command packet with sense 1590 1.1 ad * information. 1591 1.1 ad */ 1592 1.1 ad mc->mc_packet->generic.sense_buffer_address = 1593 1.1 ad htole64(mc->mc_packetphys); 1594 1.1 ad mc->mc_packet->generic.maximum_sense_size = 1595 1.1 ad sizeof(union mly_cmd_packet); 1596 1.1 ad 1597 1.1 ad s = splbio(); 1598 1.1 ad SLIST_INSERT_HEAD(&mly->mly_ccb_free, mc, mc_link.slist); 1599 1.1 ad splx(s); 1600 1.1 ad } 1601 1.1 ad 1602 1.1 ad /* 1603 1.18 perry * Allocate and initialize command and packet structures. 1604 1.1 ad * 1605 1.1 ad * If the controller supports fewer than MLY_MAX_CCBS commands, limit our 1606 1.1 ad * allocation to that number. If we don't yet know how many commands the 1607 1.18 perry * controller supports, allocate a very small set (suitable for initialization 1608 1.1 ad * purposes only). 1609 1.1 ad */ 1610 1.1 ad static int 1611 1.1 ad mly_alloc_ccbs(struct mly_softc *mly) 1612 1.1 ad { 1613 1.1 ad struct mly_ccb *mc; 1614 1.1 ad int i, rv; 1615 1.1 ad 1616 1.1 ad if (mly->mly_controllerinfo == NULL) 1617 1.1 ad mly->mly_ncmds = MLY_CCBS_RESV; 1618 1.1 ad else { 1619 1.1 ad i = le16toh(mly->mly_controllerinfo->maximum_parallel_commands); 1620 1.51 riastrad mly->mly_ncmds = uimin(MLY_MAX_CCBS, i); 1621 1.1 ad } 1622 1.1 ad 1623 1.1 ad /* 1624 1.1 ad * Allocate enough space for all the command packets in one chunk 1625 1.1 ad * and map them permanently into controller-visible space. 1626 1.1 ad */ 1627 1.1 ad rv = mly_dmamem_alloc(mly, 1628 1.1 ad mly->mly_ncmds * sizeof(union mly_cmd_packet), 1629 1.34 christos &mly->mly_pkt_dmamap, (void **)&mly->mly_pkt, 1630 1.1 ad &mly->mly_pkt_busaddr, &mly->mly_pkt_seg); 1631 1.1 ad if (rv) 1632 1.1 ad return (rv); 1633 1.1 ad 1634 1.1 ad mly->mly_ccbs = malloc(sizeof(struct mly_ccb) * mly->mly_ncmds, 1635 1.53 chs M_DEVBUF, M_WAITOK|M_ZERO); 1636 1.1 ad 1637 1.1 ad for (i = 0; i < mly->mly_ncmds; i++) { 1638 1.1 ad mc = mly->mly_ccbs + i; 1639 1.1 ad mc->mc_slot = MLY_SLOT_START + i; 1640 1.1 ad mc->mc_packet = mly->mly_pkt + i; 1641 1.1 ad mc->mc_packetphys = mly->mly_pkt_busaddr + 1642 1.1 ad (i * sizeof(union mly_cmd_packet)); 1643 1.1 ad 1644 1.1 ad rv = bus_dmamap_create(mly->mly_dmat, MLY_MAX_XFER, 1645 1.1 ad MLY_MAX_SEGS, MLY_MAX_XFER, 0, 1646 1.1 ad BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 1647 1.1 ad &mc->mc_datamap); 1648 1.1 ad if (rv) { 1649 1.1 ad mly_release_ccbs(mly); 1650 1.1 ad return (rv); 1651 1.1 ad } 1652 1.1 ad 1653 1.1 ad mly_ccb_free(mly, mc); 1654 1.1 ad } 1655 1.1 ad 1656 1.1 ad return (0); 1657 1.1 ad } 1658 1.1 ad 1659 1.1 ad /* 1660 1.1 ad * Free all the storage held by commands. 1661 1.1 ad * 1662 1.1 ad * Must be called with all commands on the free list. 1663 1.1 ad */ 1664 1.1 ad static void 1665 1.1 ad mly_release_ccbs(struct mly_softc *mly) 1666 1.1 ad { 1667 1.1 ad struct mly_ccb *mc; 1668 1.1 ad 1669 1.1 ad /* Throw away command buffer DMA maps. */ 1670 1.1 ad while (mly_ccb_alloc(mly, &mc) == 0) 1671 1.1 ad bus_dmamap_destroy(mly->mly_dmat, mc->mc_datamap); 1672 1.1 ad 1673 1.1 ad /* Release CCB storage. */ 1674 1.1 ad free(mly->mly_ccbs, M_DEVBUF); 1675 1.1 ad 1676 1.1 ad /* Release the packet storage. */ 1677 1.1 ad mly_dmamem_free(mly, mly->mly_ncmds * sizeof(union mly_cmd_packet), 1678 1.34 christos mly->mly_pkt_dmamap, (void *)mly->mly_pkt, &mly->mly_pkt_seg); 1679 1.1 ad } 1680 1.1 ad 1681 1.1 ad /* 1682 1.1 ad * Map a command into controller-visible space. 1683 1.1 ad */ 1684 1.1 ad static int 1685 1.1 ad mly_ccb_map(struct mly_softc *mly, struct mly_ccb *mc) 1686 1.1 ad { 1687 1.1 ad struct mly_cmd_generic *gen; 1688 1.1 ad struct mly_sg_entry *sg; 1689 1.1 ad bus_dma_segment_t *ds; 1690 1.1 ad int flg, nseg, rv; 1691 1.1 ad 1692 1.1 ad #ifdef DIAGNOSTIC 1693 1.1 ad /* Don't map more than once. */ 1694 1.1 ad if ((mc->mc_flags & MLY_CCB_MAPPED) != 0) 1695 1.1 ad panic("mly_ccb_map: already mapped"); 1696 1.1 ad mc->mc_flags |= MLY_CCB_MAPPED; 1697 1.1 ad 1698 1.1 ad /* Does the command have a data buffer? */ 1699 1.1 ad if (mc->mc_data == NULL) 1700 1.1 ad panic("mly_ccb_map: no data buffer"); 1701 1.1 ad #endif 1702 1.1 ad 1703 1.1 ad rv = bus_dmamap_load(mly->mly_dmat, mc->mc_datamap, mc->mc_data, 1704 1.1 ad mc->mc_length, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1705 1.1 ad ((mc->mc_flags & MLY_CCB_DATAIN) != 0 ? 1706 1.1 ad BUS_DMA_READ : BUS_DMA_WRITE)); 1707 1.1 ad if (rv != 0) 1708 1.1 ad return (rv); 1709 1.1 ad 1710 1.1 ad gen = &mc->mc_packet->generic; 1711 1.1 ad 1712 1.1 ad /* 1713 1.1 ad * Can we use the transfer structure directly? 1714 1.1 ad */ 1715 1.1 ad if ((nseg = mc->mc_datamap->dm_nsegs) <= 2) { 1716 1.1 ad mc->mc_sgoff = -1; 1717 1.1 ad sg = &gen->transfer.direct.sg[0]; 1718 1.1 ad } else { 1719 1.1 ad mc->mc_sgoff = (mc->mc_slot - MLY_SLOT_START) * 1720 1.1 ad MLY_MAX_SEGS; 1721 1.1 ad sg = mly->mly_sg + mc->mc_sgoff; 1722 1.1 ad gen->command_control |= MLY_CMDCTL_EXTENDED_SG_TABLE; 1723 1.1 ad gen->transfer.indirect.entries[0] = htole16(nseg); 1724 1.1 ad gen->transfer.indirect.table_physaddr[0] = 1725 1.1 ad htole64(mly->mly_sg_busaddr + 1726 1.1 ad (mc->mc_sgoff * sizeof(struct mly_sg_entry))); 1727 1.1 ad } 1728 1.1 ad 1729 1.1 ad /* 1730 1.1 ad * Fill the S/G table. 1731 1.1 ad */ 1732 1.1 ad for (ds = mc->mc_datamap->dm_segs; nseg != 0; nseg--, sg++, ds++) { 1733 1.1 ad sg->physaddr = htole64(ds->ds_addr); 1734 1.1 ad sg->length = htole64(ds->ds_len); 1735 1.1 ad } 1736 1.1 ad 1737 1.1 ad /* 1738 1.1 ad * Sync up the data map. 1739 1.1 ad */ 1740 1.1 ad if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1741 1.1 ad flg = BUS_DMASYNC_PREREAD; 1742 1.1 ad else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ { 1743 1.1 ad gen->command_control |= MLY_CMDCTL_DATA_DIRECTION; 1744 1.1 ad flg = BUS_DMASYNC_PREWRITE; 1745 1.1 ad } 1746 1.1 ad 1747 1.1 ad bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1748 1.1 ad 1749 1.1 ad /* 1750 1.1 ad * Sync up the chained S/G table, if we're using one. 1751 1.1 ad */ 1752 1.1 ad if (mc->mc_sgoff == -1) 1753 1.1 ad return (0); 1754 1.1 ad 1755 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1756 1.1 ad MLY_SGL_SIZE, BUS_DMASYNC_PREWRITE); 1757 1.1 ad 1758 1.1 ad return (0); 1759 1.1 ad } 1760 1.1 ad 1761 1.1 ad /* 1762 1.1 ad * Unmap a command from controller-visible space. 1763 1.1 ad */ 1764 1.1 ad static void 1765 1.1 ad mly_ccb_unmap(struct mly_softc *mly, struct mly_ccb *mc) 1766 1.1 ad { 1767 1.1 ad int flg; 1768 1.1 ad 1769 1.1 ad #ifdef DIAGNOSTIC 1770 1.1 ad if ((mc->mc_flags & MLY_CCB_MAPPED) == 0) 1771 1.1 ad panic("mly_ccb_unmap: not mapped"); 1772 1.1 ad mc->mc_flags &= ~MLY_CCB_MAPPED; 1773 1.1 ad #endif 1774 1.1 ad 1775 1.1 ad if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1776 1.1 ad flg = BUS_DMASYNC_POSTREAD; 1777 1.1 ad else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ 1778 1.1 ad flg = BUS_DMASYNC_POSTWRITE; 1779 1.1 ad 1780 1.1 ad bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1781 1.1 ad bus_dmamap_unload(mly->mly_dmat, mc->mc_datamap); 1782 1.1 ad 1783 1.1 ad if (mc->mc_sgoff == -1) 1784 1.1 ad return; 1785 1.1 ad 1786 1.1 ad bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1787 1.1 ad MLY_SGL_SIZE, BUS_DMASYNC_POSTWRITE); 1788 1.1 ad } 1789 1.1 ad 1790 1.1 ad /* 1791 1.1 ad * Adjust the size of each I/O before it passes to the SCSI layer. 1792 1.1 ad */ 1793 1.1 ad static void 1794 1.1 ad mly_scsipi_minphys(struct buf *bp) 1795 1.1 ad { 1796 1.1 ad 1797 1.1 ad if (bp->b_bcount > MLY_MAX_XFER) 1798 1.1 ad bp->b_bcount = MLY_MAX_XFER; 1799 1.1 ad minphys(bp); 1800 1.1 ad } 1801 1.1 ad 1802 1.1 ad /* 1803 1.1 ad * Start a SCSI command. 1804 1.1 ad */ 1805 1.1 ad static void 1806 1.1 ad mly_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1807 1.1 ad void *arg) 1808 1.1 ad { 1809 1.1 ad struct mly_ccb *mc; 1810 1.1 ad struct mly_cmd_scsi_small *ss; 1811 1.1 ad struct scsipi_xfer *xs; 1812 1.1 ad struct scsipi_periph *periph; 1813 1.1 ad struct mly_softc *mly; 1814 1.1 ad struct mly_btl *btl; 1815 1.1 ad int s, tmp; 1816 1.1 ad 1817 1.42 cegger mly = device_private(chan->chan_adapter->adapt_dev); 1818 1.1 ad 1819 1.1 ad switch (req) { 1820 1.1 ad case ADAPTER_REQ_RUN_XFER: 1821 1.1 ad xs = arg; 1822 1.1 ad periph = xs->xs_periph; 1823 1.1 ad btl = &mly->mly_btl[chan->chan_channel][periph->periph_target]; 1824 1.1 ad s = splbio(); 1825 1.1 ad tmp = btl->mb_flags; 1826 1.1 ad splx(s); 1827 1.1 ad 1828 1.1 ad /* 1829 1.56 andvar * Check for I/O attempt to a protected or non-existent 1830 1.1 ad * device. 1831 1.1 ad */ 1832 1.1 ad if ((tmp & MLY_BTL_PROTECTED) != 0) { 1833 1.1 ad xs->error = XS_SELTIMEOUT; 1834 1.1 ad scsipi_done(xs); 1835 1.1 ad break; 1836 1.1 ad } 1837 1.1 ad 1838 1.1 ad #ifdef DIAGNOSTIC 1839 1.1 ad /* XXX Increase if/when we support large SCSI commands. */ 1840 1.1 ad if (xs->cmdlen > MLY_CMD_SCSI_SMALL_CDB) { 1841 1.45 chs printf("%s: cmd too large\n", device_xname(mly->mly_dv)); 1842 1.1 ad xs->error = XS_DRIVER_STUFFUP; 1843 1.1 ad scsipi_done(xs); 1844 1.1 ad break; 1845 1.1 ad } 1846 1.1 ad #endif 1847 1.1 ad 1848 1.1 ad if (mly_ccb_alloc(mly, &mc)) { 1849 1.1 ad xs->error = XS_RESOURCE_SHORTAGE; 1850 1.1 ad scsipi_done(xs); 1851 1.1 ad break; 1852 1.1 ad } 1853 1.1 ad 1854 1.1 ad /* Build the command. */ 1855 1.1 ad mc->mc_data = xs->data; 1856 1.1 ad mc->mc_length = xs->datalen; 1857 1.1 ad mc->mc_complete = mly_scsipi_complete; 1858 1.1 ad mc->mc_private = xs; 1859 1.1 ad 1860 1.1 ad /* Build the packet for the controller. */ 1861 1.1 ad ss = &mc->mc_packet->scsi_small; 1862 1.1 ad ss->opcode = MDACMD_SCSI; 1863 1.1 ad #ifdef notdef 1864 1.1 ad /* 1865 1.1 ad * XXX FreeBSD does this, but it doesn't fix anything, 1866 1.1 ad * XXX and appears potentially harmful. 1867 1.1 ad */ 1868 1.1 ad ss->command_control |= MLY_CMDCTL_DISABLE_DISCONNECT; 1869 1.1 ad #endif 1870 1.3 ad 1871 1.1 ad ss->data_size = htole32(xs->datalen); 1872 1.1 ad _lto3l(MLY_PHYADDR(0, chan->chan_channel, 1873 1.1 ad periph->periph_target, periph->periph_lun), ss->addr); 1874 1.1 ad 1875 1.1 ad if (xs->timeout < 60 * 1000) 1876 1.1 ad ss->timeout = xs->timeout / 1000 | 1877 1.1 ad MLY_TIMEOUT_SECONDS; 1878 1.1 ad else if (xs->timeout < 60 * 60 * 1000) 1879 1.1 ad ss->timeout = xs->timeout / (60 * 1000) | 1880 1.1 ad MLY_TIMEOUT_MINUTES; 1881 1.1 ad else 1882 1.1 ad ss->timeout = xs->timeout / (60 * 60 * 1000) | 1883 1.1 ad MLY_TIMEOUT_HOURS; 1884 1.1 ad 1885 1.1 ad ss->maximum_sense_size = sizeof(xs->sense); 1886 1.1 ad ss->cdb_length = xs->cmdlen; 1887 1.1 ad memcpy(ss->cdb, xs->cmd, xs->cmdlen); 1888 1.1 ad 1889 1.7 ad if (mc->mc_length != 0) { 1890 1.7 ad if ((xs->xs_control & XS_CTL_DATA_OUT) != 0) 1891 1.7 ad mc->mc_flags |= MLY_CCB_DATAOUT; 1892 1.7 ad else /* if ((xs->xs_control & XS_CTL_DATA_IN) != 0) */ 1893 1.7 ad mc->mc_flags |= MLY_CCB_DATAIN; 1894 1.7 ad 1895 1.1 ad if (mly_ccb_map(mly, mc) != 0) { 1896 1.1 ad xs->error = XS_DRIVER_STUFFUP; 1897 1.1 ad mly_ccb_free(mly, mc); 1898 1.1 ad scsipi_done(xs); 1899 1.1 ad break; 1900 1.1 ad } 1901 1.7 ad } 1902 1.1 ad 1903 1.1 ad /* 1904 1.1 ad * Give the command to the controller. 1905 1.1 ad */ 1906 1.1 ad if ((xs->xs_control & XS_CTL_POLL) != 0) { 1907 1.1 ad if (mly_ccb_poll(mly, mc, xs->timeout + 5000)) { 1908 1.1 ad xs->error = XS_REQUEUE; 1909 1.1 ad if (mc->mc_length != 0) 1910 1.1 ad mly_ccb_unmap(mly, mc); 1911 1.1 ad mly_ccb_free(mly, mc); 1912 1.1 ad scsipi_done(xs); 1913 1.1 ad } 1914 1.1 ad } else 1915 1.1 ad mly_ccb_enqueue(mly, mc); 1916 1.1 ad 1917 1.1 ad break; 1918 1.1 ad 1919 1.1 ad case ADAPTER_REQ_GROW_RESOURCES: 1920 1.1 ad /* 1921 1.1 ad * Not supported. 1922 1.1 ad */ 1923 1.1 ad break; 1924 1.1 ad 1925 1.1 ad case ADAPTER_REQ_SET_XFER_MODE: 1926 1.1 ad /* 1927 1.1 ad * We can't change the transfer mode, but at least let 1928 1.1 ad * scsipi know what the adapter has negotiated. 1929 1.1 ad */ 1930 1.1 ad mly_get_xfer_mode(mly, chan->chan_channel, arg); 1931 1.1 ad break; 1932 1.1 ad } 1933 1.1 ad } 1934 1.1 ad 1935 1.1 ad /* 1936 1.1 ad * Handle completion of a SCSI command. 1937 1.1 ad */ 1938 1.1 ad static void 1939 1.1 ad mly_scsipi_complete(struct mly_softc *mly, struct mly_ccb *mc) 1940 1.1 ad { 1941 1.1 ad struct scsipi_xfer *xs; 1942 1.1 ad struct scsipi_channel *chan; 1943 1.1 ad struct scsipi_inquiry_data *inq; 1944 1.1 ad struct mly_btl *btl; 1945 1.1 ad int target, sl, s; 1946 1.1 ad const char *p; 1947 1.1 ad 1948 1.1 ad xs = mc->mc_private; 1949 1.1 ad xs->status = mc->mc_status; 1950 1.1 ad 1951 1.1 ad /* 1952 1.1 ad * XXX The `resid' value as returned by the controller appears to be 1953 1.1 ad * bogus, so we always set it to zero. Is it perhaps the transfer 1954 1.1 ad * count? 1955 1.1 ad */ 1956 1.1 ad xs->resid = 0; /* mc->mc_resid; */ 1957 1.1 ad 1958 1.1 ad if (mc->mc_length != 0) 1959 1.1 ad mly_ccb_unmap(mly, mc); 1960 1.1 ad 1961 1.1 ad switch (mc->mc_status) { 1962 1.1 ad case SCSI_OK: 1963 1.1 ad /* 1964 1.1 ad * In order to report logical device type and status, we 1965 1.1 ad * overwrite the result of the INQUIRY command to logical 1966 1.1 ad * devices. 1967 1.1 ad */ 1968 1.1 ad if (xs->cmd->opcode == INQUIRY) { 1969 1.1 ad chan = xs->xs_periph->periph_channel; 1970 1.1 ad target = xs->xs_periph->periph_target; 1971 1.1 ad btl = &mly->mly_btl[chan->chan_channel][target]; 1972 1.1 ad 1973 1.1 ad s = splbio(); 1974 1.1 ad if ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) { 1975 1.1 ad inq = (struct scsipi_inquiry_data *)xs->data; 1976 1.1 ad mly_padstr(inq->vendor, "MYLEX", 8); 1977 1.1 ad p = mly_describe_code(mly_table_device_type, 1978 1.1 ad btl->mb_type); 1979 1.1 ad mly_padstr(inq->product, p, 16); 1980 1.1 ad p = mly_describe_code(mly_table_device_state, 1981 1.1 ad btl->mb_state); 1982 1.1 ad mly_padstr(inq->revision, p, 4); 1983 1.1 ad } 1984 1.1 ad splx(s); 1985 1.1 ad } 1986 1.1 ad 1987 1.1 ad xs->error = XS_NOERROR; 1988 1.1 ad break; 1989 1.1 ad 1990 1.1 ad case SCSI_CHECK: 1991 1.1 ad sl = mc->mc_sense; 1992 1.1 ad if (sl > sizeof(xs->sense.scsi_sense)) 1993 1.1 ad sl = sizeof(xs->sense.scsi_sense); 1994 1.1 ad memcpy(&xs->sense.scsi_sense, mc->mc_packet, sl); 1995 1.1 ad xs->error = XS_SENSE; 1996 1.1 ad break; 1997 1.1 ad 1998 1.1 ad case SCSI_BUSY: 1999 1.1 ad case SCSI_QUEUE_FULL: 2000 1.1 ad xs->error = XS_BUSY; 2001 1.1 ad break; 2002 1.1 ad 2003 1.1 ad default: 2004 1.1 ad printf("%s: unknown SCSI status 0x%x\n", 2005 1.45 chs device_xname(mly->mly_dv), xs->status); 2006 1.1 ad xs->error = XS_DRIVER_STUFFUP; 2007 1.1 ad break; 2008 1.1 ad } 2009 1.1 ad 2010 1.1 ad mly_ccb_free(mly, mc); 2011 1.1 ad scsipi_done(xs); 2012 1.1 ad } 2013 1.1 ad 2014 1.1 ad /* 2015 1.1 ad * Notify scsipi about a target's transfer mode. 2016 1.1 ad */ 2017 1.1 ad static void 2018 1.1 ad mly_get_xfer_mode(struct mly_softc *mly, int bus, struct scsipi_xfer_mode *xm) 2019 1.1 ad { 2020 1.1 ad struct mly_btl *btl; 2021 1.1 ad int s; 2022 1.1 ad 2023 1.1 ad btl = &mly->mly_btl[bus][xm->xm_target]; 2024 1.1 ad xm->xm_mode = 0; 2025 1.1 ad 2026 1.1 ad s = splbio(); 2027 1.1 ad 2028 1.23 perry if ((btl->mb_flags & MLY_BTL_PHYSICAL) != 0) { 2029 1.1 ad if (btl->mb_speed == 0) { 2030 1.1 ad xm->xm_period = 0; 2031 1.1 ad xm->xm_offset = 0; 2032 1.1 ad } else { 2033 1.1 ad xm->xm_period = 12; /* XXX */ 2034 1.1 ad xm->xm_offset = 8; /* XXX */ 2035 1.1 ad xm->xm_mode |= PERIPH_CAP_SYNC; /* XXX */ 2036 1.1 ad } 2037 1.1 ad 2038 1.1 ad switch (btl->mb_width) { 2039 1.1 ad case 32: 2040 1.1 ad xm->xm_mode = PERIPH_CAP_WIDE32; 2041 1.1 ad break; 2042 1.1 ad case 16: 2043 1.1 ad xm->xm_mode = PERIPH_CAP_WIDE16; 2044 1.1 ad break; 2045 1.1 ad default: 2046 1.1 ad xm->xm_mode = 0; 2047 1.1 ad break; 2048 1.1 ad } 2049 1.1 ad } else /* ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) */ { 2050 1.1 ad xm->xm_mode = PERIPH_CAP_WIDE16 | PERIPH_CAP_SYNC; 2051 1.1 ad xm->xm_period = 12; 2052 1.1 ad xm->xm_offset = 8; 2053 1.1 ad } 2054 1.1 ad 2055 1.1 ad if ((btl->mb_flags & MLY_BTL_TQING) != 0) 2056 1.1 ad xm->xm_mode |= PERIPH_CAP_TQING; 2057 1.1 ad 2058 1.1 ad splx(s); 2059 1.1 ad 2060 1.1 ad scsipi_async_event(&mly->mly_chans[bus], ASYNC_EVENT_XFER_MODE, xm); 2061 1.1 ad } 2062 1.1 ad 2063 1.1 ad /* 2064 1.1 ad * ioctl hook; used here only to initiate low-level rescans. 2065 1.1 ad */ 2066 1.1 ad static int 2067 1.34 christos mly_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, void *data, 2068 1.32 christos int flag, struct proc *p) 2069 1.1 ad { 2070 1.1 ad struct mly_softc *mly; 2071 1.1 ad int rv; 2072 1.23 perry 2073 1.42 cegger mly = device_private(chan->chan_adapter->adapt_dev); 2074 1.23 perry 2075 1.1 ad switch (cmd) { 2076 1.1 ad case SCBUSIOLLSCAN: 2077 1.1 ad mly_scan_channel(mly, chan->chan_channel); 2078 1.1 ad rv = 0; 2079 1.1 ad break; 2080 1.1 ad default: 2081 1.1 ad rv = ENOTTY; 2082 1.1 ad break; 2083 1.1 ad } 2084 1.1 ad 2085 1.1 ad return (rv); 2086 1.1 ad } 2087 1.1 ad 2088 1.1 ad /* 2089 1.18 perry * Handshake with the firmware while the card is being initialized. 2090 1.1 ad */ 2091 1.1 ad static int 2092 1.23 perry mly_fwhandshake(struct mly_softc *mly) 2093 1.1 ad { 2094 1.46 christos u_int8_t error; 2095 1.1 ad int spinup; 2096 1.1 ad 2097 1.1 ad spinup = 0; 2098 1.1 ad 2099 1.18 perry /* Set HM_STSACK and let the firmware initialize. */ 2100 1.1 ad mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 2101 1.1 ad DELAY(1000); /* too short? */ 2102 1.1 ad 2103 1.18 perry /* If HM_STSACK is still true, the controller is initializing. */ 2104 1.1 ad if (!mly_idbr_true(mly, MLY_HM_STSACK)) 2105 1.1 ad return (0); 2106 1.1 ad 2107 1.18 perry printf("%s: controller initialization started\n", 2108 1.45 chs device_xname(mly->mly_dv)); 2109 1.1 ad 2110 1.1 ad /* 2111 1.18 perry * Spin waiting for initialization to finish, or for a message to be 2112 1.1 ad * delivered. 2113 1.1 ad */ 2114 1.1 ad while (mly_idbr_true(mly, MLY_HM_STSACK)) { 2115 1.1 ad /* Check for a message */ 2116 1.1 ad if (!mly_error_valid(mly)) 2117 1.1 ad continue; 2118 1.1 ad 2119 1.1 ad error = mly_inb(mly, mly->mly_error_status) & ~MLY_MSG_EMPTY; 2120 1.46 christos (void)mly_inb(mly, mly->mly_cmd_mailbox); 2121 1.46 christos (void)mly_inb(mly, mly->mly_cmd_mailbox + 1); 2122 1.1 ad 2123 1.1 ad switch (error) { 2124 1.1 ad case MLY_MSG_SPINUP: 2125 1.1 ad if (!spinup) { 2126 1.1 ad printf("%s: drive spinup in progress\n", 2127 1.45 chs device_xname(mly->mly_dv)); 2128 1.1 ad spinup = 1; 2129 1.1 ad } 2130 1.1 ad break; 2131 1.1 ad 2132 1.1 ad case MLY_MSG_RACE_RECOVERY_FAIL: 2133 1.1 ad printf("%s: mirror race recovery failed - \n", 2134 1.45 chs device_xname(mly->mly_dv)); 2135 1.1 ad printf("%s: one or more drives offline\n", 2136 1.45 chs device_xname(mly->mly_dv)); 2137 1.1 ad break; 2138 1.1 ad 2139 1.1 ad case MLY_MSG_RACE_IN_PROGRESS: 2140 1.1 ad printf("%s: mirror race recovery in progress\n", 2141 1.45 chs device_xname(mly->mly_dv)); 2142 1.1 ad break; 2143 1.1 ad 2144 1.1 ad case MLY_MSG_RACE_ON_CRITICAL: 2145 1.1 ad printf("%s: mirror race recovery on critical drive\n", 2146 1.45 chs device_xname(mly->mly_dv)); 2147 1.1 ad break; 2148 1.1 ad 2149 1.1 ad case MLY_MSG_PARITY_ERROR: 2150 1.1 ad printf("%s: FATAL MEMORY PARITY ERROR\n", 2151 1.45 chs device_xname(mly->mly_dv)); 2152 1.1 ad return (ENXIO); 2153 1.1 ad 2154 1.1 ad default: 2155 1.18 perry printf("%s: unknown initialization code 0x%x\n", 2156 1.45 chs device_xname(mly->mly_dv), error); 2157 1.1 ad break; 2158 1.1 ad } 2159 1.1 ad } 2160 1.1 ad 2161 1.1 ad return (0); 2162 1.1 ad } 2163 1.1 ad 2164 1.1 ad /* 2165 1.1 ad * Space-fill a character string 2166 1.1 ad */ 2167 1.1 ad static void 2168 1.1 ad mly_padstr(char *dst, const char *src, int len) 2169 1.1 ad { 2170 1.1 ad 2171 1.1 ad while (len-- > 0) { 2172 1.1 ad if (*src != '\0') 2173 1.1 ad *dst++ = *src++; 2174 1.1 ad else 2175 1.1 ad *dst++ = ' '; 2176 1.1 ad } 2177 1.1 ad } 2178 1.1 ad 2179 1.1 ad /* 2180 1.1 ad * Allocate DMA safe memory. 2181 1.1 ad */ 2182 1.1 ad static int 2183 1.23 perry mly_dmamem_alloc(struct mly_softc *mly, int size, bus_dmamap_t *dmamap, 2184 1.34 christos void **kva, bus_addr_t *paddr, bus_dma_segment_t *seg) 2185 1.1 ad { 2186 1.1 ad int rseg, rv, state; 2187 1.1 ad 2188 1.1 ad state = 0; 2189 1.23 perry 2190 1.23 perry if ((rv = bus_dmamem_alloc(mly->mly_dmat, size, PAGE_SIZE, 0, 2191 1.1 ad seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 2192 1.45 chs aprint_error_dev(mly->mly_dv, "dmamem_alloc = %d\n", rv); 2193 1.1 ad goto bad; 2194 1.1 ad } 2195 1.1 ad 2196 1.1 ad state++; 2197 1.1 ad 2198 1.1 ad if ((rv = bus_dmamem_map(mly->mly_dmat, seg, 1, size, kva, 2199 1.1 ad BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 2200 1.45 chs aprint_error_dev(mly->mly_dv, "dmamem_map = %d\n", rv); 2201 1.1 ad goto bad; 2202 1.1 ad } 2203 1.1 ad 2204 1.1 ad state++; 2205 1.1 ad 2206 1.23 perry if ((rv = bus_dmamap_create(mly->mly_dmat, size, size, 1, 0, 2207 1.1 ad BUS_DMA_NOWAIT, dmamap)) != 0) { 2208 1.45 chs aprint_error_dev(mly->mly_dv, "dmamap_create = %d\n", rv); 2209 1.1 ad goto bad; 2210 1.1 ad } 2211 1.1 ad 2212 1.1 ad state++; 2213 1.1 ad 2214 1.23 perry if ((rv = bus_dmamap_load(mly->mly_dmat, *dmamap, *kva, size, 2215 1.1 ad NULL, BUS_DMA_NOWAIT)) != 0) { 2216 1.45 chs aprint_error_dev(mly->mly_dv, "dmamap_load = %d\n", rv); 2217 1.1 ad goto bad; 2218 1.1 ad } 2219 1.1 ad 2220 1.1 ad *paddr = (*dmamap)->dm_segs[0].ds_addr; 2221 1.1 ad memset(*kva, 0, size); 2222 1.1 ad return (0); 2223 1.1 ad 2224 1.1 ad bad: 2225 1.1 ad if (state > 2) 2226 1.1 ad bus_dmamap_destroy(mly->mly_dmat, *dmamap); 2227 1.1 ad if (state > 1) 2228 1.1 ad bus_dmamem_unmap(mly->mly_dmat, *kva, size); 2229 1.1 ad if (state > 0) 2230 1.1 ad bus_dmamem_free(mly->mly_dmat, seg, 1); 2231 1.1 ad 2232 1.1 ad return (rv); 2233 1.1 ad } 2234 1.1 ad 2235 1.1 ad /* 2236 1.1 ad * Free DMA safe memory. 2237 1.1 ad */ 2238 1.1 ad static void 2239 1.23 perry mly_dmamem_free(struct mly_softc *mly, int size, bus_dmamap_t dmamap, 2240 1.34 christos void *kva, bus_dma_segment_t *seg) 2241 1.1 ad { 2242 1.1 ad 2243 1.1 ad bus_dmamap_unload(mly->mly_dmat, dmamap); 2244 1.1 ad bus_dmamap_destroy(mly->mly_dmat, dmamap); 2245 1.1 ad bus_dmamem_unmap(mly->mly_dmat, kva, size); 2246 1.1 ad bus_dmamem_free(mly->mly_dmat, seg, 1); 2247 1.1 ad } 2248 1.1 ad 2249 1.1 ad 2250 1.1 ad /* 2251 1.1 ad * Accept an open operation on the control device. 2252 1.1 ad */ 2253 1.1 ad int 2254 1.32 christos mlyopen(dev_t dev, int flag, int mode, struct lwp *l) 2255 1.1 ad { 2256 1.1 ad struct mly_softc *mly; 2257 1.1 ad 2258 1.39 tsutsui if ((mly = device_lookup_private(&mly_cd, minor(dev))) == NULL) 2259 1.1 ad return (ENXIO); 2260 1.1 ad if ((mly->mly_state & MLY_STATE_INITOK) == 0) 2261 1.1 ad return (ENXIO); 2262 1.1 ad if ((mly->mly_state & MLY_STATE_OPEN) != 0) 2263 1.1 ad return (EBUSY); 2264 1.1 ad 2265 1.1 ad mly->mly_state |= MLY_STATE_OPEN; 2266 1.1 ad return (0); 2267 1.1 ad } 2268 1.1 ad 2269 1.1 ad /* 2270 1.1 ad * Accept the last close on the control device. 2271 1.1 ad */ 2272 1.1 ad int 2273 1.32 christos mlyclose(dev_t dev, int flag, int mode, 2274 1.32 christos struct lwp *l) 2275 1.1 ad { 2276 1.1 ad struct mly_softc *mly; 2277 1.1 ad 2278 1.39 tsutsui mly = device_lookup_private(&mly_cd, minor(dev)); 2279 1.1 ad mly->mly_state &= ~MLY_STATE_OPEN; 2280 1.1 ad return (0); 2281 1.1 ad } 2282 1.1 ad 2283 1.1 ad /* 2284 1.1 ad * Handle control operations. 2285 1.1 ad */ 2286 1.1 ad int 2287 1.34 christos mlyioctl(dev_t dev, u_long cmd, void *data, int flag, 2288 1.31 elad struct lwp *l) 2289 1.1 ad { 2290 1.1 ad struct mly_softc *mly; 2291 1.1 ad int rv; 2292 1.1 ad 2293 1.39 tsutsui mly = device_lookup_private(&mly_cd, minor(dev)); 2294 1.1 ad 2295 1.1 ad switch (cmd) { 2296 1.1 ad case MLYIO_COMMAND: 2297 1.33 elad rv = kauth_authorize_device_passthru(l->l_cred, dev, 2298 1.33 elad KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data); 2299 1.31 elad if (rv) 2300 1.31 elad break; 2301 1.31 elad 2302 1.31 elad rv = mly_user_command(mly, (void *)data); 2303 1.1 ad break; 2304 1.1 ad case MLYIO_HEALTH: 2305 1.1 ad rv = mly_user_health(mly, (void *)data); 2306 1.1 ad break; 2307 1.1 ad default: 2308 1.1 ad rv = ENOTTY; 2309 1.1 ad break; 2310 1.1 ad } 2311 1.1 ad 2312 1.1 ad return (rv); 2313 1.1 ad } 2314 1.1 ad 2315 1.1 ad /* 2316 1.1 ad * Execute a command passed in from userspace. 2317 1.1 ad * 2318 1.1 ad * The control structure contains the actual command for the controller, as 2319 1.1 ad * well as the user-space data pointer and data size, and an optional sense 2320 1.1 ad * buffer size/pointer. On completion, the data size is adjusted to the 2321 1.1 ad * command residual, and the sense buffer size to the size of the returned 2322 1.1 ad * sense data. 2323 1.1 ad */ 2324 1.1 ad static int 2325 1.1 ad mly_user_command(struct mly_softc *mly, struct mly_user_command *uc) 2326 1.1 ad { 2327 1.1 ad struct mly_ccb *mc; 2328 1.1 ad int rv, mapped; 2329 1.1 ad 2330 1.1 ad if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 2331 1.1 ad return (rv); 2332 1.1 ad 2333 1.1 ad mapped = 0; 2334 1.1 ad mc->mc_data = NULL; 2335 1.1 ad 2336 1.1 ad /* 2337 1.1 ad * Handle data size/direction. 2338 1.1 ad */ 2339 1.1 ad if ((mc->mc_length = abs(uc->DataTransferLength)) != 0) { 2340 1.6 ad if (mc->mc_length > MAXPHYS) { 2341 1.6 ad rv = EINVAL; 2342 1.6 ad goto out; 2343 1.6 ad } 2344 1.6 ad 2345 1.1 ad mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_WAITOK); 2346 1.1 ad if (mc->mc_data == NULL) { 2347 1.1 ad rv = ENOMEM; 2348 1.1 ad goto out; 2349 1.1 ad } 2350 1.1 ad 2351 1.1 ad if (uc->DataTransferLength > 0) { 2352 1.1 ad mc->mc_flags |= MLY_CCB_DATAIN; 2353 1.1 ad memset(mc->mc_data, 0, mc->mc_length); 2354 1.1 ad } 2355 1.23 perry 2356 1.1 ad if (uc->DataTransferLength < 0) { 2357 1.1 ad mc->mc_flags |= MLY_CCB_DATAOUT; 2358 1.1 ad rv = copyin(uc->DataTransferBuffer, mc->mc_data, 2359 1.1 ad mc->mc_length); 2360 1.1 ad if (rv != 0) 2361 1.1 ad goto out; 2362 1.1 ad } 2363 1.1 ad 2364 1.1 ad if ((rv = mly_ccb_map(mly, mc)) != 0) 2365 1.1 ad goto out; 2366 1.1 ad mapped = 1; 2367 1.1 ad } 2368 1.1 ad 2369 1.1 ad /* Copy in the command and execute it. */ 2370 1.1 ad memcpy(mc->mc_packet, &uc->CommandMailbox, sizeof(uc->CommandMailbox)); 2371 1.1 ad 2372 1.1 ad if ((rv = mly_ccb_wait(mly, mc, 60000)) != 0) 2373 1.1 ad goto out; 2374 1.1 ad 2375 1.1 ad /* Return the data to userspace. */ 2376 1.1 ad if (uc->DataTransferLength > 0) { 2377 1.1 ad rv = copyout(mc->mc_data, uc->DataTransferBuffer, 2378 1.1 ad mc->mc_length); 2379 1.1 ad if (rv != 0) 2380 1.1 ad goto out; 2381 1.1 ad } 2382 1.23 perry 2383 1.1 ad /* Return the sense buffer to userspace. */ 2384 1.1 ad if (uc->RequestSenseLength > 0 && mc->mc_sense > 0) { 2385 1.23 perry rv = copyout(mc->mc_packet, uc->RequestSenseBuffer, 2386 1.51 riastrad uimin(uc->RequestSenseLength, mc->mc_sense)); 2387 1.1 ad if (rv != 0) 2388 1.1 ad goto out; 2389 1.1 ad } 2390 1.1 ad 2391 1.1 ad /* Return command results to userspace (caller will copy out). */ 2392 1.1 ad uc->DataTransferLength = mc->mc_resid; 2393 1.51 riastrad uc->RequestSenseLength = uimin(uc->RequestSenseLength, mc->mc_sense); 2394 1.1 ad uc->CommandStatus = mc->mc_status; 2395 1.1 ad rv = 0; 2396 1.1 ad 2397 1.1 ad out: 2398 1.1 ad if (mapped) 2399 1.1 ad mly_ccb_unmap(mly, mc); 2400 1.1 ad if (mc->mc_data != NULL) 2401 1.1 ad free(mc->mc_data, M_DEVBUF); 2402 1.25 christos mly_ccb_free(mly, mc); 2403 1.1 ad 2404 1.1 ad return (rv); 2405 1.1 ad } 2406 1.1 ad 2407 1.1 ad /* 2408 1.1 ad * Return health status to userspace. If the health change index in the 2409 1.1 ad * user structure does not match that currently exported by the controller, 2410 1.1 ad * we return the current status immediately. Otherwise, we block until 2411 1.1 ad * either interrupted or new status is delivered. 2412 1.1 ad */ 2413 1.1 ad static int 2414 1.1 ad mly_user_health(struct mly_softc *mly, struct mly_user_health *uh) 2415 1.1 ad { 2416 1.1 ad struct mly_health_status mh; 2417 1.1 ad int rv, s; 2418 1.23 perry 2419 1.1 ad /* Fetch the current health status from userspace. */ 2420 1.1 ad rv = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh)); 2421 1.1 ad if (rv != 0) 2422 1.1 ad return (rv); 2423 1.1 ad 2424 1.1 ad /* spin waiting for a status update */ 2425 1.1 ad s = splbio(); 2426 1.1 ad if (mly->mly_event_change == mh.change_counter) 2427 1.1 ad rv = tsleep(&mly->mly_event_change, PRIBIO | PCATCH, 2428 1.1 ad "mlyhealth", 0); 2429 1.1 ad splx(s); 2430 1.1 ad 2431 1.1 ad if (rv == 0) { 2432 1.1 ad /* 2433 1.1 ad * Copy the controller's health status buffer out (there is 2434 1.1 ad * a race here if it changes again). 2435 1.1 ad */ 2436 1.1 ad rv = copyout(&mly->mly_mmbox->mmm_health.status, 2437 1.1 ad uh->HealthStatusBuffer, sizeof(uh->HealthStatusBuffer)); 2438 1.1 ad } 2439 1.1 ad 2440 1.1 ad return (rv); 2441 1.1 ad } 2442