This source file includes following definitions.
- sili_attach
- sili_detach
- sili_port_intr
- sili_intr
- sili_ports_alloc
- sili_ports_free
- sili_ccb_alloc
- sili_ccb_free
- sili_get_ccb
- sili_put_ccb
- sili_dmamem_alloc
- sili_dmamem_free
- sili_read
- sili_write
- sili_pread
- sili_pwrite
- sili_pwait_eq
- sili_pwait_ne
- sili_post_direct
- sili_pread_fis
- sili_post_indirect
- sili_signature
- sili_ata_probe
- sili_ata_cmd
- sili_ata_cmd_done
- sili_ata_cmd_timeout
- sili_load
- sili_unload
- sili_poll
- sili_start
- sili_read_ncq_error
- sili_ata_get_xfer
- sili_ata_put_xfer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/buf.h>
22 #include <sys/device.h>
23 #include <sys/proc.h>
24 #include <sys/malloc.h>
25 #include <sys/kernel.h>
26
27 #include <machine/bus.h>
28
29 #include <dev/ata/atascsi.h>
30
31 #include <dev/ic/silireg.h>
32 #include <dev/ic/silivar.h>
33
34
35 #define NO_SILI_DEBUG
36
37 #ifdef SILI_DEBUG
38 #define SILI_D_VERBOSE (1<<0)
39 #define SILI_D_INTR (1<<1)
40
41 int silidebug = SILI_D_VERBOSE;
42
43 #define DPRINTF(m, a...) do { if ((m) & silidebug) printf(a); } while (0)
44 #else
45 #define DPRINTF(m, a...)
46 #endif
47
48 struct cfdriver sili_cd = {
49 NULL, "sili", DV_DULL
50 };
51
52
53 struct sili_dmamem {
54 bus_dmamap_t sdm_map;
55 bus_dma_segment_t sdm_seg;
56 size_t sdm_size;
57 caddr_t sdm_kva;
58 };
59 #define SILI_DMA_MAP(_sdm) ((_sdm)->sdm_map)
60 #define SILI_DMA_DVA(_sdm) ((_sdm)->sdm_map->dm_segs[0].ds_addr)
61 #define SILI_DMA_KVA(_sdm) ((void *)(_sdm)->sdm_kva)
62
63 struct sili_dmamem *sili_dmamem_alloc(struct sili_softc *, bus_size_t,
64 bus_size_t);
65 void sili_dmamem_free(struct sili_softc *,
66 struct sili_dmamem *);
67
68
69 struct sili_ccb;
70
71
72 #define SILI_SCRATCH_LEN 512
73
74 struct sili_port {
75 struct sili_softc *sp_sc;
76 bus_space_handle_t sp_ioh;
77
78 struct sili_ccb *sp_ccbs;
79 struct sili_dmamem *sp_cmds;
80 struct sili_dmamem *sp_scratch;
81
82 TAILQ_HEAD(, sili_ccb) sp_free_ccbs;
83
84 volatile u_int32_t sp_active;
85 TAILQ_HEAD(, sili_ccb) sp_active_ccbs;
86 TAILQ_HEAD(, sili_ccb) sp_deferred_ccbs;
87
88 #ifdef SILI_DEBUG
89 char sp_name[16];
90 #define PORTNAME(_sp) ((_sp)->sp_name)
91 #else
92 #define PORTNAME(_sp) DEVNAME((_sp)->sp_sc)
93 #endif
94 };
95
96 int sili_ports_alloc(struct sili_softc *);
97 void sili_ports_free(struct sili_softc *);
98
99
100
101
102
103
104
105 #define SILI_CMD_LEN 512
106
107
108
109
110
111
112
113
114 #define SILI_DMA_SEGS 22
115
116 struct sili_ccb {
117 struct ata_xfer ccb_xa;
118
119 void *ccb_cmd;
120 u_int64_t ccb_cmd_dva;
121 bus_dmamap_t ccb_dmamap;
122
123 struct sili_port *ccb_port;
124
125 TAILQ_ENTRY(sili_ccb) ccb_entry;
126 };
127
128 int sili_ccb_alloc(struct sili_port *);
129 void sili_ccb_free(struct sili_port *);
130 struct sili_ccb *sili_get_ccb(struct sili_port *);
131 void sili_put_ccb(struct sili_ccb *);
132
133
134 u_int32_t sili_read(struct sili_softc *, bus_size_t);
135 void sili_write(struct sili_softc *, bus_size_t, u_int32_t);
136 u_int32_t sili_pread(struct sili_port *, bus_size_t);
137 void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
138 int sili_pwait_eq(struct sili_port *, bus_size_t,
139 u_int32_t, u_int32_t, int);
140 int sili_pwait_ne(struct sili_port *, bus_size_t,
141 u_int32_t, u_int32_t, int);
142
143
144 void sili_post_direct(struct sili_port *, u_int,
145 void *, size_t buflen);
146 void sili_post_indirect(struct sili_port *,
147 struct sili_ccb *);
148 void sili_pread_fis(struct sili_port *, u_int,
149 struct ata_fis_d2h *);
150 u_int32_t sili_signature(struct sili_port *, u_int);
151 int sili_load(struct sili_ccb *, struct sili_sge *, int);
152 void sili_unload(struct sili_ccb *);
153 int sili_poll(struct sili_ccb *, int, void (*)(void *));
154 void sili_start(struct sili_port *, struct sili_ccb *);
155 int sili_read_ncq_error(struct sili_port *, int *);
156
157
158 u_int32_t sili_port_intr(struct sili_port *, int);
159
160
161 int sili_ata_probe(void *, int);
162 struct ata_xfer *sili_ata_get_xfer(void *, int);
163 void sili_ata_put_xfer(struct ata_xfer *);
164 int sili_ata_cmd(struct ata_xfer *);
165
166 struct atascsi_methods sili_atascsi_methods = {
167 sili_ata_probe,
168 sili_ata_get_xfer,
169 sili_ata_cmd
170 };
171
172
173 void sili_ata_cmd_done(struct sili_ccb *, int);
174 void sili_ata_cmd_timeout(void *);
175
176 int
177 sili_attach(struct sili_softc *sc)
178 {
179 struct atascsi_attach_args aaa;
180
181 printf("\n");
182
183 if (sili_ports_alloc(sc) != 0) {
184
185 return (1);
186 }
187
188
189 sili_write(sc, SILI_REG_GC, SILI_REG_GC_GR);
190 sili_write(sc, SILI_REG_GC, 0x0);
191
192 bzero(&aaa, sizeof(aaa));
193 aaa.aaa_cookie = sc;
194 aaa.aaa_methods = &sili_atascsi_methods;
195 aaa.aaa_minphys = minphys;
196 aaa.aaa_nports = sc->sc_nports;
197 aaa.aaa_ncmds = SILI_MAX_CMDS;
198 aaa.aaa_capability = ASAA_CAP_NCQ;
199
200 sc->sc_atascsi = atascsi_attach(&sc->sc_dev, &aaa);
201
202 return (0);
203 }
204
205 int
206 sili_detach(struct sili_softc *sc, int flags)
207 {
208 return (0);
209 }
210
211 u_int32_t
212 sili_port_intr(struct sili_port *sp, int timeout_slot)
213 {
214 u_int32_t is, pss_saved, pss_masked;
215 u_int32_t processed = 0, need_restart = 0;
216 int slot;
217 struct sili_ccb *ccb;
218
219 is = sili_pread(sp, SILI_PREG_IS);
220 pss_saved = sili_pread(sp, SILI_PREG_PSS);
221
222 #ifdef SILI_DEBUG
223 if ((pss_saved & SILI_PREG_PSS_ALL_SLOTS) != sp->sp_active ||
224 ((is >> 16) & ~SILI_PREG_IS_CMDCOMP)) {
225 DPRINTF(SILI_D_INTR, "%s: IS: 0x%08x (0x%b), PSS: %08x, "
226 "active: %08x\n", PORTNAME(sp), is, is >> 16, SILI_PFMT_IS,
227 pss_saved, sp->sp_active);
228 }
229 #endif
230
231
232 pss_saved &= SILI_PREG_PSS_ALL_SLOTS;
233
234 if (is & SILI_PREG_IS_CMDERR) {
235 int err_slot, err_code;
236 u_int32_t sactive = 0;
237
238 sili_pwrite(sp, SILI_PREG_IS, SILI_PREG_IS_CMDERR);
239 err_slot = SILI_PREG_PCS_ACTIVE(sili_pread(sp, SILI_PREG_PCS));
240 err_code = sili_pread(sp, SILI_PREG_CE);
241 ccb = &sp->sp_ccbs[err_slot];
242
243 switch (err_code) {
244 case SILI_PREG_CE_DEVICEERROR:
245 case SILI_PREG_CE_DATAFISERROR:
246
247 sili_pread_fis(sp, err_slot, &ccb->ccb_xa.rfis);
248 break;
249
250 case SILI_PREG_CE_SDBERROR:
251
252 sactive = sili_pread(sp, SILI_PREG_SACT);
253 if (sactive == 0)
254 break;
255
256
257 if (!sili_read_ncq_error(sp, &err_slot)) {
258
259 ccb = &sp->sp_ccbs[err_slot];
260 break;
261 }
262
263
264
265
266 default:
267
268 printf("%s: fatal error (%d), aborting active slots "
269 "(%08x) and resetting device.\n", PORTNAME(sp),
270 err_code, pss_saved);
271 while (pss_saved) {
272 slot = ffs(pss_saved) - 1;
273 pss_saved &= ~(1 << slot);
274
275 ccb = &sp->sp_ccbs[slot];
276 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
277 ccb->ccb_xa.state = ATA_S_ERROR;
278 }
279 need_restart = SILI_PREG_PCS_DEVRESET;
280 goto fatal;
281 }
282
283 DPRINTF(SILI_D_VERBOSE, "%s: %serror, code %d, slot %d, "
284 "active %08x\n", PORTNAME(sp), sactive ? "NCQ " : "",
285 err_code, err_slot, sp->sp_active);
286
287
288 pss_saved &= ~(1 << err_slot);
289
290 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
291 ccb->ccb_xa.state = ATA_S_ERROR;
292
293 need_restart = SILI_PREG_PCS_PORTINIT;
294 }
295 fatal:
296
297
298 if (timeout_slot >= 0 && (pss_saved & (1 << timeout_slot))) {
299 DPRINTF(SILI_D_VERBOSE, "%s: timing out slot %d, active %08x\n",
300 PORTNAME(sp), timeout_slot, sp->sp_active);
301
302
303 pss_saved &= ~(1 << timeout_slot);
304
305 ccb = &sp->sp_ccbs[timeout_slot];
306 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
307 ccb->ccb_xa.state = ATA_S_TIMEOUT;
308
309
310 need_restart = SILI_PREG_PCS_DEVRESET;
311 }
312
313
314 pss_masked = ~pss_saved & sp->sp_active;
315 while (pss_masked) {
316 slot = ffs(pss_masked) - 1;
317 ccb = &sp->sp_ccbs[slot];
318 pss_masked &= ~(1 << slot);
319
320 DPRINTF(SILI_D_INTR, "%s: slot %d is complete%s\n",
321 PORTNAME(sp), slot, ccb->ccb_xa.state == ATA_S_ERROR ?
322 " (error)" : (ccb->ccb_xa.state == ATA_S_TIMEOUT ?
323 " (timeout)" : ""));
324
325 sili_ata_cmd_done(ccb, need_restart);
326
327 processed |= 1 << slot;
328 }
329
330 if (need_restart) {
331
332 sili_pwrite(sp, SILI_PREG_PCS, need_restart);
333 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
334 SILI_PREG_PCS_PORTRDY, 1000)) {
335 printf("%s: couldn't restart port after error\n",
336 PORTNAME(sp));
337 }
338
339
340 pss_masked = pss_saved;
341 TAILQ_FOREACH(ccb, &sp->sp_active_ccbs, ccb_entry) {
342 DPRINTF(SILI_D_VERBOSE, "%s: restarting slot %d "
343 "after error, state %02x\n", PORTNAME(sp),
344 ccb->ccb_xa.tag, ccb->ccb_xa.state);
345 if (!(pss_masked & (1 << ccb->ccb_xa.tag))) {
346 panic("sili_intr: slot %d not active in "
347 "pss_masked: %08x, state %02x",
348 ccb->ccb_xa.tag, pss_masked,
349 ccb->ccb_xa.state);
350 }
351 pss_masked &= ~(1 << ccb->ccb_xa.tag);
352
353 KASSERT(ccb->ccb_xa.state == ATA_S_ONCHIP);
354 sili_post_indirect(sp, ccb);
355 }
356 KASSERT(pss_masked == 0);
357
358
359
360
361
362
363 while ((ccb = TAILQ_FIRST(&sp->sp_deferred_ccbs)) != NULL) {
364 TAILQ_REMOVE(&sp->sp_deferred_ccbs, ccb, ccb_entry);
365
366 KASSERT(ccb->ccb_xa.state == ATA_S_COMPLETE ||
367 ccb->ccb_xa.state == ATA_S_ERROR ||
368 ccb->ccb_xa.state == ATA_S_TIMEOUT);
369 ccb->ccb_xa.complete(&ccb->ccb_xa);
370 }
371 }
372
373 return (processed);
374 }
375
376 int
377 sili_intr(void *arg)
378 {
379 struct sili_softc *sc = arg;
380 u_int32_t is;
381 int port;
382
383 is = sili_read(sc, SILI_REG_GIS);
384 if (is == 0)
385 return (0);
386 sili_write(sc, SILI_REG_GIS, is);
387 DPRINTF(SILI_D_INTR, "sili_intr, GIS: %08x\n", is);
388
389 while (is & SILI_REG_GIS_PIS_MASK) {
390 port = ffs(is) - 1;
391 sili_port_intr(&sc->sc_ports[port], -1);
392 is &= ~(1 << port);
393 }
394
395 return (1);
396 }
397
398 int
399 sili_ports_alloc(struct sili_softc *sc)
400 {
401 struct sili_port *sp;
402 int i;
403
404 sc->sc_ports = malloc(sizeof(struct sili_port) * sc->sc_nports,
405 M_DEVBUF, M_WAITOK);
406 bzero(sc->sc_ports, sizeof(struct sili_port) * sc->sc_nports);
407
408 for (i = 0; i < sc->sc_nports; i++) {
409 sp = &sc->sc_ports[i];
410
411 sp->sp_sc = sc;
412 #ifdef SILI_DEBUG
413 snprintf(sp->sp_name, sizeof(sp->sp_name), "%s.%d",
414 DEVNAME(sc), i);
415 #endif
416 if (bus_space_subregion(sc->sc_iot_port, sc->sc_ioh_port,
417 SILI_PORT_OFFSET(i), SILI_PORT_SIZE, &sp->sp_ioh) != 0) {
418 printf("%s: unable to create register window "
419 "for port %d\n", DEVNAME(sc), i);
420 goto freeports;
421 }
422 }
423
424 return (0);
425
426 freeports:
427
428 free(sp, M_DEVBUF);
429 sc->sc_ports = NULL;
430 return (1);
431 }
432
433 void
434 sili_ports_free(struct sili_softc *sc)
435 {
436 struct sili_port *sp;
437 int i;
438
439 for (i = 0; i < sc->sc_nports; i++) {
440 sp = &sc->sc_ports[i];
441
442 if (sp->sp_ccbs != NULL)
443 sili_ccb_free(sp);
444 }
445
446
447 free(sc->sc_ports, M_DEVBUF);
448 sc->sc_ports = NULL;
449 }
450
451 int
452 sili_ccb_alloc(struct sili_port *sp)
453 {
454 struct sili_softc *sc = sp->sp_sc;
455 struct sili_ccb *ccb;
456 struct sili_prb *prb;
457 int i;
458
459 TAILQ_INIT(&sp->sp_free_ccbs);
460 TAILQ_INIT(&sp->sp_active_ccbs);
461 TAILQ_INIT(&sp->sp_deferred_ccbs);
462
463 sp->sp_ccbs = malloc(sizeof(struct sili_ccb) * SILI_MAX_CMDS,
464 M_DEVBUF, M_WAITOK);
465 sp->sp_cmds = sili_dmamem_alloc(sc, SILI_CMD_LEN * SILI_MAX_CMDS,
466 SILI_PRB_ALIGN);
467 if (sp->sp_cmds == NULL)
468 goto free_ccbs;
469 sp->sp_scratch = sili_dmamem_alloc(sc, SILI_SCRATCH_LEN, PAGE_SIZE);
470 if (sp->sp_scratch == NULL)
471 goto free_cmds;
472
473 bzero(sp->sp_ccbs, sizeof(struct sili_ccb) * SILI_MAX_CMDS);
474
475 for (i = 0; i < SILI_MAX_CMDS; i++) {
476 ccb = &sp->sp_ccbs[i];
477 ccb->ccb_port = sp;
478 ccb->ccb_cmd = SILI_DMA_KVA(sp->sp_cmds) + i * SILI_CMD_LEN;
479 ccb->ccb_cmd_dva = SILI_DMA_DVA(sp->sp_cmds) + i * SILI_CMD_LEN;
480 if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, SILI_DMA_SEGS,
481 MAXPHYS, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
482 &ccb->ccb_dmamap) != 0)
483 goto free_scratch;
484
485 prb = ccb->ccb_cmd;
486 ccb->ccb_xa.fis = (struct ata_fis_h2d *)&prb->fis;
487 ccb->ccb_xa.packetcmd = ((struct sili_prb_packet *)prb)->cdb;
488 ccb->ccb_xa.tag = i;
489 ccb->ccb_xa.ata_put_xfer = sili_ata_put_xfer;
490 ccb->ccb_xa.state = ATA_S_COMPLETE;
491
492 sili_put_ccb(ccb);
493 }
494
495 return (0);
496
497 free_scratch:
498 sili_dmamem_free(sc, sp->sp_scratch);
499 free_cmds:
500 sili_dmamem_free(sc, sp->sp_cmds);
501 free_ccbs:
502 sili_ccb_free(sp);
503 return (1);
504 }
505
506 void
507 sili_ccb_free(struct sili_port *sp)
508 {
509 struct sili_softc *sc = sp->sp_sc;
510 struct sili_ccb *ccb;
511
512 while ((ccb = sili_get_ccb(sp)) != NULL)
513 bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
514
515 free(sp->sp_ccbs, M_DEVBUF);
516 sp->sp_ccbs = NULL;
517 }
518
519 struct sili_ccb *
520 sili_get_ccb(struct sili_port *sp)
521 {
522 struct sili_ccb *ccb;
523
524 ccb = TAILQ_FIRST(&sp->sp_free_ccbs);
525 if (ccb != NULL) {
526 KASSERT(ccb->ccb_xa.state == ATA_S_PUT);
527 TAILQ_REMOVE(&sp->sp_free_ccbs, ccb, ccb_entry);
528 ccb->ccb_xa.state = ATA_S_SETUP;
529 }
530
531 return (ccb);
532 }
533
534 void
535 sili_put_ccb(struct sili_ccb *ccb)
536 {
537 struct sili_port *sp = ccb->ccb_port;
538
539 #ifdef DIAGNOSTIC
540 if (ccb->ccb_xa.state != ATA_S_COMPLETE &&
541 ccb->ccb_xa.state != ATA_S_TIMEOUT &&
542 ccb->ccb_xa.state != ATA_S_ERROR) {
543 printf("%s: invalid ata_xfer state %02x in sili_put_ccb, "
544 "slot %d\n", PORTNAME(sp), ccb->ccb_xa.state,
545 ccb->ccb_xa.tag);
546 }
547 #endif
548
549 ccb->ccb_xa.state = ATA_S_PUT;
550 TAILQ_INSERT_TAIL(&sp->sp_free_ccbs, ccb, ccb_entry);
551 }
552
553 struct sili_dmamem *
554 sili_dmamem_alloc(struct sili_softc *sc, bus_size_t size, bus_size_t align)
555 {
556 struct sili_dmamem *sdm;
557 int nsegs;
558
559 sdm = malloc(sizeof(struct sili_dmamem), M_DEVBUF, M_WAITOK);
560 bzero(sdm, sizeof(struct sili_dmamem));
561 sdm->sdm_size = size;
562
563 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
564 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &sdm->sdm_map) != 0)
565 goto sdmfree;
566
567 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &sdm->sdm_seg,
568 1, &nsegs, BUS_DMA_NOWAIT) != 0)
569 goto destroy;
570
571 if (bus_dmamem_map(sc->sc_dmat, &sdm->sdm_seg, nsegs, size,
572 &sdm->sdm_kva, BUS_DMA_NOWAIT) != 0)
573 goto free;
574
575 if (bus_dmamap_load(sc->sc_dmat, sdm->sdm_map, sdm->sdm_kva, size,
576 NULL, BUS_DMA_NOWAIT) != 0)
577 goto unmap;
578
579 bzero(sdm->sdm_kva, size);
580
581 return (sdm);
582
583 unmap:
584 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, size);
585 free:
586 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
587 destroy:
588 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
589 sdmfree:
590 free(sdm, M_DEVBUF);
591
592 return (NULL);
593 }
594
595 void
596 sili_dmamem_free(struct sili_softc *sc, struct sili_dmamem *sdm)
597 {
598 bus_dmamap_unload(sc->sc_dmat, sdm->sdm_map);
599 bus_dmamem_unmap(sc->sc_dmat, sdm->sdm_kva, sdm->sdm_size);
600 bus_dmamem_free(sc->sc_dmat, &sdm->sdm_seg, 1);
601 bus_dmamap_destroy(sc->sc_dmat, sdm->sdm_map);
602 free(sdm, M_DEVBUF);
603 }
604
605 u_int32_t
606 sili_read(struct sili_softc *sc, bus_size_t r)
607 {
608 u_int32_t rv;
609
610 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
611 BUS_SPACE_BARRIER_READ);
612 rv = bus_space_read_4(sc->sc_iot_global, sc->sc_ioh_global, r);
613
614 return (rv);
615 }
616
617 void
618 sili_write(struct sili_softc *sc, bus_size_t r, u_int32_t v)
619 {
620 bus_space_write_4(sc->sc_iot_global, sc->sc_ioh_global, r, v);
621 bus_space_barrier(sc->sc_iot_global, sc->sc_ioh_global, r, 4,
622 BUS_SPACE_BARRIER_WRITE);
623 }
624
625 u_int32_t
626 sili_pread(struct sili_port *sp, bus_size_t r)
627 {
628 u_int32_t rv;
629
630 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
631 BUS_SPACE_BARRIER_READ);
632 rv = bus_space_read_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r);
633
634 return (rv);
635 }
636
637 void
638 sili_pwrite(struct sili_port *sp, bus_size_t r, u_int32_t v)
639 {
640 bus_space_write_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, v);
641 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, 4,
642 BUS_SPACE_BARRIER_WRITE);
643 }
644
645 int
646 sili_pwait_eq(struct sili_port *sp, bus_size_t r, u_int32_t mask,
647 u_int32_t value, int timeout)
648 {
649 while ((sili_pread(sp, r) & mask) != value) {
650 if (timeout == 0)
651 return (0);
652
653 delay(1000);
654 timeout--;
655 }
656
657 return (1);
658 }
659
660 int
661 sili_pwait_ne(struct sili_port *sp, bus_size_t r, u_int32_t mask,
662 u_int32_t value, int timeout)
663 {
664 while ((sili_pread(sp, r) & mask) == value) {
665 if (timeout == 0)
666 return (0);
667
668 delay(1000);
669 timeout--;
670 }
671
672 return (1);
673 }
674
675 void
676 sili_post_direct(struct sili_port *sp, u_int slot, void *buf, size_t buflen)
677 {
678 bus_size_t r = SILI_PREG_SLOT(slot);
679
680 #ifdef DIAGNOSTIC
681 if (buflen != 64 && buflen != 128)
682 panic("sili_pcopy: buflen of %d is not 64 or 128", buflen);
683 #endif
684
685 bus_space_write_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
686 buf, buflen);
687 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r, buflen,
688 BUS_SPACE_BARRIER_WRITE);
689
690 sili_pwrite(sp, SILI_PREG_FIFO, slot);
691 }
692
693 void
694 sili_pread_fis(struct sili_port *sp, u_int slot, struct ata_fis_d2h *fis)
695 {
696 bus_size_t r = SILI_PREG_SLOT(slot) + 8;
697
698 bus_space_barrier(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
699 sizeof(struct ata_fis_d2h), BUS_SPACE_BARRIER_READ);
700 bus_space_read_raw_region_4(sp->sp_sc->sc_iot_port, sp->sp_ioh, r,
701 fis, sizeof(struct ata_fis_d2h));
702 }
703
704 void
705 sili_post_indirect(struct sili_port *sp, struct sili_ccb *ccb)
706 {
707 sili_pwrite(sp, SILI_PREG_CAR_LO(ccb->ccb_xa.tag),
708 (u_int32_t)ccb->ccb_cmd_dva);
709 sili_pwrite(sp, SILI_PREG_CAR_HI(ccb->ccb_xa.tag),
710 (u_int32_t)(ccb->ccb_cmd_dva >> 32));
711 }
712
713 u_int32_t
714 sili_signature(struct sili_port *sp, u_int slot)
715 {
716 u_int32_t sig_hi, sig_lo;
717
718 sig_hi = sili_pread(sp, SILI_PREG_SIG_HI(slot));
719 sig_hi <<= SILI_PREG_SIG_HI_SHIFT;
720 sig_lo = sili_pread(sp, SILI_PREG_SIG_LO(slot));
721 sig_lo &= SILI_PREG_SIG_LO_MASK;
722
723 return (sig_hi | sig_lo);
724 }
725
726 int
727 sili_ata_probe(void *xsc, int port)
728 {
729 struct sili_softc *sc = xsc;
730 struct sili_port *sp = &sc->sc_ports[port];
731 struct sili_prb_softreset sreset;
732 u_int32_t signature;
733 int port_type;
734
735 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_PORTRESET);
736 sili_pwrite(sp, SILI_PREG_PCC, SILI_PREG_PCC_A32B);
737
738 if (!sili_pwait_eq(sp, SILI_PREG_SSTS, SATA_SStatus_DET,
739 SATA_SStatus_DET_DEV, 1000))
740 return (ATA_PORT_T_NONE);
741
742 DPRINTF(SILI_D_VERBOSE, "%s: SSTS 0x%08x\n", PORTNAME(sp),
743 sili_pread(sp, SILI_PREG_SSTS));
744
745 bzero(&sreset, sizeof(sreset));
746 sreset.control = htole16(SILI_PRB_SOFT_RESET | SILI_PRB_INTERRUPT_MASK);
747
748
749
750 sili_post_direct(sp, 0, &sreset, sizeof(sreset));
751 if (!sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000)) {
752 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for soft "
753 "reset\n", PORTNAME(sp));
754 return (ATA_PORT_T_NONE);
755 }
756
757
758 signature = sili_signature(sp, 0);
759
760 DPRINTF(SILI_D_VERBOSE, "%s: signature 0x%08x\n", PORTNAME(sp),
761 signature);
762
763 switch (signature) {
764 case SATA_SIGNATURE_DISK:
765 port_type = ATA_PORT_T_DISK;
766 break;
767 case SATA_SIGNATURE_ATAPI:
768 port_type = ATA_PORT_T_ATAPI;
769 break;
770 case SATA_SIGNATURE_PORT_MULTIPLIER:
771 default:
772 return (ATA_PORT_T_NONE);
773 }
774
775
776 if (sili_ccb_alloc(sp) != 0)
777 return (ATA_PORT_T_NONE);
778
779
780 sili_write(sc, SILI_REG_GC, sili_read(sc, SILI_REG_GC) | 1 << port);
781 sili_pwrite(sp, SILI_PREG_IES, SILI_PREG_IE_CMDERR |
782 SILI_PREG_IE_CMDCOMP);
783
784 return (port_type);
785 }
786
787 int
788 sili_ata_cmd(struct ata_xfer *xa)
789 {
790 struct sili_ccb *ccb = (struct sili_ccb *)xa;
791 struct sili_port *sp = ccb->ccb_port;
792 struct sili_softc *sc = sp->sp_sc;
793 struct sili_prb_ata *ata;
794 struct sili_prb_packet *atapi;
795 struct sili_sge *sgl;
796 int sgllen;
797 int s;
798
799 KASSERT(xa->state == ATA_S_SETUP);
800
801 if (xa->flags & ATA_F_PACKET) {
802 atapi = ccb->ccb_cmd;
803
804 if (xa->flags & ATA_F_WRITE)
805 atapi->control = htole16(SILI_PRB_PACKET_WRITE);
806 else
807 atapi->control = htole16(SILI_PRB_PACKET_READ);
808
809 sgl = atapi->sgl;
810 sgllen = sizeofa(atapi->sgl);
811 } else {
812 ata = ccb->ccb_cmd;
813
814 ata->control = 0;
815
816 sgl = ata->sgl;
817 sgllen = sizeofa(ata->sgl);
818 }
819
820 if (sili_load(ccb, sgl, sgllen) != 0)
821 goto failcmd;
822
823 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
824 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_PREWRITE);
825
826 timeout_set(&xa->stimeout, sili_ata_cmd_timeout, ccb);
827
828 xa->state = ATA_S_PENDING;
829
830 if (xa->flags & ATA_F_POLL) {
831 sili_poll(ccb, xa->timeout, sili_ata_cmd_timeout);
832 return (ATA_COMPLETE);
833 }
834
835 timeout_add(&xa->stimeout, (xa->timeout * hz) / 1000);
836
837 s = splbio();
838 sili_start(sp, ccb);
839 splx(s);
840 return (ATA_QUEUED);
841
842 failcmd:
843 s = splbio();
844 xa->state = ATA_S_ERROR;
845 xa->complete(xa);
846 splx(s);
847 return (ATA_ERROR);
848 }
849
850 void
851 sili_ata_cmd_done(struct sili_ccb *ccb, int defer_completion)
852 {
853 struct sili_port *sp = ccb->ccb_port;
854 struct sili_softc *sc = sp->sp_sc;
855 struct ata_xfer *xa = &ccb->ccb_xa;
856
857 splassert(IPL_BIO);
858
859 timeout_del(&xa->stimeout);
860
861 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_cmds),
862 xa->tag * SILI_CMD_LEN, SILI_CMD_LEN, BUS_DMASYNC_POSTWRITE);
863
864 sili_unload(ccb);
865
866 TAILQ_REMOVE(&sp->sp_active_ccbs, ccb, ccb_entry);
867 sp->sp_active &= ~(1 << xa->tag);
868
869 if (xa->state == ATA_S_ONCHIP)
870 xa->state = ATA_S_COMPLETE;
871 #ifdef DIAGNOSTIC
872 else if (xa->state != ATA_S_ERROR && xa->state != ATA_S_TIMEOUT)
873 printf("%s: invalid ata_xfer state %02x in sili_ata_cmd_done, "
874 "slot %d\n", PORTNAME(sp), xa->state, xa->tag);
875 #endif
876 if (defer_completion)
877 TAILQ_INSERT_TAIL(&sp->sp_deferred_ccbs, ccb, ccb_entry);
878 else if (xa->state == ATA_S_COMPLETE)
879 xa->complete(xa);
880 #ifdef DIAGNOSTIC
881 else
882 printf("%s: completion not deferred, but xa->state is %02x?\n",
883 PORTNAME(sp), xa->state);
884 #endif
885 }
886
887 void
888 sili_ata_cmd_timeout(void *xccb)
889 {
890 struct sili_ccb *ccb = xccb;
891 struct sili_port *sp = ccb->ccb_port;
892 int s;
893
894 s = splbio();
895 sili_port_intr(sp, ccb->ccb_xa.tag);
896 splx(s);
897 }
898
899 int
900 sili_load(struct sili_ccb *ccb, struct sili_sge *sgl, int sgllen)
901 {
902 struct sili_port *sp = ccb->ccb_port;
903 struct sili_softc *sc = sp->sp_sc;
904 struct ata_xfer *xa = &ccb->ccb_xa;
905 struct sili_sge *nsge = sgl, *ce = NULL;
906 bus_dmamap_t dmap = ccb->ccb_dmamap;
907 u_int64_t addr;
908 int error;
909 int i;
910
911 if (xa->datalen == 0)
912 return (0);
913
914 error = bus_dmamap_load(sc->sc_dmat, dmap, xa->data, xa->datalen, NULL,
915 (xa->flags & ATA_F_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
916 if (error != 0) {
917 printf("%s: error %d loading dmamap\n", PORTNAME(sp), error);
918 return (1);
919 }
920
921 if (dmap->dm_nsegs > sgllen)
922 ce = &sgl[sgllen - 1];
923
924 for (i = 0; i < dmap->dm_nsegs; i++) {
925 if (nsge == ce) {
926 nsge++;
927
928 addr = ccb->ccb_cmd_dva;
929 addr += ((u_int8_t *)nsge - (u_int8_t *)ccb->ccb_cmd);
930
931 ce->addr_lo = htole32((u_int32_t)addr);
932 ce->addr_hi = htole32((u_int32_t)(addr >> 32));
933 ce->flags = htole32(SILI_SGE_LNK);
934
935 if ((dmap->dm_nsegs - i) > SILI_SGT_SGLLEN)
936 ce += SILI_SGT_SGLLEN;
937 else
938 ce = NULL;
939 }
940
941 sgl = nsge;
942
943 addr = dmap->dm_segs[i].ds_addr;
944 sgl->addr_lo = htole32((u_int32_t)addr);
945 sgl->addr_hi = htole32((u_int32_t)(addr >> 32));
946 sgl->data_count = htole32(dmap->dm_segs[i].ds_len);
947 sgl->flags = 0;
948
949 nsge++;
950 }
951 sgl->flags |= htole32(SILI_SGE_TRM);
952
953 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
954 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_PREREAD :
955 BUS_DMASYNC_PREWRITE);
956
957 return (0);
958 }
959
960 void
961 sili_unload(struct sili_ccb *ccb)
962 {
963 struct sili_port *sp = ccb->ccb_port;
964 struct sili_softc *sc = sp->sp_sc;
965 struct ata_xfer *xa = &ccb->ccb_xa;
966 bus_dmamap_t dmap = ccb->ccb_dmamap;
967
968 if (xa->datalen == 0)
969 return;
970
971 bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
972 (xa->flags & ATA_F_READ) ? BUS_DMASYNC_POSTREAD :
973 BUS_DMASYNC_POSTWRITE);
974 bus_dmamap_unload(sc->sc_dmat, dmap);
975
976 if (xa->flags & ATA_F_READ)
977 xa->resid = xa->datalen - sili_pread(sp,
978 SILI_PREG_RX_COUNT(xa->tag));
979 else
980 xa->resid = 0;
981 }
982
983 int
984 sili_poll(struct sili_ccb *ccb, int timeout, void (*timeout_fn)(void *))
985 {
986 struct sili_port *sp = ccb->ccb_port;
987 int s;
988
989 s = splbio();
990 sili_start(sp, ccb);
991 do {
992 if (sili_port_intr(sp, -1) & (1 << ccb->ccb_xa.tag)) {
993 splx(s);
994 return (0);
995 }
996
997 delay(1000);
998 } while (--timeout > 0);
999
1000
1001 if (timeout_fn != NULL)
1002 timeout_fn(ccb);
1003
1004 splx(s);
1005
1006 return (1);
1007 }
1008
1009 void
1010 sili_start(struct sili_port *sp, struct sili_ccb *ccb)
1011 {
1012 int slot = ccb->ccb_xa.tag;
1013
1014 splassert(IPL_BIO);
1015 KASSERT(ccb->ccb_xa.state == ATA_S_PENDING);
1016
1017 TAILQ_INSERT_TAIL(&sp->sp_active_ccbs, ccb, ccb_entry);
1018 sp->sp_active |= 1 << slot;
1019 ccb->ccb_xa.state = ATA_S_ONCHIP;
1020
1021 sili_post_indirect(sp, ccb);
1022 }
1023
1024 int
1025 sili_read_ncq_error(struct sili_port *sp, int *err_slotp)
1026 {
1027 struct sili_softc *sc = sp->sp_sc;
1028 struct sili_prb_ata read_10h;
1029 u_int64_t addr;
1030 struct ata_fis_h2d *fis;
1031 struct ata_log_page_10h *log;
1032 struct sili_ccb *ccb;
1033 int rc;
1034
1035 sili_pwrite(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTINIT);
1036 if (!sili_pwait_eq(sp, SILI_PREG_PCS, SILI_PREG_PCS_PORTRDY,
1037 SILI_PREG_PCS_PORTRDY, 1000)) {
1038 printf("%s: couldn't ready port during log page read\n",
1039 PORTNAME(sp));
1040 return (1);
1041 }
1042
1043
1044 bzero(&read_10h, sizeof(read_10h));
1045 read_10h.control = htole16(SILI_PRB_INTERRUPT_MASK);
1046
1047 addr = SILI_DMA_DVA(sp->sp_scratch);
1048 read_10h.sgl[0].addr_lo = htole32((u_int32_t)addr);
1049 read_10h.sgl[0].addr_hi = htole32((u_int32_t)(addr >> 32));
1050 read_10h.sgl[0].data_count = htole32(512);
1051 read_10h.sgl[0].flags = htole32(SILI_SGE_TRM);
1052
1053 fis = (struct ata_fis_h2d *)read_10h.fis;
1054 fis->type = ATA_FIS_TYPE_H2D;
1055 fis->flags = ATA_H2D_FLAGS_CMD;
1056 fis->command = ATA_C_READ_LOG_EXT;
1057 fis->lba_low = 0x10;
1058 fis->sector_count = 1;
1059 fis->sector_count_exp = 0;
1060 fis->lba_mid = 0;
1061 fis->lba_mid_exp = 0;
1062 fis->device = 0;
1063
1064 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
1065 512, BUS_DMASYNC_PREREAD);
1066
1067
1068 sili_post_direct(sp, 0, &read_10h, sizeof(read_10h));
1069 rc = sili_pwait_eq(sp, SILI_PREG_PSS, (1 << 0), 0, 1000);
1070
1071 bus_dmamap_sync(sc->sc_dmat, SILI_DMA_MAP(sp->sp_scratch), 0,
1072 512, BUS_DMASYNC_POSTREAD);
1073
1074 if (!rc) {
1075 DPRINTF(SILI_D_VERBOSE, "%s: timed out while waiting for log "
1076 "page read\n", PORTNAME(sp));
1077 return (1);
1078 }
1079
1080
1081 log = (struct ata_log_page_10h *)SILI_DMA_KVA(sp->sp_scratch);
1082 if (ISSET(log->err_regs.type, ATA_LOG_10H_TYPE_NOTQUEUED)) {
1083
1084 printf("%s: read NCQ error page, but not an NCQ error?\n",
1085 PORTNAME(sp));
1086 return (1);
1087 }
1088
1089
1090 *err_slotp = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK;
1091
1092 ccb = &sp->sp_ccbs[*err_slotp];
1093 memcpy(&ccb->ccb_xa.rfis, &log->err_regs, sizeof(struct ata_fis_d2h));
1094 ccb->ccb_xa.rfis.type = ATA_FIS_TYPE_D2H;
1095 ccb->ccb_xa.rfis.flags = 0;
1096
1097 return (0);
1098 }
1099
1100 struct ata_xfer *
1101 sili_ata_get_xfer(void *xsc, int port)
1102 {
1103 struct sili_softc *sc = xsc;
1104 struct sili_port *sp = &sc->sc_ports[port];
1105 struct sili_ccb *ccb;
1106
1107 ccb = sili_get_ccb(sp);
1108 if (ccb == NULL) {
1109 printf("sili_ata_get_xfer: NULL ccb\n");
1110 return (NULL);
1111 }
1112
1113 bzero(ccb->ccb_cmd, SILI_CMD_LEN);
1114
1115 return ((struct ata_xfer *)ccb);
1116 }
1117
1118 void
1119 sili_ata_put_xfer(struct ata_xfer *xa)
1120 {
1121 struct sili_ccb *ccb = (struct sili_ccb *)xa;
1122
1123 sili_put_ccb(ccb);
1124 }