1 1.79 andvar /* $NetBSD: dpt.c,v 1.79 2024/02/10 09:24:17 andvar Exp $ */ 2 1.1 ad 3 1.1 ad /*- 4 1.29 bouyer * Copyright (c) 1997, 1998, 1999, 2000, 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.22 ad * by Andrew Doran, Charles M. Hannum and by Jason R. Thorpe of the Numerical 9 1.1 ad * Aerospace Simulation Facility, NASA Ames Research Center. 10 1.1 ad * 11 1.1 ad * Redistribution and use in source and binary forms, with or without 12 1.1 ad * modification, are permitted provided that the following conditions 13 1.1 ad * are met: 14 1.1 ad * 1. Redistributions of source code must retain the above copyright 15 1.1 ad * notice, this list of conditions and the following disclaimer. 16 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 ad * notice, this list of conditions and the following disclaimer in the 18 1.1 ad * documentation and/or other materials provided with the distribution. 19 1.1 ad * 20 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 ad * POSSIBILITY OF SUCH DAMAGE. 31 1.1 ad */ 32 1.1 ad 33 1.1 ad /* 34 1.33 ad * Copyright (c) 1996-2000 Distributed Processing Technology Corporation 35 1.33 ad * Copyright (c) 2000 Adaptec Corporation 36 1.33 ad * All rights reserved. 37 1.33 ad * 38 1.33 ad * TERMS AND CONDITIONS OF USE 39 1.33 ad * 40 1.33 ad * Redistribution and use in source form, with or without modification, are 41 1.33 ad * permitted provided that redistributions of source code must retain the 42 1.33 ad * above copyright notice, this list of conditions and the following disclaimer. 43 1.33 ad * 44 1.33 ad * This software is provided `as is' by Adaptec and any express or implied 45 1.33 ad * warranties, including, but not limited to, the implied warranties of 46 1.33 ad * merchantability and fitness for a particular purpose, are disclaimed. In no 47 1.33 ad * event shall Adaptec be liable for any direct, indirect, incidental, special, 48 1.33 ad * exemplary or consequential damages (including, but not limited to, 49 1.33 ad * procurement of substitute goods or services; loss of use, data, or profits; 50 1.33 ad * or business interruptions) however caused and on any theory of liability, 51 1.33 ad * whether in contract, strict liability, or tort (including negligence or 52 1.33 ad * otherwise) arising in any way out of the use of this driver software, even 53 1.33 ad * if advised of the possibility of such damage. 54 1.33 ad */ 55 1.33 ad 56 1.33 ad /* 57 1.1 ad * Portions of this code fall under the following copyright: 58 1.1 ad * 59 1.1 ad * Originally written by Julian Elischer (julian (at) tfs.com) 60 1.1 ad * for TRW Financial Systems for use under the MACH(2.5) operating system. 61 1.1 ad * 62 1.1 ad * TRW Financial Systems, in accordance with their agreement with Carnegie 63 1.1 ad * Mellon University, makes this software available to CMU to distribute 64 1.1 ad * or use in any manner that they see fit as long as this message is kept with 65 1.1 ad * the software. For this reason TFS also grants any other persons or 66 1.1 ad * organisations permission to use or modify this software. 67 1.1 ad * 68 1.1 ad * TFS supplies this software to be publicly redistributed 69 1.1 ad * on the understanding that TFS is not responsible for the correct 70 1.1 ad * functioning of this software in any circumstances. 71 1.1 ad */ 72 1.31 lukem 73 1.31 lukem #include <sys/cdefs.h> 74 1.79 andvar __KERNEL_RCSID(0, "$NetBSD: dpt.c,v 1.79 2024/02/10 09:24:17 andvar Exp $"); 75 1.1 ad 76 1.1 ad #include <sys/param.h> 77 1.1 ad #include <sys/systm.h> 78 1.1 ad #include <sys/device.h> 79 1.1 ad #include <sys/queue.h> 80 1.1 ad #include <sys/buf.h> 81 1.13 ad #include <sys/endian.h> 82 1.33 ad #include <sys/conf.h> 83 1.53 elad #include <sys/kauth.h> 84 1.57 ad #include <sys/proc.h> 85 1.66 rmind #include <sys/mutex.h> 86 1.1 ad 87 1.58 ad #include <sys/bus.h> 88 1.33 ad #ifdef i386 89 1.33 ad #include <machine/pio.h> 90 1.61 ad #include <machine/cputypes.h> 91 1.33 ad #endif 92 1.1 ad 93 1.1 ad #include <dev/scsipi/scsi_all.h> 94 1.1 ad #include <dev/scsipi/scsipi_all.h> 95 1.1 ad #include <dev/scsipi/scsiconf.h> 96 1.1 ad 97 1.1 ad #include <dev/ic/dptreg.h> 98 1.1 ad #include <dev/ic/dptvar.h> 99 1.1 ad 100 1.33 ad #include <dev/i2o/dptivar.h> 101 1.33 ad 102 1.74 riastrad #include "ioconf.h" 103 1.74 riastrad 104 1.33 ad #ifdef DEBUG 105 1.33 ad #define DPRINTF(x) printf x 106 1.33 ad #else 107 1.33 ad #define DPRINTF(x) 108 1.33 ad #endif 109 1.33 ad 110 1.29 bouyer #define dpt_inb(x, o) \ 111 1.29 bouyer bus_space_read_1((x)->sc_iot, (x)->sc_ioh, (o)) 112 1.29 bouyer #define dpt_outb(x, o, d) \ 113 1.29 bouyer bus_space_write_1((x)->sc_iot, (x)->sc_ioh, (o), (d)) 114 1.29 bouyer 115 1.29 bouyer static const char * const dpt_cname[] = { 116 1.29 bouyer "3334", "SmartRAID IV", 117 1.29 bouyer "3332", "SmartRAID IV", 118 1.29 bouyer "2144", "SmartCache IV", 119 1.29 bouyer "2044", "SmartCache IV", 120 1.29 bouyer "2142", "SmartCache IV", 121 1.29 bouyer "2042", "SmartCache IV", 122 1.29 bouyer "2041", "SmartCache IV", 123 1.29 bouyer "3224", "SmartRAID III", 124 1.44 perry "3222", "SmartRAID III", 125 1.29 bouyer "3021", "SmartRAID III", 126 1.29 bouyer "2124", "SmartCache III", 127 1.29 bouyer "2024", "SmartCache III", 128 1.29 bouyer "2122", "SmartCache III", 129 1.29 bouyer "2022", "SmartCache III", 130 1.29 bouyer "2021", "SmartCache III", 131 1.44 perry "2012", "SmartCache Plus", 132 1.29 bouyer "2011", "SmartCache Plus", 133 1.29 bouyer NULL, "<unknown>", 134 1.1 ad }; 135 1.1 ad 136 1.29 bouyer static void *dpt_sdh; 137 1.29 bouyer 138 1.33 ad dev_type_open(dptopen); 139 1.33 ad dev_type_ioctl(dptioctl); 140 1.33 ad 141 1.33 ad const struct cdevsw dpt_cdevsw = { 142 1.70 dholland .d_open = dptopen, 143 1.70 dholland .d_close = nullclose, 144 1.70 dholland .d_read = noread, 145 1.70 dholland .d_write = nowrite, 146 1.70 dholland .d_ioctl = dptioctl, 147 1.70 dholland .d_stop = nostop, 148 1.70 dholland .d_tty = notty, 149 1.70 dholland .d_poll = nopoll, 150 1.70 dholland .d_mmap = nommap, 151 1.70 dholland .d_kqfilter = nokqfilter, 152 1.71 dholland .d_discard = nodiscard, 153 1.70 dholland .d_flag = D_OTHER, 154 1.33 ad }; 155 1.33 ad 156 1.33 ad static struct dpt_sig dpt_sig = { 157 1.33 ad { 'd', 'P', 't', 'S', 'i', 'G'}, 158 1.33 ad SIG_VERSION, 159 1.33 ad #if defined(i386) 160 1.33 ad PROC_INTEL, 161 1.33 ad #elif defined(powerpc) 162 1.33 ad PROC_POWERPC, 163 1.33 ad #elif defined(alpha) 164 1.33 ad PROC_ALPHA, 165 1.33 ad #elif defined(__mips__) 166 1.33 ad PROC_MIPS, 167 1.33 ad #elif defined(sparc64) 168 1.33 ad PROC_ULTRASPARC, 169 1.35 fvdl #else 170 1.35 fvdl 0xff, 171 1.33 ad #endif 172 1.33 ad #if defined(i386) 173 1.33 ad PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM, 174 1.33 ad #else 175 1.33 ad 0, 176 1.33 ad #endif 177 1.33 ad FT_HBADRVR, 178 1.33 ad 0, 179 1.33 ad OEM_DPT, 180 1.33 ad OS_FREE_BSD, /* XXX */ 181 1.33 ad CAP_ABOVE16MB, 182 1.33 ad DEV_ALL, 183 1.33 ad ADF_ALL_EATA, 184 1.33 ad 0, 185 1.33 ad 0, 186 1.33 ad DPT_VERSION, 187 1.33 ad DPT_REVISION, 188 1.33 ad DPT_SUBREVISION, 189 1.33 ad DPT_MONTH, 190 1.33 ad DPT_DAY, 191 1.33 ad DPT_YEAR, 192 1.33 ad "" /* Will be filled later */ 193 1.33 ad }; 194 1.33 ad 195 1.29 bouyer static void dpt_ccb_abort(struct dpt_softc *, struct dpt_ccb *); 196 1.29 bouyer static void dpt_ccb_done(struct dpt_softc *, struct dpt_ccb *); 197 1.29 bouyer static int dpt_ccb_map(struct dpt_softc *, struct dpt_ccb *); 198 1.29 bouyer static int dpt_ccb_poll(struct dpt_softc *, struct dpt_ccb *); 199 1.29 bouyer static void dpt_ccb_unmap(struct dpt_softc *, struct dpt_ccb *); 200 1.29 bouyer static int dpt_cmd(struct dpt_softc *, struct dpt_ccb *, int, int); 201 1.33 ad static void dpt_ctlrinfo(struct dpt_softc *, struct dpt_eata_ctlrinfo *); 202 1.29 bouyer static void dpt_hba_inquire(struct dpt_softc *, struct eata_inquiry_data **); 203 1.29 bouyer static void dpt_minphys(struct buf *); 204 1.34 ad static int dpt_passthrough(struct dpt_softc *, struct eata_ucp *, 205 1.45 christos struct lwp *); 206 1.29 bouyer static void dpt_scsipi_request(struct scsipi_channel *, 207 1.29 bouyer scsipi_adapter_req_t, void *); 208 1.29 bouyer static void dpt_shutdown(void *); 209 1.33 ad static void dpt_sysinfo(struct dpt_softc *, struct dpt_sysinfo *); 210 1.29 bouyer static int dpt_wait(struct dpt_softc *, u_int8_t, u_int8_t, int); 211 1.29 bouyer 212 1.46 perry static inline struct dpt_ccb *dpt_ccb_alloc(struct dpt_softc *); 213 1.46 perry static inline void dpt_ccb_free(struct dpt_softc *, struct dpt_ccb *); 214 1.29 bouyer 215 1.46 perry static inline struct dpt_ccb * 216 1.29 bouyer dpt_ccb_alloc(struct dpt_softc *sc) 217 1.29 bouyer { 218 1.29 bouyer struct dpt_ccb *ccb; 219 1.29 bouyer int s; 220 1.29 bouyer 221 1.29 bouyer s = splbio(); 222 1.29 bouyer ccb = SLIST_FIRST(&sc->sc_ccb_free); 223 1.29 bouyer SLIST_REMOVE_HEAD(&sc->sc_ccb_free, ccb_chain); 224 1.29 bouyer splx(s); 225 1.29 bouyer 226 1.29 bouyer return (ccb); 227 1.29 bouyer } 228 1.29 bouyer 229 1.46 perry static inline void 230 1.29 bouyer dpt_ccb_free(struct dpt_softc *sc, struct dpt_ccb *ccb) 231 1.29 bouyer { 232 1.29 bouyer int s; 233 1.1 ad 234 1.29 bouyer ccb->ccb_flg = 0; 235 1.33 ad ccb->ccb_savesp = NULL; 236 1.29 bouyer s = splbio(); 237 1.29 bouyer SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_chain); 238 1.29 bouyer splx(s); 239 1.29 bouyer } 240 1.19 ad 241 1.1 ad /* 242 1.1 ad * Handle an interrupt from the HBA. 243 1.1 ad */ 244 1.1 ad int 245 1.29 bouyer dpt_intr(void *cookie) 246 1.1 ad { 247 1.1 ad struct dpt_softc *sc; 248 1.1 ad struct dpt_ccb *ccb; 249 1.1 ad struct eata_sp *sp; 250 1.29 bouyer int forus; 251 1.1 ad 252 1.29 bouyer sc = cookie; 253 1.19 ad sp = sc->sc_stp; 254 1.29 bouyer forus = 0; 255 1.19 ad 256 1.7 ad for (;;) { 257 1.7 ad /* 258 1.7 ad * HBA might have interrupted while we were dealing with the 259 1.44 perry * last completed command, since we ACK before we deal; keep 260 1.19 ad * polling. 261 1.29 bouyer */ 262 1.19 ad if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) 263 1.7 ad break; 264 1.29 bouyer forus = 1; 265 1.29 bouyer 266 1.19 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff, 267 1.1 ad sizeof(struct eata_sp), BUS_DMASYNC_POSTREAD); 268 1.1 ad 269 1.29 bouyer /* Might have looped before HBA can reset HBA_AUX_INTR. */ 270 1.1 ad if (sp->sp_ccbid == -1) { 271 1.1 ad DELAY(50); 272 1.19 ad 273 1.1 ad if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) == 0) 274 1.1 ad return (0); 275 1.19 ad 276 1.68 chs printf("%s: no status\n", device_xname(sc->sc_dev)); 277 1.19 ad 278 1.1 ad /* Re-sync DMA map */ 279 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 280 1.19 ad sc->sc_stpoff, sizeof(struct eata_sp), 281 1.1 ad BUS_DMASYNC_POSTREAD); 282 1.1 ad } 283 1.1 ad 284 1.29 bouyer /* Make sure CCB ID from status packet is realistic. */ 285 1.29 bouyer if ((u_int)sp->sp_ccbid >= sc->sc_nccbs) { 286 1.44 perry printf("%s: bogus status (returned CCB id %d)\n", 287 1.68 chs device_xname(sc->sc_dev), sp->sp_ccbid); 288 1.1 ad 289 1.1 ad /* Ack the interrupt */ 290 1.20 ad sp->sp_ccbid = -1; 291 1.69 martin (void)dpt_inb(sc, HA_STATUS); 292 1.29 bouyer continue; 293 1.1 ad } 294 1.29 bouyer 295 1.29 bouyer /* Sync up DMA map and cache cmd status. */ 296 1.29 bouyer ccb = sc->sc_ccbs + sp->sp_ccbid; 297 1.29 bouyer 298 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb), 299 1.29 bouyer sizeof(struct dpt_ccb), BUS_DMASYNC_POSTWRITE); 300 1.29 bouyer 301 1.29 bouyer ccb->ccb_hba_status = sp->sp_hba_status & 0x7f; 302 1.29 bouyer ccb->ccb_scsi_status = sp->sp_scsi_status; 303 1.33 ad if (ccb->ccb_savesp != NULL) 304 1.33 ad memcpy(ccb->ccb_savesp, sp, sizeof(*sp)); 305 1.29 bouyer 306 1.44 perry /* 307 1.29 bouyer * Ack the interrupt and process the CCB. If this 308 1.29 bouyer * is a private CCB it's up to dpt_ccb_poll() to 309 1.29 bouyer * notice. 310 1.29 bouyer */ 311 1.29 bouyer sp->sp_ccbid = -1; 312 1.29 bouyer ccb->ccb_flg |= CCB_INTR; 313 1.69 martin (void)dpt_inb(sc, HA_STATUS); 314 1.29 bouyer if ((ccb->ccb_flg & CCB_PRIVATE) == 0) 315 1.29 bouyer dpt_ccb_done(sc, ccb); 316 1.33 ad else if ((ccb->ccb_flg & CCB_WAIT) != 0) 317 1.33 ad wakeup(ccb); 318 1.1 ad } 319 1.1 ad 320 1.29 bouyer return (forus); 321 1.1 ad } 322 1.1 ad 323 1.1 ad /* 324 1.29 bouyer * Initialize and attach the HBA. This is the entry point from bus 325 1.1 ad * specific probe-and-attach code. 326 1.1 ad */ 327 1.1 ad void 328 1.29 bouyer dpt_init(struct dpt_softc *sc, const char *intrstr) 329 1.1 ad { 330 1.29 bouyer struct scsipi_adapter *adapt; 331 1.29 bouyer struct scsipi_channel *chan; 332 1.1 ad struct eata_inquiry_data *ei; 333 1.29 bouyer int i, j, rv, rseg, maxchannel, maxtarget, mapsize; 334 1.1 ad bus_dma_segment_t seg; 335 1.4 ad struct eata_cfg *ec; 336 1.29 bouyer struct dpt_ccb *ccb; 337 1.47 christos char model[__arraycount(ei->ei_model) + __arraycount(ei->ei_suffix) + 1]; 338 1.47 christos char vendor[__arraycount(ei->ei_vendor) + 1]; 339 1.29 bouyer 340 1.4 ad ec = &sc->sc_ec; 341 1.43 itojun snprintf(dpt_sig.dsDescription, sizeof(dpt_sig.dsDescription), 342 1.43 itojun "NetBSD %s DPT driver", osrelease); 343 1.66 rmind mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 344 1.33 ad 345 1.29 bouyer /* 346 1.29 bouyer * Allocate the CCB/status packet/scratch DMA map and load. 347 1.29 bouyer */ 348 1.44 perry sc->sc_nccbs = 349 1.75 riastrad uimin(be16toh(*(int16_t *)ec->ec_queuedepth), DPT_MAX_CCBS); 350 1.19 ad sc->sc_stpoff = sc->sc_nccbs * sizeof(struct dpt_ccb); 351 1.19 ad sc->sc_scroff = sc->sc_stpoff + sizeof(struct eata_sp); 352 1.44 perry mapsize = sc->sc_nccbs * sizeof(struct dpt_ccb) + 353 1.29 bouyer DPT_SCRATCH_SIZE + sizeof(struct eata_sp); 354 1.29 bouyer 355 1.29 bouyer if ((rv = bus_dmamem_alloc(sc->sc_dmat, mapsize, 356 1.24 thorpej PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 357 1.68 chs aprint_error_dev(sc->sc_dev, "unable to allocate CCBs, rv = %d\n", rv); 358 1.1 ad return; 359 1.1 ad } 360 1.1 ad 361 1.29 bouyer if ((rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, mapsize, 362 1.56 christos (void **)&sc->sc_ccbs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { 363 1.68 chs aprint_error_dev(sc->sc_dev, "unable to map CCBs, rv = %d\n", 364 1.59 cegger rv); 365 1.1 ad return; 366 1.1 ad } 367 1.1 ad 368 1.29 bouyer if ((rv = bus_dmamap_create(sc->sc_dmat, mapsize, 369 1.29 bouyer mapsize, 1, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { 370 1.68 chs aprint_error_dev(sc->sc_dev, "unable to create CCB DMA map, rv = %d\n", rv); 371 1.1 ad return; 372 1.1 ad } 373 1.1 ad 374 1.29 bouyer if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 375 1.29 bouyer sc->sc_ccbs, mapsize, NULL, BUS_DMA_NOWAIT)) != 0) { 376 1.68 chs aprint_error_dev(sc->sc_dev, "unable to load CCB DMA map, rv = %d\n", rv); 377 1.1 ad return; 378 1.1 ad } 379 1.1 ad 380 1.56 christos sc->sc_stp = (struct eata_sp *)((char *)sc->sc_ccbs + sc->sc_stpoff); 381 1.19 ad sc->sc_stppa = sc->sc_dmamap->dm_segs[0].ds_addr + sc->sc_stpoff; 382 1.56 christos sc->sc_scr = (char *)sc->sc_ccbs + sc->sc_scroff; 383 1.19 ad sc->sc_scrpa = sc->sc_dmamap->dm_segs[0].ds_addr + sc->sc_scroff; 384 1.19 ad sc->sc_stp->sp_ccbid = -1; 385 1.4 ad 386 1.29 bouyer /* 387 1.29 bouyer * Create the CCBs. 388 1.29 bouyer */ 389 1.29 bouyer SLIST_INIT(&sc->sc_ccb_free); 390 1.29 bouyer memset(sc->sc_ccbs, 0, sizeof(struct dpt_ccb) * sc->sc_nccbs); 391 1.29 bouyer 392 1.29 bouyer for (i = 0, ccb = sc->sc_ccbs; i < sc->sc_nccbs; i++, ccb++) { 393 1.29 bouyer rv = bus_dmamap_create(sc->sc_dmat, DPT_MAX_XFER, 394 1.29 bouyer DPT_SG_SIZE, DPT_MAX_XFER, 0, 395 1.29 bouyer BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 396 1.29 bouyer &ccb->ccb_dmamap_xfer); 397 1.29 bouyer if (rv) { 398 1.68 chs aprint_error_dev(sc->sc_dev, "can't create ccb dmamap (%d)\n", rv); 399 1.29 bouyer break; 400 1.29 bouyer } 401 1.29 bouyer 402 1.29 bouyer ccb->ccb_id = i; 403 1.29 bouyer ccb->ccb_ccbpa = sc->sc_dmamap->dm_segs[0].ds_addr + 404 1.29 bouyer CCB_OFF(sc, ccb); 405 1.29 bouyer SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_chain); 406 1.29 bouyer } 407 1.1 ad 408 1.1 ad if (i == 0) { 409 1.68 chs aprint_error_dev(sc->sc_dev, "unable to create CCBs\n"); 410 1.1 ad return; 411 1.1 ad } else if (i != sc->sc_nccbs) { 412 1.68 chs aprint_error_dev(sc->sc_dev, "%d/%d CCBs created!\n", 413 1.39 thorpej i, sc->sc_nccbs); 414 1.1 ad sc->sc_nccbs = i; 415 1.1 ad } 416 1.1 ad 417 1.29 bouyer /* Set shutdownhook before we start any device activity. */ 418 1.23 ad if (dpt_sdh == NULL) 419 1.19 ad dpt_sdh = shutdownhook_establish(dpt_shutdown, NULL); 420 1.1 ad 421 1.29 bouyer /* Get the inquiry data from the HBA. */ 422 1.1 ad dpt_hba_inquire(sc, &ei); 423 1.1 ad 424 1.44 perry /* 425 1.1 ad * dpt0 at pci0 dev 12 function 0: DPT SmartRAID III (PM3224A/9X-R) 426 1.1 ad * dpt0: interrupting at irq 10 427 1.1 ad * dpt0: 64 queued commands, 1 channel(s), adapter on ID(s) 7 428 1.1 ad */ 429 1.67 bouyer for (i = 0; i < __arraycount(ei->ei_vendor) && ei->ei_vendor[i] != ' '; 430 1.47 christos i++) 431 1.47 christos vendor[i] = ei->ei_vendor[i]; 432 1.47 christos vendor[i] = '\0'; 433 1.1 ad 434 1.67 bouyer for (i = 0; i < __arraycount(ei->ei_model) && ei->ei_model[i] != ' '; 435 1.47 christos i++) 436 1.25 cgd model[i] = ei->ei_model[i]; 437 1.67 bouyer for (j = 0; j < __arraycount(ei->ei_suffix) && ei->ei_suffix[j] != ' '; 438 1.47 christos i++, j++) 439 1.47 christos model[i] = ei->ei_suffix[j]; 440 1.1 ad model[i] = '\0'; 441 1.1 ad 442 1.29 bouyer /* Find the marketing name for the board. */ 443 1.9 ad for (i = 0; dpt_cname[i] != NULL; i += 2) 444 1.29 bouyer if (memcmp(ei->ei_model + 2, dpt_cname[i], 4) == 0) 445 1.1 ad break; 446 1.29 bouyer 447 1.47 christos aprint_normal("%s %s (%s)\n", vendor, dpt_cname[i + 1], model); 448 1.1 ad 449 1.1 ad if (intrstr != NULL) 450 1.73 msaitoh aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); 451 1.1 ad 452 1.19 ad maxchannel = (ec->ec_feat3 & EC_F3_MAX_CHANNEL_MASK) >> 453 1.19 ad EC_F3_MAX_CHANNEL_SHIFT; 454 1.19 ad maxtarget = (ec->ec_feat3 & EC_F3_MAX_TARGET_MASK) >> 455 1.19 ad EC_F3_MAX_TARGET_SHIFT; 456 1.19 ad 457 1.73 msaitoh aprint_normal_dev(sc->sc_dev, 458 1.73 msaitoh "%d queued commands, %d channel(s), adapter on ID(s)", 459 1.59 cegger sc->sc_nccbs, maxchannel + 1); 460 1.1 ad 461 1.19 ad for (i = 0; i <= maxchannel; i++) { 462 1.19 ad sc->sc_hbaid[i] = ec->ec_hba[3 - i]; 463 1.39 thorpej aprint_normal(" %d", sc->sc_hbaid[i]); 464 1.19 ad } 465 1.39 thorpej aprint_normal("\n"); 466 1.1 ad 467 1.29 bouyer /* 468 1.29 bouyer * Reset the SCSI controller chip(s) and bus. XXX Do we need to do 469 1.29 bouyer * this for each bus? 470 1.29 bouyer */ 471 1.29 bouyer if (dpt_cmd(sc, NULL, CP_IMMEDIATE, CPI_BUS_RESET)) 472 1.68 chs panic("%s: dpt_cmd failed", device_xname(sc->sc_dev)); 473 1.29 bouyer 474 1.29 bouyer /* Fill in the scsipi_adapter. */ 475 1.29 bouyer adapt = &sc->sc_adapt; 476 1.29 bouyer memset(adapt, 0, sizeof(*adapt)); 477 1.68 chs adapt->adapt_dev = sc->sc_dev; 478 1.29 bouyer adapt->adapt_nchannels = maxchannel + 1; 479 1.33 ad adapt->adapt_openings = sc->sc_nccbs - 1; 480 1.33 ad adapt->adapt_max_periph = sc->sc_nccbs - 1; 481 1.29 bouyer adapt->adapt_request = dpt_scsipi_request; 482 1.29 bouyer adapt->adapt_minphys = dpt_minphys; 483 1.1 ad 484 1.19 ad for (i = 0; i <= maxchannel; i++) { 485 1.29 bouyer /* Fill in the scsipi_channel. */ 486 1.29 bouyer chan = &sc->sc_chans[i]; 487 1.29 bouyer memset(chan, 0, sizeof(*chan)); 488 1.29 bouyer chan->chan_adapter = adapt; 489 1.29 bouyer chan->chan_bustype = &scsi_bustype; 490 1.29 bouyer chan->chan_channel = i; 491 1.29 bouyer chan->chan_ntargets = maxtarget + 1; 492 1.29 bouyer chan->chan_nluns = ec->ec_maxlun + 1; 493 1.29 bouyer chan->chan_id = sc->sc_hbaid[i]; 494 1.77 thorpej config_found(sc->sc_dev, chan, scsiprint, CFARGS_NONE); 495 1.23 ad } 496 1.1 ad } 497 1.1 ad 498 1.1 ad /* 499 1.1 ad * Read the EATA configuration from the HBA and perform some sanity checks. 500 1.1 ad */ 501 1.1 ad int 502 1.29 bouyer dpt_readcfg(struct dpt_softc *sc) 503 1.1 ad { 504 1.4 ad struct eata_cfg *ec; 505 1.1 ad int i, j, stat; 506 1.1 ad u_int16_t *p; 507 1.1 ad 508 1.4 ad ec = &sc->sc_ec; 509 1.4 ad 510 1.29 bouyer /* Older firmware may puke if we talk to it too soon after reset. */ 511 1.4 ad dpt_outb(sc, HA_COMMAND, CP_RESET); 512 1.19 ad DELAY(750000); 513 1.4 ad 514 1.4 ad for (i = 1000; i; i--) { 515 1.4 ad if ((dpt_inb(sc, HA_STATUS) & HA_ST_READY) != 0) 516 1.4 ad break; 517 1.4 ad DELAY(2000); 518 1.4 ad } 519 1.29 bouyer 520 1.4 ad if (i == 0) { 521 1.17 ad printf("%s: HBA not ready after reset (hba status:%02x)\n", 522 1.68 chs device_xname(sc->sc_dev), dpt_inb(sc, HA_STATUS)); 523 1.4 ad return (-1); 524 1.4 ad } 525 1.4 ad 526 1.1 ad while((((stat = dpt_inb(sc, HA_STATUS)) 527 1.19 ad != (HA_ST_READY|HA_ST_SEEK_COMPLETE)) 528 1.19 ad && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR)) 529 1.19 ad && (stat != (HA_ST_READY|HA_ST_SEEK_COMPLETE|HA_ST_ERROR|HA_ST_DRQ))) 530 1.29 bouyer || (dpt_wait(sc, HA_ST_BUSY, 0, 2000))) { 531 1.19 ad /* RAID drives still spinning up? */ 532 1.29 bouyer if(dpt_inb(sc, HA_ERROR) != 'D' || 533 1.29 bouyer dpt_inb(sc, HA_ERROR + 1) != 'P' || 534 1.29 bouyer dpt_inb(sc, HA_ERROR + 2) != 'T') { 535 1.68 chs printf("%s: HBA not ready\n", device_xname(sc->sc_dev)); 536 1.19 ad return (-1); 537 1.2 ad } 538 1.19 ad } 539 1.1 ad 540 1.44 perry /* 541 1.44 perry * Issue the read-config command and wait for the data to appear. 542 1.29 bouyer * 543 1.78 msaitoh * Apparently certain firmware revisions won't DMA later on if we 544 1.29 bouyer * request the config data using PIO, but it makes it a lot easier 545 1.29 bouyer * as no DMA setup is required. 546 1.1 ad */ 547 1.1 ad dpt_outb(sc, HA_COMMAND, CP_PIO_GETCFG); 548 1.4 ad memset(ec, 0, sizeof(*ec)); 549 1.65 mrg i = ((int)(uintptr_t)&((struct eata_cfg *)0)->ec_cfglen + 550 1.4 ad sizeof(ec->ec_cfglen)) >> 1; 551 1.4 ad p = (u_int16_t *)ec; 552 1.44 perry 553 1.4 ad if (dpt_wait(sc, 0xFF, HA_ST_DATA_RDY, 2000)) { 554 1.29 bouyer printf("%s: cfg data didn't appear (hba status:%02x)\n", 555 1.68 chs device_xname(sc->sc_dev), dpt_inb(sc, HA_STATUS)); 556 1.29 bouyer return (-1); 557 1.29 bouyer } 558 1.1 ad 559 1.29 bouyer /* Begin reading. */ 560 1.29 bouyer while (i--) 561 1.27 briggs *p++ = bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA); 562 1.1 ad 563 1.19 ad if ((i = ec->ec_cfglen) > (sizeof(struct eata_cfg) 564 1.65 mrg - (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen)) 565 1.19 ad - sizeof(ec->ec_cfglen))) 566 1.19 ad i = sizeof(struct eata_cfg) 567 1.65 mrg - (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen)) 568 1.19 ad - sizeof(ec->ec_cfglen); 569 1.19 ad 570 1.65 mrg j = i + (int)(uintptr_t)(&(((struct eata_cfg *)0L)->ec_cfglen)) + 571 1.19 ad sizeof(ec->ec_cfglen); 572 1.19 ad i >>= 1; 573 1.1 ad 574 1.1 ad while (i--) 575 1.27 briggs *p++ = bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA); 576 1.29 bouyer 577 1.19 ad /* Flush until we have read 512 bytes. */ 578 1.19 ad i = (512 - j + 1) >> 1; 579 1.1 ad while (i--) 580 1.48 christos (void)bus_space_read_stream_2(sc->sc_iot, sc->sc_ioh, HA_DATA); 581 1.44 perry 582 1.29 bouyer /* Defaults for older firmware... */ 583 1.4 ad if (p <= (u_short *)&ec->ec_hba[DPT_MAX_CHANNELS - 1]) 584 1.4 ad ec->ec_hba[DPT_MAX_CHANNELS - 1] = 7; 585 1.1 ad 586 1.19 ad if ((dpt_inb(sc, HA_STATUS) & HA_ST_ERROR) != 0) { 587 1.68 chs aprint_error_dev(sc->sc_dev, "HBA error\n"); 588 1.19 ad return (-1); 589 1.19 ad } 590 1.29 bouyer 591 1.15 ad if (memcmp(ec->ec_eatasig, "EATA", 4) != 0) { 592 1.68 chs aprint_error_dev(sc->sc_dev, "EATA signature mismatch\n"); 593 1.1 ad return (-1); 594 1.1 ad } 595 1.29 bouyer 596 1.19 ad if ((ec->ec_feat0 & EC_F0_HBA_VALID) == 0) { 597 1.68 chs aprint_error_dev(sc->sc_dev, "ec_hba field invalid\n"); 598 1.1 ad return (-1); 599 1.1 ad } 600 1.29 bouyer 601 1.19 ad if ((ec->ec_feat0 & EC_F0_DMA_SUPPORTED) == 0) { 602 1.68 chs aprint_error_dev(sc->sc_dev, "DMA not supported\n"); 603 1.1 ad return (-1); 604 1.1 ad } 605 1.1 ad 606 1.1 ad return (0); 607 1.1 ad } 608 1.1 ad 609 1.1 ad /* 610 1.29 bouyer * Our `shutdownhook' to cleanly shut down the HBA. The HBA must flush all 611 1.72 snj * data from its cache and mark array groups as clean. 612 1.29 bouyer * 613 1.29 bouyer * XXX This doesn't always work (i.e., the HBA may still be flushing after 614 1.29 bouyer * we tell root that it's safe to power off). 615 1.1 ad */ 616 1.29 bouyer static void 617 1.54 christos dpt_shutdown(void *cookie) 618 1.1 ad { 619 1.29 bouyer extern struct cfdriver dpt_cd; 620 1.29 bouyer struct dpt_softc *sc; 621 1.29 bouyer int i; 622 1.29 bouyer 623 1.29 bouyer printf("shutting down dpt devices..."); 624 1.29 bouyer 625 1.29 bouyer for (i = 0; i < dpt_cd.cd_ndevs; i++) { 626 1.62 tsutsui if ((sc = device_lookup_private(&dpt_cd, i)) == NULL) 627 1.29 bouyer continue; 628 1.29 bouyer dpt_cmd(sc, NULL, CP_IMMEDIATE, CPI_POWEROFF_WARN); 629 1.29 bouyer } 630 1.1 ad 631 1.29 bouyer delay(10000*1000); 632 1.29 bouyer printf(" done\n"); 633 1.1 ad } 634 1.1 ad 635 1.1 ad /* 636 1.29 bouyer * Send an EATA command to the HBA. 637 1.1 ad */ 638 1.29 bouyer static int 639 1.29 bouyer dpt_cmd(struct dpt_softc *sc, struct dpt_ccb *ccb, int eatacmd, int icmd) 640 1.1 ad { 641 1.29 bouyer u_int32_t pa; 642 1.29 bouyer int i, s; 643 1.1 ad 644 1.1 ad s = splbio(); 645 1.1 ad 646 1.29 bouyer for (i = 20000; i != 0; i--) { 647 1.29 bouyer if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_BUSY) == 0) 648 1.29 bouyer break; 649 1.29 bouyer DELAY(50); 650 1.29 bouyer } 651 1.29 bouyer if (i == 0) { 652 1.29 bouyer splx(s); 653 1.29 bouyer return (-1); 654 1.29 bouyer } 655 1.29 bouyer 656 1.29 bouyer pa = (ccb != NULL ? ccb->ccb_ccbpa : 0); 657 1.29 bouyer dpt_outb(sc, HA_DMA_BASE + 0, (pa ) & 0xff); 658 1.29 bouyer dpt_outb(sc, HA_DMA_BASE + 1, (pa >> 8) & 0xff); 659 1.29 bouyer dpt_outb(sc, HA_DMA_BASE + 2, (pa >> 16) & 0xff); 660 1.29 bouyer dpt_outb(sc, HA_DMA_BASE + 3, (pa >> 24) & 0xff); 661 1.29 bouyer 662 1.29 bouyer if (eatacmd == CP_IMMEDIATE) 663 1.29 bouyer dpt_outb(sc, HA_ICMD, icmd); 664 1.1 ad 665 1.29 bouyer dpt_outb(sc, HA_COMMAND, eatacmd); 666 1.1 ad 667 1.29 bouyer splx(s); 668 1.1 ad return (0); 669 1.1 ad } 670 1.1 ad 671 1.1 ad /* 672 1.29 bouyer * Wait for the HBA status register to reach a specific state. 673 1.1 ad */ 674 1.29 bouyer static int 675 1.29 bouyer dpt_wait(struct dpt_softc *sc, u_int8_t mask, u_int8_t state, int ms) 676 1.1 ad { 677 1.1 ad 678 1.29 bouyer for (ms *= 10; ms != 0; ms--) { 679 1.29 bouyer if ((dpt_inb(sc, HA_STATUS) & mask) == state) 680 1.29 bouyer return (0); 681 1.29 bouyer DELAY(100); 682 1.1 ad } 683 1.1 ad 684 1.29 bouyer return (-1); 685 1.1 ad } 686 1.1 ad 687 1.1 ad /* 688 1.29 bouyer * Spin waiting for a command to finish. The timeout value from the CCB is 689 1.29 bouyer * used. The CCB must be marked with CCB_PRIVATE, otherwise it'll will get 690 1.29 bouyer * recycled before we get a look at it. 691 1.1 ad */ 692 1.29 bouyer static int 693 1.29 bouyer dpt_ccb_poll(struct dpt_softc *sc, struct dpt_ccb *ccb) 694 1.1 ad { 695 1.29 bouyer int i, s; 696 1.29 bouyer 697 1.29 bouyer #ifdef DEBUG 698 1.29 bouyer if ((ccb->ccb_flg & CCB_PRIVATE) == 0) 699 1.32 provos panic("dpt_ccb_poll: called for non-CCB_PRIVATE request"); 700 1.29 bouyer #endif 701 1.1 ad 702 1.1 ad s = splbio(); 703 1.1 ad 704 1.29 bouyer if ((ccb->ccb_flg & CCB_INTR) != 0) { 705 1.29 bouyer splx(s); 706 1.29 bouyer return (0); 707 1.29 bouyer } 708 1.29 bouyer 709 1.29 bouyer for (i = ccb->ccb_timeout * 20; i != 0; i--) { 710 1.29 bouyer if ((dpt_inb(sc, HA_AUX_STATUS) & HA_AUX_INTR) != 0) 711 1.29 bouyer dpt_intr(sc); 712 1.29 bouyer if ((ccb->ccb_flg & CCB_INTR) != 0) 713 1.1 ad break; 714 1.29 bouyer DELAY(50); 715 1.1 ad } 716 1.1 ad 717 1.1 ad splx(s); 718 1.29 bouyer return (i == 0); 719 1.1 ad } 720 1.1 ad 721 1.1 ad /* 722 1.29 bouyer * We have a command which has been processed by the HBA, so now we look to 723 1.29 bouyer * see how the operation went. CCBs marked CCB_PRIVATE are not passed here 724 1.29 bouyer * by dpt_intr(). 725 1.1 ad */ 726 1.29 bouyer static void 727 1.29 bouyer dpt_ccb_done(struct dpt_softc *sc, struct dpt_ccb *ccb) 728 1.1 ad { 729 1.1 ad struct scsipi_xfer *xs; 730 1.29 bouyer 731 1.1 ad xs = ccb->ccb_xs; 732 1.1 ad 733 1.29 bouyer SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("dpt_ccb_done\n")); 734 1.1 ad 735 1.1 ad /* 736 1.44 perry * If we were a data transfer, unload the map that described the 737 1.1 ad * data buffer. 738 1.1 ad */ 739 1.29 bouyer if (xs->datalen != 0) 740 1.29 bouyer dpt_ccb_unmap(sc, ccb); 741 1.1 ad 742 1.1 ad if (xs->error == XS_NOERROR) { 743 1.19 ad if (ccb->ccb_hba_status != SP_HBA_NO_ERROR) { 744 1.1 ad switch (ccb->ccb_hba_status) { 745 1.19 ad case SP_HBA_ERROR_SEL_TO: 746 1.1 ad xs->error = XS_SELTIMEOUT; 747 1.1 ad break; 748 1.19 ad case SP_HBA_ERROR_RESET: 749 1.1 ad xs->error = XS_RESET; 750 1.1 ad break; 751 1.29 bouyer default: 752 1.1 ad printf("%s: HBA status %x\n", 753 1.68 chs device_xname(sc->sc_dev), ccb->ccb_hba_status); 754 1.1 ad xs->error = XS_DRIVER_STUFFUP; 755 1.29 bouyer break; 756 1.1 ad } 757 1.1 ad } else if (ccb->ccb_scsi_status != SCSI_OK) { 758 1.1 ad switch (ccb->ccb_scsi_status) { 759 1.1 ad case SCSI_CHECK: 760 1.29 bouyer memcpy(&xs->sense.scsi_sense, &ccb->ccb_sense, 761 1.29 bouyer sizeof(xs->sense.scsi_sense)); 762 1.1 ad xs->error = XS_SENSE; 763 1.1 ad break; 764 1.1 ad case SCSI_BUSY: 765 1.29 bouyer case SCSI_QUEUE_FULL: 766 1.1 ad xs->error = XS_BUSY; 767 1.1 ad break; 768 1.1 ad default: 769 1.29 bouyer scsipi_printaddr(xs->xs_periph); 770 1.29 bouyer printf("SCSI status %x\n", 771 1.29 bouyer ccb->ccb_scsi_status); 772 1.1 ad xs->error = XS_DRIVER_STUFFUP; 773 1.29 bouyer break; 774 1.1 ad } 775 1.1 ad } else 776 1.1 ad xs->resid = 0; 777 1.29 bouyer 778 1.7 ad xs->status = ccb->ccb_scsi_status; 779 1.1 ad } 780 1.1 ad 781 1.29 bouyer /* Free up the CCB and mark the command as done. */ 782 1.29 bouyer dpt_ccb_free(sc, ccb); 783 1.1 ad scsipi_done(xs); 784 1.1 ad } 785 1.1 ad 786 1.1 ad /* 787 1.29 bouyer * Specified CCB has timed out, abort it. 788 1.1 ad */ 789 1.29 bouyer static void 790 1.29 bouyer dpt_ccb_abort(struct dpt_softc *sc, struct dpt_ccb *ccb) 791 1.29 bouyer { 792 1.29 bouyer struct scsipi_periph *periph; 793 1.1 ad struct scsipi_xfer *xs; 794 1.29 bouyer int s; 795 1.1 ad 796 1.29 bouyer xs = ccb->ccb_xs; 797 1.29 bouyer periph = xs->xs_periph; 798 1.1 ad 799 1.29 bouyer scsipi_printaddr(periph); 800 1.44 perry printf("timed out (status:%02x aux status:%02x)", 801 1.29 bouyer dpt_inb(sc, HA_STATUS), dpt_inb(sc, HA_AUX_STATUS)); 802 1.1 ad 803 1.1 ad s = splbio(); 804 1.1 ad 805 1.29 bouyer if ((ccb->ccb_flg & CCB_ABORT) != 0) { 806 1.29 bouyer /* Abort timed out, reset the HBA */ 807 1.29 bouyer printf(" AGAIN, resetting HBA\n"); 808 1.29 bouyer dpt_outb(sc, HA_COMMAND, CP_RESET); 809 1.29 bouyer DELAY(750000); 810 1.1 ad } else { 811 1.29 bouyer /* Abort the operation that has timed out */ 812 1.29 bouyer printf("\n"); 813 1.29 bouyer xs->error = XS_TIMEOUT; 814 1.29 bouyer ccb->ccb_timeout = DPT_ABORT_TIMEOUT; 815 1.29 bouyer ccb->ccb_flg |= CCB_ABORT; 816 1.29 bouyer /* Start the abort */ 817 1.29 bouyer if (dpt_cmd(sc, ccb, CP_IMMEDIATE, CPI_SPEC_ABORT)) 818 1.68 chs aprint_error_dev(sc->sc_dev, "dpt_cmd failed\n"); 819 1.29 bouyer } 820 1.29 bouyer 821 1.29 bouyer splx(s); 822 1.29 bouyer } 823 1.1 ad 824 1.29 bouyer /* 825 1.29 bouyer * Map a data transfer. 826 1.29 bouyer */ 827 1.29 bouyer static int 828 1.29 bouyer dpt_ccb_map(struct dpt_softc *sc, struct dpt_ccb *ccb) 829 1.29 bouyer { 830 1.29 bouyer struct scsipi_xfer *xs; 831 1.29 bouyer bus_dmamap_t xfer; 832 1.29 bouyer bus_dma_segment_t *ds; 833 1.29 bouyer struct eata_sg *sg; 834 1.29 bouyer struct eata_cp *cp; 835 1.29 bouyer int rv, i; 836 1.1 ad 837 1.29 bouyer xs = ccb->ccb_xs; 838 1.29 bouyer xfer = ccb->ccb_dmamap_xfer; 839 1.29 bouyer cp = &ccb->ccb_eata_cp; 840 1.1 ad 841 1.29 bouyer rv = bus_dmamap_load(sc->sc_dmat, xfer, xs->data, xs->datalen, NULL, 842 1.44 perry ((xs->xs_control & XS_CTL_NOSLEEP) != 0 ? 843 1.30 thorpej BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | BUS_DMA_STREAMING | 844 1.30 thorpej ((xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); 845 1.29 bouyer 846 1.29 bouyer switch (rv) { 847 1.29 bouyer case 0: 848 1.29 bouyer break; 849 1.29 bouyer case ENOMEM: 850 1.29 bouyer case EAGAIN: 851 1.29 bouyer xs->error = XS_RESOURCE_SHORTAGE; 852 1.29 bouyer break; 853 1.29 bouyer default: 854 1.29 bouyer xs->error = XS_DRIVER_STUFFUP; 855 1.68 chs printf("%s: error %d loading map\n", device_xname(sc->sc_dev), rv); 856 1.29 bouyer break; 857 1.29 bouyer } 858 1.1 ad 859 1.29 bouyer if (xs->error != XS_NOERROR) { 860 1.29 bouyer dpt_ccb_free(sc, ccb); 861 1.29 bouyer scsipi_done(xs); 862 1.29 bouyer return (-1); 863 1.1 ad } 864 1.1 ad 865 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize, 866 1.29 bouyer (xs->xs_control & XS_CTL_DATA_IN) != 0 ? BUS_DMASYNC_PREREAD : 867 1.29 bouyer BUS_DMASYNC_PREWRITE); 868 1.29 bouyer 869 1.29 bouyer /* Don't bother using scatter/gather for just 1 seg */ 870 1.29 bouyer if (xfer->dm_nsegs == 1) { 871 1.29 bouyer cp->cp_dataaddr = htobe32(xfer->dm_segs[0].ds_addr); 872 1.29 bouyer cp->cp_datalen = htobe32(xfer->dm_segs[0].ds_len); 873 1.29 bouyer } else { 874 1.29 bouyer /* 875 1.44 perry * Load the hardware scatter/gather map with 876 1.29 bouyer * the contents of the DMA map. 877 1.1 ad */ 878 1.29 bouyer sg = ccb->ccb_sg; 879 1.29 bouyer ds = xfer->dm_segs; 880 1.29 bouyer for (i = 0; i < xfer->dm_nsegs; i++, sg++, ds++) { 881 1.29 bouyer sg->sg_addr = htobe32(ds->ds_addr); 882 1.29 bouyer sg->sg_len = htobe32(ds->ds_len); 883 1.29 bouyer } 884 1.44 perry cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) + 885 1.29 bouyer sc->sc_dmamap->dm_segs[0].ds_addr + 886 1.29 bouyer offsetof(struct dpt_ccb, ccb_sg)); 887 1.29 bouyer cp->cp_datalen = htobe32(i * sizeof(struct eata_sg)); 888 1.29 bouyer cp->cp_ctl0 |= CP_C0_SCATTER; 889 1.1 ad } 890 1.1 ad 891 1.29 bouyer return (0); 892 1.29 bouyer } 893 1.29 bouyer 894 1.29 bouyer /* 895 1.29 bouyer * Unmap a transfer. 896 1.29 bouyer */ 897 1.29 bouyer static void 898 1.29 bouyer dpt_ccb_unmap(struct dpt_softc *sc, struct dpt_ccb *ccb) 899 1.29 bouyer { 900 1.29 bouyer 901 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap_xfer, 0, 902 1.29 bouyer ccb->ccb_dmamap_xfer->dm_mapsize, 903 1.29 bouyer (ccb->ccb_eata_cp.cp_ctl0 & CP_C0_DATA_IN) != 0 ? 904 1.29 bouyer BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 905 1.29 bouyer bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap_xfer); 906 1.29 bouyer } 907 1.29 bouyer 908 1.29 bouyer /* 909 1.29 bouyer * Adjust the size of each I/O before it passes to the SCSI layer. 910 1.29 bouyer */ 911 1.29 bouyer static void 912 1.29 bouyer dpt_minphys(struct buf *bp) 913 1.29 bouyer { 914 1.29 bouyer 915 1.29 bouyer if (bp->b_bcount > DPT_MAX_XFER) 916 1.29 bouyer bp->b_bcount = DPT_MAX_XFER; 917 1.29 bouyer minphys(bp); 918 1.29 bouyer } 919 1.29 bouyer 920 1.29 bouyer /* 921 1.29 bouyer * Start a SCSI command. 922 1.29 bouyer */ 923 1.29 bouyer static void 924 1.29 bouyer dpt_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 925 1.29 bouyer void *arg) 926 1.29 bouyer { 927 1.29 bouyer struct dpt_softc *sc; 928 1.29 bouyer struct scsipi_xfer *xs; 929 1.29 bouyer int flags; 930 1.29 bouyer struct scsipi_periph *periph; 931 1.29 bouyer struct dpt_ccb *ccb; 932 1.29 bouyer struct eata_cp *cp; 933 1.29 bouyer 934 1.68 chs sc = device_private(chan->chan_adapter->adapt_dev); 935 1.1 ad 936 1.29 bouyer switch (req) { 937 1.29 bouyer case ADAPTER_REQ_RUN_XFER: 938 1.29 bouyer xs = arg; 939 1.29 bouyer periph = xs->xs_periph; 940 1.29 bouyer flags = xs->xs_control; 941 1.1 ad 942 1.29 bouyer #ifdef DIAGNOSTIC 943 1.29 bouyer /* Cmds must be no more than 12 bytes for us. */ 944 1.29 bouyer if (xs->cmdlen > 12) { 945 1.29 bouyer xs->error = XS_DRIVER_STUFFUP; 946 1.29 bouyer scsipi_done(xs); 947 1.29 bouyer break; 948 1.1 ad } 949 1.29 bouyer #endif 950 1.29 bouyer /* 951 1.29 bouyer * XXX We can't reset devices just yet. Apparently some 952 1.29 bouyer * older firmware revisions don't even support it. 953 1.29 bouyer */ 954 1.29 bouyer if ((flags & XS_CTL_RESET) != 0) { 955 1.1 ad xs->error = XS_DRIVER_STUFFUP; 956 1.29 bouyer scsipi_done(xs); 957 1.29 bouyer break; 958 1.1 ad } 959 1.1 ad 960 1.29 bouyer /* 961 1.29 bouyer * Get a CCB and fill it. 962 1.29 bouyer */ 963 1.29 bouyer ccb = dpt_ccb_alloc(sc); 964 1.29 bouyer ccb->ccb_xs = xs; 965 1.29 bouyer ccb->ccb_timeout = xs->timeout; 966 1.29 bouyer 967 1.29 bouyer cp = &ccb->ccb_eata_cp; 968 1.29 bouyer memcpy(&cp->cp_cdb_cmd, xs->cmd, xs->cmdlen); 969 1.29 bouyer cp->cp_ccbid = ccb->ccb_id; 970 1.29 bouyer cp->cp_senselen = sizeof(ccb->ccb_sense); 971 1.29 bouyer cp->cp_stataddr = htobe32(sc->sc_stppa); 972 1.29 bouyer cp->cp_ctl0 = CP_C0_AUTO_SENSE; 973 1.44 perry cp->cp_ctl1 = 0; 974 1.29 bouyer cp->cp_ctl2 = 0; 975 1.29 bouyer cp->cp_ctl3 = periph->periph_target << CP_C3_ID_SHIFT; 976 1.29 bouyer cp->cp_ctl3 |= chan->chan_channel << CP_C3_CHANNEL_SHIFT; 977 1.29 bouyer cp->cp_ctl4 = periph->periph_lun << CP_C4_LUN_SHIFT; 978 1.29 bouyer cp->cp_ctl4 |= CP_C4_DIS_PRI | CP_C4_IDENTIFY; 979 1.29 bouyer 980 1.29 bouyer if ((flags & XS_CTL_DATA_IN) != 0) 981 1.29 bouyer cp->cp_ctl0 |= CP_C0_DATA_IN; 982 1.29 bouyer if ((flags & XS_CTL_DATA_OUT) != 0) 983 1.29 bouyer cp->cp_ctl0 |= CP_C0_DATA_OUT; 984 1.29 bouyer if (sc->sc_hbaid[chan->chan_channel] == periph->periph_target) 985 1.29 bouyer cp->cp_ctl0 |= CP_C0_INTERPRET; 986 1.29 bouyer 987 1.79 andvar /* Synchronous xfers mustn't write-back through the cache. */ 988 1.29 bouyer if (xs->bp != NULL) 989 1.29 bouyer if ((xs->bp->b_flags & (B_ASYNC | B_READ)) == 0) 990 1.29 bouyer cp->cp_ctl2 |= CP_C2_NO_CACHE; 991 1.29 bouyer 992 1.29 bouyer cp->cp_senseaddr = 993 1.29 bouyer htobe32(sc->sc_dmamap->dm_segs[0].ds_addr + 994 1.29 bouyer CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense)); 995 1.1 ad 996 1.29 bouyer if (xs->datalen != 0) { 997 1.29 bouyer if (dpt_ccb_map(sc, ccb)) 998 1.29 bouyer break; 999 1.9 ad } else { 1000 1.29 bouyer cp->cp_dataaddr = 0; 1001 1.29 bouyer cp->cp_datalen = 0; 1002 1.1 ad } 1003 1.1 ad 1004 1.29 bouyer /* Sync up CCB and status packet. */ 1005 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 1006 1.29 bouyer CCB_OFF(sc, ccb), sizeof(struct dpt_ccb), 1007 1.29 bouyer BUS_DMASYNC_PREWRITE); 1008 1.29 bouyer bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff, 1009 1.29 bouyer sizeof(struct eata_sp), BUS_DMASYNC_PREREAD); 1010 1.1 ad 1011 1.44 perry /* 1012 1.29 bouyer * Start the command. 1013 1.29 bouyer */ 1014 1.29 bouyer if ((xs->xs_control & XS_CTL_POLL) != 0) 1015 1.44 perry ccb->ccb_flg |= CCB_PRIVATE; 1016 1.1 ad 1017 1.29 bouyer if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0)) { 1018 1.68 chs aprint_error_dev(sc->sc_dev, "dpt_cmd failed\n"); 1019 1.29 bouyer xs->error = XS_DRIVER_STUFFUP; 1020 1.29 bouyer if (xs->datalen != 0) 1021 1.29 bouyer dpt_ccb_unmap(sc, ccb); 1022 1.29 bouyer dpt_ccb_free(sc, ccb); 1023 1.29 bouyer break; 1024 1.29 bouyer } 1025 1.1 ad 1026 1.29 bouyer if ((xs->xs_control & XS_CTL_POLL) == 0) 1027 1.29 bouyer break; 1028 1.1 ad 1029 1.29 bouyer if (dpt_ccb_poll(sc, ccb)) { 1030 1.29 bouyer dpt_ccb_abort(sc, ccb); 1031 1.29 bouyer /* Wait for abort to complete... */ 1032 1.29 bouyer if (dpt_ccb_poll(sc, ccb)) 1033 1.29 bouyer dpt_ccb_abort(sc, ccb); 1034 1.44 perry } 1035 1.1 ad 1036 1.29 bouyer dpt_ccb_done(sc, ccb); 1037 1.29 bouyer break; 1038 1.1 ad 1039 1.29 bouyer case ADAPTER_REQ_GROW_RESOURCES: 1040 1.29 bouyer /* 1041 1.29 bouyer * Not supported, since we allocate the maximum number of 1042 1.29 bouyer * CCBs up front. 1043 1.29 bouyer */ 1044 1.29 bouyer break; 1045 1.1 ad 1046 1.29 bouyer case ADAPTER_REQ_SET_XFER_MODE: 1047 1.29 bouyer /* 1048 1.29 bouyer * This will be handled by the HBA itself, and we can't 1049 1.29 bouyer * modify that (ditto for tagged queueing). 1050 1.29 bouyer */ 1051 1.29 bouyer break; 1052 1.1 ad } 1053 1.1 ad } 1054 1.1 ad 1055 1.1 ad /* 1056 1.1 ad * Get inquiry data from the adapter. 1057 1.1 ad */ 1058 1.29 bouyer static void 1059 1.29 bouyer dpt_hba_inquire(struct dpt_softc *sc, struct eata_inquiry_data **ei) 1060 1.1 ad { 1061 1.1 ad struct dpt_ccb *ccb; 1062 1.1 ad struct eata_cp *cp; 1063 1.29 bouyer 1064 1.1 ad *ei = (struct eata_inquiry_data *)sc->sc_scr; 1065 1.1 ad 1066 1.1 ad /* Get a CCB and mark as private */ 1067 1.29 bouyer ccb = dpt_ccb_alloc(sc); 1068 1.1 ad ccb->ccb_flg |= CCB_PRIVATE; 1069 1.1 ad ccb->ccb_timeout = 200; 1070 1.1 ad 1071 1.29 bouyer /* Put all the arguments into the CCB. */ 1072 1.1 ad cp = &ccb->ccb_eata_cp; 1073 1.1 ad cp->cp_ccbid = ccb->ccb_id; 1074 1.1 ad cp->cp_senselen = sizeof(ccb->ccb_sense); 1075 1.29 bouyer cp->cp_senseaddr = 0; 1076 1.19 ad cp->cp_stataddr = htobe32(sc->sc_stppa); 1077 1.13 ad cp->cp_dataaddr = htobe32(sc->sc_scrpa); 1078 1.13 ad cp->cp_datalen = htobe32(sizeof(struct eata_inquiry_data)); 1079 1.19 ad cp->cp_ctl0 = CP_C0_DATA_IN | CP_C0_INTERPRET; 1080 1.19 ad cp->cp_ctl1 = 0; 1081 1.19 ad cp->cp_ctl2 = 0; 1082 1.19 ad cp->cp_ctl3 = sc->sc_hbaid[0] << CP_C3_ID_SHIFT; 1083 1.19 ad cp->cp_ctl4 = CP_C4_DIS_PRI | CP_C4_IDENTIFY; 1084 1.19 ad 1085 1.29 bouyer /* Put together the SCSI inquiry command. */ 1086 1.29 bouyer memset(&cp->cp_cdb_cmd, 0, 12); 1087 1.19 ad cp->cp_cdb_cmd = INQUIRY; 1088 1.19 ad cp->cp_cdb_len = sizeof(struct eata_inquiry_data); 1089 1.1 ad 1090 1.29 bouyer /* Sync up CCB, status packet and scratch area. */ 1091 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb), 1092 1.1 ad sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE); 1093 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff, 1094 1.1 ad sizeof(struct eata_sp), BUS_DMASYNC_PREREAD); 1095 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_scroff, 1096 1.1 ad sizeof(struct eata_inquiry_data), BUS_DMASYNC_PREREAD); 1097 1.1 ad 1098 1.29 bouyer /* Start the command and poll on completion. */ 1099 1.29 bouyer if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0)) 1100 1.68 chs panic("%s: dpt_cmd failed", device_xname(sc->sc_dev)); 1101 1.1 ad 1102 1.29 bouyer if (dpt_ccb_poll(sc, ccb)) 1103 1.68 chs panic("%s: inquiry timed out", device_xname(sc->sc_dev)); 1104 1.1 ad 1105 1.19 ad if (ccb->ccb_hba_status != SP_HBA_NO_ERROR || 1106 1.1 ad ccb->ccb_scsi_status != SCSI_OK) 1107 1.29 bouyer panic("%s: inquiry failed (hba:%02x scsi:%02x)", 1108 1.68 chs device_xname(sc->sc_dev), ccb->ccb_hba_status, 1109 1.29 bouyer ccb->ccb_scsi_status); 1110 1.29 bouyer 1111 1.29 bouyer /* Sync up the DMA map and free CCB, returning. */ 1112 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_scroff, 1113 1.1 ad sizeof(struct eata_inquiry_data), BUS_DMASYNC_POSTREAD); 1114 1.29 bouyer dpt_ccb_free(sc, ccb); 1115 1.33 ad } 1116 1.33 ad 1117 1.33 ad int 1118 1.54 christos dptopen(dev_t dev, int flag, int mode, struct lwp *l) 1119 1.33 ad { 1120 1.33 ad 1121 1.33 ad if (device_lookup(&dpt_cd, minor(dev)) == NULL) 1122 1.33 ad return (ENXIO); 1123 1.33 ad 1124 1.33 ad return (0); 1125 1.33 ad } 1126 1.33 ad 1127 1.33 ad int 1128 1.56 christos dptioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 1129 1.33 ad { 1130 1.33 ad struct dpt_softc *sc; 1131 1.33 ad int rv; 1132 1.33 ad 1133 1.62 tsutsui sc = device_lookup_private(&dpt_cd, minor(dev)); 1134 1.33 ad 1135 1.33 ad switch (cmd & 0xffff) { 1136 1.33 ad case DPT_SIGNATURE: 1137 1.75 riastrad memcpy(data, &dpt_sig, uimin(IOCPARM_LEN(cmd), sizeof(dpt_sig))); 1138 1.33 ad break; 1139 1.33 ad 1140 1.33 ad case DPT_CTRLINFO: 1141 1.33 ad dpt_ctlrinfo(sc, (struct dpt_eata_ctlrinfo *)data); 1142 1.33 ad break; 1143 1.33 ad 1144 1.33 ad case DPT_SYSINFO: 1145 1.33 ad dpt_sysinfo(sc, (struct dpt_sysinfo *)data); 1146 1.33 ad break; 1147 1.33 ad 1148 1.33 ad case DPT_BLINKLED: 1149 1.33 ad /* 1150 1.33 ad * XXX Don't know how to get this from EATA boards. I think 1151 1.33 ad * it involves waiting for a "DPT" sequence from HA_ERROR 1152 1.33 ad * and then reading one of the HA_ICMD registers. 1153 1.33 ad */ 1154 1.33 ad *(int *)data = 0; 1155 1.33 ad break; 1156 1.33 ad 1157 1.33 ad case DPT_EATAUSRCMD: 1158 1.55 elad rv = kauth_authorize_device_passthru(l->l_cred, dev, 1159 1.55 elad KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data); 1160 1.53 elad if (rv) 1161 1.53 elad return (rv); 1162 1.49 christos 1163 1.37 ad if (IOCPARM_LEN(cmd) < sizeof(struct eata_ucp)) { 1164 1.38 kleink DPRINTF(("%s: ucp %lu vs %lu bytes\n", 1165 1.68 chs device_xname(sc->sc_dev), IOCPARM_LEN(cmd), 1166 1.38 kleink (unsigned long int)sizeof(struct eata_ucp))); 1167 1.37 ad return (EINVAL); 1168 1.37 ad } 1169 1.37 ad 1170 1.66 rmind mutex_enter(&sc->sc_lock); 1171 1.45 christos rv = dpt_passthrough(sc, (struct eata_ucp *)data, l); 1172 1.66 rmind mutex_exit(&sc->sc_lock); 1173 1.33 ad 1174 1.33 ad return (rv); 1175 1.33 ad 1176 1.33 ad default: 1177 1.68 chs DPRINTF(("%s: unknown ioctl %lx\n", device_xname(sc->sc_dev), cmd)); 1178 1.33 ad return (ENOTTY); 1179 1.33 ad } 1180 1.33 ad 1181 1.33 ad return (0); 1182 1.33 ad } 1183 1.33 ad 1184 1.33 ad void 1185 1.33 ad dpt_ctlrinfo(struct dpt_softc *sc, struct dpt_eata_ctlrinfo *info) 1186 1.33 ad { 1187 1.33 ad 1188 1.33 ad memset(info, 0, sizeof(*info)); 1189 1.33 ad info->id = sc->sc_hbaid[0]; 1190 1.33 ad info->vect = sc->sc_isairq; 1191 1.33 ad info->base = sc->sc_isaport; 1192 1.33 ad info->qdepth = sc->sc_nccbs; 1193 1.33 ad info->sgsize = DPT_SG_SIZE * sizeof(struct eata_sg); 1194 1.33 ad info->heads = 16; 1195 1.33 ad info->sectors = 63; 1196 1.33 ad info->do_drive32 = 1; 1197 1.33 ad info->primary = 1; 1198 1.33 ad info->cpLength = sizeof(struct eata_cp); 1199 1.33 ad info->spLength = sizeof(struct eata_sp); 1200 1.33 ad info->drqNum = sc->sc_isadrq; 1201 1.33 ad } 1202 1.33 ad 1203 1.33 ad void 1204 1.33 ad dpt_sysinfo(struct dpt_softc *sc, struct dpt_sysinfo *info) 1205 1.33 ad { 1206 1.33 ad #ifdef i386 1207 1.33 ad int i, j; 1208 1.33 ad #endif 1209 1.33 ad 1210 1.33 ad memset(info, 0, sizeof(*info)); 1211 1.33 ad 1212 1.33 ad #ifdef i386 1213 1.33 ad outb (0x70, 0x12); 1214 1.33 ad i = inb(0x71); 1215 1.33 ad j = i >> 4; 1216 1.33 ad if (i == 0x0f) { 1217 1.33 ad outb (0x70, 0x19); 1218 1.33 ad j = inb (0x71); 1219 1.33 ad } 1220 1.33 ad info->drive0CMOS = j; 1221 1.33 ad 1222 1.33 ad j = i & 0x0f; 1223 1.33 ad if (i == 0x0f) { 1224 1.33 ad outb (0x70, 0x1a); 1225 1.33 ad j = inb (0x71); 1226 1.33 ad } 1227 1.33 ad info->drive1CMOS = j; 1228 1.33 ad info->processorFamily = dpt_sig.dsProcessorFamily; 1229 1.33 ad 1230 1.33 ad /* 1231 1.33 ad * Get the conventional memory size from CMOS. 1232 1.33 ad */ 1233 1.33 ad outb(0x70, 0x16); 1234 1.33 ad j = inb(0x71); 1235 1.33 ad j <<= 8; 1236 1.33 ad outb(0x70, 0x15); 1237 1.33 ad j |= inb(0x71); 1238 1.33 ad info->conventionalMemSize = j; 1239 1.33 ad 1240 1.33 ad /* 1241 1.33 ad * Get the extended memory size from CMOS. 1242 1.33 ad */ 1243 1.33 ad outb(0x70, 0x31); 1244 1.33 ad j = inb(0x71); 1245 1.33 ad j <<= 8; 1246 1.33 ad outb(0x70, 0x30); 1247 1.33 ad j |= inb(0x71); 1248 1.33 ad info->extendedMemSize = j; 1249 1.33 ad 1250 1.33 ad switch (cpu_class) { 1251 1.33 ad case CPUCLASS_386: 1252 1.33 ad info->processorType = PROC_386; 1253 1.33 ad break; 1254 1.33 ad case CPUCLASS_486: 1255 1.33 ad info->processorType = PROC_486; 1256 1.33 ad break; 1257 1.33 ad case CPUCLASS_586: 1258 1.33 ad info->processorType = PROC_PENTIUM; 1259 1.33 ad break; 1260 1.33 ad case CPUCLASS_686: 1261 1.33 ad default: 1262 1.33 ad info->processorType = PROC_SEXIUM; 1263 1.33 ad break; 1264 1.33 ad } 1265 1.33 ad 1266 1.33 ad info->flags = SI_CMOS_Valid | SI_BusTypeValid | 1267 1.33 ad SI_MemorySizeValid | SI_NO_SmartROM; 1268 1.33 ad #else 1269 1.33 ad info->flags = SI_BusTypeValid | SI_NO_SmartROM; 1270 1.33 ad #endif 1271 1.33 ad 1272 1.33 ad info->busType = sc->sc_bustype; 1273 1.33 ad } 1274 1.33 ad 1275 1.33 ad int 1276 1.45 christos dpt_passthrough(struct dpt_softc *sc, struct eata_ucp *ucp, struct lwp *l) 1277 1.33 ad { 1278 1.33 ad struct dpt_ccb *ccb; 1279 1.33 ad struct eata_sp sp; 1280 1.33 ad struct eata_cp *cp; 1281 1.33 ad struct eata_sg *sg; 1282 1.42 christos bus_dmamap_t xfer = 0; /* XXX: gcc */ 1283 1.33 ad bus_dma_segment_t *ds; 1284 1.42 christos int datain = 0, s, rv = 0, i, uslen; /* XXX: gcc */ 1285 1.33 ad 1286 1.33 ad /* 1287 1.33 ad * Get a CCB and fill. 1288 1.33 ad */ 1289 1.33 ad ccb = dpt_ccb_alloc(sc); 1290 1.33 ad ccb->ccb_flg |= CCB_PRIVATE | CCB_WAIT; 1291 1.33 ad ccb->ccb_timeout = 0; 1292 1.33 ad ccb->ccb_savesp = &sp; 1293 1.33 ad 1294 1.33 ad cp = &ccb->ccb_eata_cp; 1295 1.34 ad memcpy(cp, ucp->ucp_cp, sizeof(ucp->ucp_cp)); 1296 1.34 ad uslen = cp->cp_senselen; 1297 1.33 ad cp->cp_ccbid = ccb->ccb_id; 1298 1.33 ad cp->cp_senselen = sizeof(ccb->ccb_sense); 1299 1.33 ad cp->cp_senseaddr = htobe32(sc->sc_dmamap->dm_segs[0].ds_addr + 1300 1.33 ad CCB_OFF(sc, ccb) + offsetof(struct dpt_ccb, ccb_sense)); 1301 1.33 ad cp->cp_stataddr = htobe32(sc->sc_stppa); 1302 1.33 ad 1303 1.33 ad /* 1304 1.33 ad * Map data transfers. 1305 1.33 ad */ 1306 1.34 ad if (ucp->ucp_dataaddr && ucp->ucp_datalen) { 1307 1.33 ad xfer = ccb->ccb_dmamap_xfer; 1308 1.34 ad datain = ((cp->cp_ctl0 & CP_C0_DATA_IN) != 0); 1309 1.33 ad 1310 1.34 ad if (ucp->ucp_datalen > DPT_MAX_XFER) { 1311 1.68 chs DPRINTF(("%s: xfer too big\n", device_xname(sc->sc_dev))); 1312 1.33 ad dpt_ccb_free(sc, ccb); 1313 1.33 ad return (EFBIG); 1314 1.33 ad } 1315 1.33 ad rv = bus_dmamap_load(sc->sc_dmat, xfer, 1316 1.45 christos ucp->ucp_dataaddr, ucp->ucp_datalen, l->l_proc, 1317 1.33 ad BUS_DMA_WAITOK | BUS_DMA_STREAMING | 1318 1.33 ad (datain ? BUS_DMA_READ : BUS_DMA_WRITE)); 1319 1.33 ad if (rv != 0) { 1320 1.68 chs DPRINTF(("%s: map failed; %d\n", device_xname(sc->sc_dev), 1321 1.33 ad rv)); 1322 1.33 ad dpt_ccb_free(sc, ccb); 1323 1.33 ad return (rv); 1324 1.33 ad } 1325 1.33 ad 1326 1.33 ad bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize, 1327 1.33 ad (datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE)); 1328 1.33 ad 1329 1.33 ad sg = ccb->ccb_sg; 1330 1.33 ad ds = xfer->dm_segs; 1331 1.33 ad for (i = 0; i < xfer->dm_nsegs; i++, sg++, ds++) { 1332 1.33 ad sg->sg_addr = htobe32(ds->ds_addr); 1333 1.34 ad sg->sg_len = htobe32(ds->ds_len); 1334 1.33 ad } 1335 1.44 perry cp->cp_dataaddr = htobe32(CCB_OFF(sc, ccb) + 1336 1.33 ad sc->sc_dmamap->dm_segs[0].ds_addr + 1337 1.33 ad offsetof(struct dpt_ccb, ccb_sg)); 1338 1.33 ad cp->cp_datalen = htobe32(i * sizeof(struct eata_sg)); 1339 1.33 ad cp->cp_ctl0 |= CP_C0_SCATTER; 1340 1.33 ad } else { 1341 1.33 ad cp->cp_dataaddr = 0; 1342 1.33 ad cp->cp_datalen = 0; 1343 1.33 ad } 1344 1.33 ad 1345 1.33 ad /* 1346 1.33 ad * Start the command and sleep on completion. 1347 1.33 ad */ 1348 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb), 1349 1.33 ad sizeof(struct dpt_ccb), BUS_DMASYNC_PREWRITE); 1350 1.33 ad s = splbio(); 1351 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, sc->sc_stpoff, 1352 1.33 ad sizeof(struct eata_sp), BUS_DMASYNC_PREREAD); 1353 1.33 ad if (dpt_cmd(sc, ccb, CP_DMA_CMD, 0)) 1354 1.68 chs panic("%s: dpt_cmd failed", device_xname(sc->sc_dev)); 1355 1.33 ad tsleep(ccb, PWAIT, "dptucmd", 0); 1356 1.33 ad splx(s); 1357 1.33 ad 1358 1.33 ad /* 1359 1.33 ad * Sync up the DMA map and copy out results. 1360 1.33 ad */ 1361 1.44 perry bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, CCB_OFF(sc, ccb), 1362 1.33 ad sizeof(struct dpt_ccb), BUS_DMASYNC_POSTWRITE); 1363 1.33 ad 1364 1.33 ad if (cp->cp_datalen != 0) { 1365 1.33 ad bus_dmamap_sync(sc->sc_dmat, xfer, 0, xfer->dm_mapsize, 1366 1.33 ad (datain ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE)); 1367 1.33 ad bus_dmamap_unload(sc->sc_dmat, xfer); 1368 1.33 ad } 1369 1.33 ad 1370 1.34 ad if (ucp->ucp_stataddr != NULL) { 1371 1.34 ad rv = copyout(&sp, ucp->ucp_stataddr, sizeof(sp)); 1372 1.51 christos if (rv != 0) { 1373 1.33 ad DPRINTF(("%s: sp copyout() failed\n", 1374 1.68 chs device_xname(sc->sc_dev))); 1375 1.51 christos } 1376 1.33 ad } 1377 1.34 ad if (rv == 0 && ucp->ucp_senseaddr != NULL) { 1378 1.75 riastrad i = uimin(uslen, sizeof(ccb->ccb_sense)); 1379 1.34 ad rv = copyout(&ccb->ccb_sense, ucp->ucp_senseaddr, i); 1380 1.51 christos if (rv != 0) { 1381 1.33 ad DPRINTF(("%s: sense copyout() failed\n", 1382 1.68 chs device_xname(sc->sc_dev))); 1383 1.51 christos } 1384 1.33 ad } 1385 1.33 ad 1386 1.37 ad ucp->ucp_hstatus = (u_int8_t)ccb->ccb_hba_status; 1387 1.37 ad ucp->ucp_tstatus = (u_int8_t)ccb->ccb_scsi_status; 1388 1.33 ad dpt_ccb_free(sc, ccb); 1389 1.33 ad return (rv); 1390 1.1 ad } 1391