Home | History | Annotate | Download | only in pci

Lines Matching defs:amr

1 /*	$NetBSD: amr.c,v 1.68 2024/02/02 22:00:33 andvar Exp $	*/
59 * from FreeBSD: amr.c,v 1.16 2000/08/30 07:52:40 msmith Exp
67 __KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.68 2024/02/02 22:00:33 andvar Exp $");
122 CFATTACH_DECL3_NEW(amr, sizeof(struct amr_softc),
203 amr_inb(struct amr_softc *amr, int off)
205 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1,
207 return (bus_space_read_1(amr->amr_iot, amr->amr_ioh, off));
211 amr_inl(struct amr_softc *amr, int off)
213 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4,
215 return (bus_space_read_4(amr->amr_iot, amr->amr_ioh, off));
219 amr_outb(struct amr_softc *amr, int off, u_int8_t val)
221 bus_space_write_1(amr->amr_iot, amr->amr_ioh, off, val);
222 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1,
227 amr_outl(struct amr_softc *amr, int off, u_int32_t val)
229 bus_space_write_4(amr->amr_iot, amr->amr_ioh, off, val);
230 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4,
276 struct amr_softc *amr;
287 amr = device_private(self);
288 amr->amr_dv = self;
290 mutex_init(&amr->amr_mutex, MUTEX_DEFAULT, IPL_BIO);
317 &amr->amr_iot, &amr->amr_ioh, NULL, &amr->amr_ios) == 0)
320 &amr->amr_iot, &amr->amr_ioh, NULL, &amr->amr_ios) == 0)
324 amr_teardown(amr);
328 amr->amr_flags |= AMRF_PCI_REGS;
329 amr->amr_dmat = pa->pa_dmat;
330 amr->amr_pc = pa->pa_pc;
340 amr_teardown(amr);
344 amr->amr_ih = pci_intr_establish_xname(pc, ih, IPL_BIO, amr_intr, amr,
346 if (amr->amr_ih == NULL) {
351 amr_teardown(amr);
354 amr->amr_flags |= AMRF_PCI_INTR;
366 amr->amr_dmasize = size;
368 if ((rv = bus_dmamem_alloc(amr->amr_dmat, size, PAGE_SIZE, 0,
369 &amr->amr_dmaseg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
370 aprint_error_dev(amr->amr_dv,
372 amr_teardown(amr);
375 amr->amr_flags |= AMRF_DMA_ALLOC;
377 if ((rv = bus_dmamem_map(amr->amr_dmat, &amr->amr_dmaseg, rseg, size,
378 (void **)&amr->amr_mbox,
380 aprint_error_dev(amr->amr_dv, "unable to map buffer, rv = %d\n",
382 amr_teardown(amr);
385 amr->amr_flags |= AMRF_DMA_MAP;
387 if ((rv = bus_dmamap_create(amr->amr_dmat, size, 1, size, 0,
388 BUS_DMA_NOWAIT, &amr->amr_dmamap)) != 0) {
389 aprint_error_dev(amr->amr_dv,
391 amr_teardown(amr);
394 amr->amr_flags |= AMRF_DMA_CREATE;
396 if ((rv = bus_dmamap_load(amr->amr_dmat, amr->amr_dmamap,
397 amr->amr_mbox, size, NULL, BUS_DMA_NOWAIT)) != 0) {
398 aprint_error_dev(amr->amr_dv,
400 amr_teardown(amr);
403 amr->amr_flags |= AMRF_DMA_LOAD;
405 memset(amr->amr_mbox, 0, size);
407 amr->amr_mbox_paddr = amr->amr_dmamap->dm_segs[0].ds_addr;
408 amr->amr_sgls_paddr = (amr->amr_mbox_paddr + 0x1fff) & ~0x1fff;
409 amr->amr_sgls = (struct amr_sgentry *)((char *)amr->amr_mbox +
410 amr->amr_sgls_paddr - amr->amr_dmamap->dm_segs[0].ds_addr);
416 amr->amr_ccbs = ac;
417 SLIST_INIT(&amr->amr_ccb_freelist);
418 TAILQ_INIT(&amr->amr_ccb_active);
419 amr->amr_flags |= AMRF_CCBS;
427 rv = bus_dmamap_create(amr->amr_dmat, amr_max_xfer,
436 amr_ccb_free(amr, ac);
439 aprint_error_dev(amr->amr_dv, "memory exhausted\n");
440 amr_teardown(amr);
448 amr->amr_submit = amr_quartz_submit;
449 amr->amr_get_work = amr_quartz_get_work;
451 amr->amr_submit = amr_std_submit;
452 amr->amr_get_work = amr_std_get_work;
455 amr_outl(amr, AMR_SREG_MBOX, (u_int32_t)amr->amr_mbox_paddr + 16);
456 amr_outb(amr, AMR_SREG_MBOX_ENABLE, AMR_SMBOX_ENABLE_ADDR);
459 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_ACKINTR);
460 amr_outb(amr, AMR_SREG_TOGL,
461 amr_inb(amr, AMR_SREG_TOGL) | AMR_STOGL_ENABLE);
467 amr->amr_enqbuf = malloc(AMR_ENQUIRY_BUFSIZE, M_DEVBUF, M_WAITOK);
468 amr->amr_flags |= AMRF_ENQBUF;
469 amr->amr_maxqueuecnt = i;
471 if (amr_init(amr, intrstr, pa) != 0) {
472 amr_teardown(amr);
481 amr->amr_maxqueuecnt = uimin(amr->amr_maxqueuecnt, AMR_MAX_CMDS);
482 if (amr->amr_maxqueuecnt > i)
483 amr->amr_maxqueuecnt = i;
492 SIMPLEQ_INIT(&amr->amr_ccb_queue);
499 amr_std_thread, amr, &amr->amr_thread,
500 "%s", device_xname(amr->amr_dv));
503 amr_quartz_thread, amr, &amr->amr_thread,
504 "%s", device_xname(amr->amr_dv));
507 aprint_error_dev(amr->amr_dv, "unable to create thread (%d)",
510 amr->amr_flags |= AMRF_THREAD;
519 struct amr_softc *amr;
521 amr = device_private(self);
522 for (j = 0; j < amr->amr_numdrives; j++) {
523 if (amr->amr_drive[j].al_dv)
525 if (amr->amr_drive[j].al_size == 0)
531 amr->amr_drive[j].al_dv =
532 config_found(amr->amr_dv, &amra, amr_print,
544 amr_teardown(struct amr_softc *amr)
549 fl = amr->amr_flags;
552 amr->amr_flags |= AMRF_THREAD_EXIT;
556 while ((amr->amr_flags & AMRF_THREAD_EXIT) != 0) {
563 SLIST_FOREACH(ac, &amr->amr_ccb_freelist, ac_chain.slist) {
564 bus_dmamap_destroy(amr->amr_dmat, ac->ac_xfer_map);
566 free(amr->amr_ccbs, M_DEVBUF);
569 free(amr->amr_enqbuf, M_DEVBUF);
571 bus_dmamap_unload(amr->amr_dmat, amr->amr_dmamap);
573 bus_dmamem_unmap(amr->amr_dmat, (void *)amr->amr_mbox,
574 amr->amr_dmasize);
576 bus_dmamem_free(amr->amr_dmat, &amr->amr_dmaseg, 1);
578 bus_dmamap_destroy(amr->amr_dmat, amr->amr_dmamap);
580 pci_intr_disestablish(amr->amr_pc, amr->amr_ih);
582 bus_space_unmap(amr->amr_iot, amr->amr_ioh, amr->amr_ios);
605 amr_init(struct amr_softc *amr, const char *intrstr,
620 ap = amr_enquire(amr, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0,
621 amr->amr_enqbuf);
625 aprint_normal_dev(amr->amr_dv, "interrupting at %s\n",
627 aprint_normal_dev(amr->amr_dv,
631 amr->amr_maxqueuecnt = ap->ap_maxio;
636 aex = amr_enquire(amr, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
637 AMR_CONFIG_ENQ3_SOLICITED_FULL, amr->amr_enqbuf);
639 aprint_error_dev(amr->amr_dv, "ENQUIRY3 failed\n");
644 aprint_error_dev(amr->amr_dv, "Inquiry returned more "
651 aprint_error_dev(amr->amr_dv,
653 AMR_MAX_UNITS, amr->amr_numdrives);
654 amr->amr_numdrives = AMR_MAX_UNITS;
656 amr->amr_numdrives = aex->ae_numldrives;
658 for (i = 0; i < amr->amr_numdrives; i++) {
659 amr->amr_drive[i].al_size =
661 amr->amr_drive[i].al_state = aex->ae_drivestate[i];
662 amr->amr_drive[i].al_properties = aex->ae_driveprop[i];
672 ae = amr_enquire(amr, AMR_CMD_EXT_ENQUIRY2, 0, 0, amr->amr_enqbuf);
689 ae = amr_enquire(amr, AMR_CMD_ENQUIRY, 0, 0, amr->amr_enqbuf);
691 aprint_error_dev(amr->amr_dv,
734 aprint_normal_dev(amr->amr_dv, "interrupting at %s\n",
738 aprint_normal_dev(amr->amr_dv, "firmware <%c.%02d.%02d>, "
743 aprint_normal_dev(amr->amr_dv, "firmware <%.4s>, BIOS <%.4s>, "
747 amr->amr_maxqueuecnt = aa->aa_maxio;
753 aprint_error_dev(amr->amr_dv, "Inquiry returned more drives "
760 aprint_error_dev(amr->amr_dv,
763 amr->amr_numdrives = AMR_MAX_UNITS;
765 amr->amr_numdrives = ae->ae_ldrv.al_numdrives;
767 for (i = 0; i < amr->amr_numdrives; i++) {
768 amr->amr_drive[i].al_size = le32toh(ae->ae_ldrv.al_size[i]);
769 amr->amr_drive[i].al_state = ae->ae_ldrv.al_state[i];
770 amr->amr_drive[i].al_properties = ae->ae_ldrv.al_properties[i];
784 struct amr_softc *amr;
789 if ((amr = device_lookup_private(&amr_cd, i)) == NULL)
792 if ((rv = amr_ccb_alloc(amr, &ac)) == 0) {
794 rv = amr_ccb_poll(amr, ac, 30000);
795 amr_ccb_free(amr, ac);
798 aprint_error_dev(amr->amr_dv,
809 struct amr_softc *amr;
814 amr = cookie;
817 mutex_spin_enter(&amr->amr_mutex);
819 while ((*amr->amr_get_work)(amr, &mbox) == 0) {
823 ac = amr->amr_ccbs + idx;
825 if (idx >= amr->amr_maxqueuecnt) {
827 device_xname(amr->amr_dv), i, idx);
833 device_xname(amr->amr_dv), ac->ac_flags);
840 TAILQ_REMOVE(&amr->amr_ccb_active, ac, ac_chain.tailq);
844 device_xname(amr->amr_dv), ac->ac_ident);
847 mutex_spin_exit(&amr->amr_mutex);
855 mutex_spin_enter(&amr->amr_mutex);
860 mutex_spin_exit(&amr->amr_mutex);
863 amr_ccb_enqueue(amr, NULL);
874 struct amr_softc *amr;
877 amr = cookie;
884 if ((amr->amr_flags & AMRF_THREAD_EXIT) != 0) {
885 amr->amr_flags ^= AMRF_THREAD_EXIT;
892 if (amr_intr(amr) == 0)
893 amr_ccb_enqueue(amr, NULL);
895 mutex_spin_enter(&amr->amr_mutex);
896 ac = TAILQ_FIRST(&amr->amr_ccb_active);
902 device_xname(amr->amr_dv), ac->ac_ident);
903 amr_ccb_dump(amr, ac);
908 mutex_spin_exit(&amr->amr_mutex);
915 struct amr_softc *amr;
921 amr = cookie;
922 ae = amr->amr_enqbuf;
929 if ((amr->amr_flags & AMRF_THREAD_EXIT) != 0) {
930 amr->amr_flags ^= AMRF_THREAD_EXIT;
937 if (amr_intr(amr) == 0)
938 amr_ccb_enqueue(amr, NULL);
940 mutex_spin_enter(&amr->amr_mutex);
941 ac = TAILQ_FIRST(&amr->amr_ccb_active);
947 device_xname(amr->amr_dv), ac->ac_ident);
948 amr_ccb_dump(amr, ac);
953 mutex_spin_exit(&amr->amr_mutex);
955 if ((rv = amr_ccb_alloc(amr, &ac)) != 0) {
957 device_xname(amr->amr_dv), rv);
963 rv = amr_ccb_map(amr, ac, amr->amr_enqbuf,
966 aprint_error_dev(amr->amr_dv, "ccb_map failed (%d)\n",
968 amr_ccb_free(amr, ac);
972 rv = amr_ccb_wait(amr, ac);
973 amr_ccb_unmap(amr, ac);
975 aprint_error_dev(amr->amr_dv,
979 amr_ccb_free(amr, ac);
981 al = amr->amr_drive;
1024 amr_enquire(struct amr_softc *amr, u_int8_t cmd, u_int8_t cmdsub,
1031 if (amr_ccb_alloc(amr, &ac) != 0)
1040 rv = amr_ccb_map(amr, ac, sbuf, AMR_ENQUIRY_BUFSIZE, AC_XFER_IN);
1042 rv = amr_ccb_poll(amr, ac, 2000);
1043 amr_ccb_unmap(amr, ac);
1045 amr_ccb_free(amr, ac);
1054 amr_ccb_alloc(struct amr_softc *amr, struct amr_ccb **acp)
1056 mutex_spin_enter(&amr->amr_mutex);
1057 if ((*acp = SLIST_FIRST(&amr->amr_ccb_freelist)) == NULL) {
1058 mutex_spin_exit(&amr->amr_mutex);
1061 SLIST_REMOVE_HEAD(&amr->amr_ccb_freelist, ac_chain.slist);
1062 mutex_spin_exit(&amr->amr_mutex);
1071 amr_ccb_free(struct amr_softc *amr, struct amr_ccb *ac)
1079 mutex_spin_enter(&amr->amr_mutex);
1080 SLIST_INSERT_HEAD(&amr->amr_ccb_freelist, ac, ac_chain.slist);
1081 mutex_spin_exit(&amr->amr_mutex);
1090 amr_ccb_enqueue(struct amr_softc *amr, struct amr_ccb *ac)
1093 mutex_spin_enter(&amr->amr_mutex);
1094 SIMPLEQ_INSERT_TAIL(&amr->amr_ccb_queue, ac, ac_chain.simpleq);
1095 mutex_spin_exit(&amr->amr_mutex);
1098 while (SIMPLEQ_FIRST(&amr->amr_ccb_queue) != NULL) {
1099 mutex_spin_enter(&amr->amr_mutex);
1100 if ((ac = SIMPLEQ_FIRST(&amr->amr_ccb_queue)) != NULL) {
1101 if ((*amr->amr_submit)(amr, ac) != 0) {
1102 mutex_spin_exit(&amr->amr_mutex);
1105 SIMPLEQ_REMOVE_HEAD(&amr->amr_ccb_queue,
1107 TAILQ_INSERT_TAIL(&amr->amr_ccb_active, ac,
1110 mutex_spin_exit(&amr->amr_mutex);
1119 amr_ccb_map(struct amr_softc *amr, struct amr_ccb *ac, void *data, int size,
1130 rv = bus_dmamap_load(amr->amr_dmat, xfer, data, size, NULL,
1153 mb->mb_physaddr = htole32(amr->amr_sgls_paddr + sgloff);
1155 sge = (struct amr_sgentry *)((char *)amr->amr_sgls + sgloff);
1162 bus_dmamap_sync(amr->amr_dmat, xfer, 0, ac->ac_xfer_size, dmaflag);
1165 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, sgloff,
1175 amr_ccb_unmap(struct amr_softc *amr, struct amr_ccb *ac)
1185 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap,
1188 bus_dmamap_sync(amr->amr_dmat, ac->ac_xfer_map, 0, ac->ac_xfer_size,
1190 bus_dmamap_unload(amr->amr_dmat, ac->ac_xfer_map);
1198 amr_ccb_poll(struct amr_softc *amr, struct amr_ccb *ac, int timo)
1202 mutex_spin_enter(&amr->amr_mutex);
1203 if ((rv = (*amr->amr_submit)(amr, ac)) != 0) {
1204 mutex_spin_exit(&amr->amr_mutex);
1207 TAILQ_INSERT_TAIL(&amr->amr_ccb_active, ac, ac_chain.tailq);
1208 mutex_spin_exit(&amr->amr_mutex);
1211 amr_intr(amr);
1219 device_xname(amr->amr_dv), timo);
1229 amr_ccb_wait(struct amr_softc *amr, struct amr_ccb *ac)
1231 amr_ccb_enqueue(amr, ac);
1244 amr_mbox_wait(struct amr_softc *amr)
1249 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1251 if (amr->amr_mbox->mb_cmd.mb_busy == 0)
1257 printf("%s: controller wedged\n", device_xname(amr->amr_dv));
1268 amr_quartz_submit(struct amr_softc *amr, struct amr_ccb *ac)
1273 amr->amr_mbox->mb_poll = 0;
1274 amr->amr_mbox->mb_ack = 0;
1276 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1280 v = amr_inl(amr, AMR_QREG_ODB);
1281 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1283 while ((amr->amr_mbox->mb_cmd.mb_busy != 0) && (i++ < 10)) {
1284 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1287 v = amr_inl(amr, AMR_QREG_ODB);
1289 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1293 if (amr->amr_mbox->mb_cmd.mb_busy != 0)
1296 v = amr_inl(amr, AMR_QREG_IDB);
1298 amr->amr_mbox->mb_cmd.mb_busy = 0;
1299 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1301 printf("%s: submit failed\n", device_xname(amr->amr_dv));
1305 amr->amr_mbox->mb_segment = 0;
1306 memcpy(&amr->amr_mbox->mb_cmd, &ac->ac_cmd, sizeof(ac->ac_cmd));
1307 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1313 amr_outl(amr, AMR_QREG_IDB,
1314 (amr->amr_mbox_paddr + 16) | AMR_QIDB_SUBMIT);
1315 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1322 amr_std_submit(struct amr_softc *amr, struct amr_ccb *ac)
1325 amr->amr_mbox->mb_poll = 0;
1326 amr->amr_mbox->mb_ack = 0;
1328 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1331 if (amr->amr_mbox->mb_cmd.mb_busy != 0)
1334 if ((amr_inb(amr, AMR_SREG_MBOX_BUSY) & AMR_SMBOX_BUSY_FLAG) != 0) {
1335 amr->amr_mbox->mb_cmd.mb_busy = 0;
1336 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1341 amr->amr_mbox->mb_segment = 0;
1342 memcpy(&amr->amr_mbox->mb_cmd, &ac->ac_cmd, sizeof(ac->ac_cmd));
1344 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1349 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_POST);
1351 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1363 amr_quartz_get_work(struct amr_softc *amr, struct amr_mailbox_resp *mbsave)
1365 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1369 if (amr_inl(amr, AMR_QREG_ODB) != AMR_QODB_READY)
1372 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1376 memcpy(mbsave, &amr->amr_mbox->mb_resp, sizeof(*mbsave));
1379 amr_outl(amr, AMR_QREG_ODB, AMR_QODB_READY);
1380 amr_outl(amr, AMR_QREG_IDB, (amr->amr_mbox_paddr+16) | AMR_QIDB_ACK);
1391 while ((amr_inl(amr, AMR_QREG_IDB) & AMR_QIDB_ACK) != 0)
1398 amr_std_get_work(struct amr_softc *amr, struct amr_mailbox_resp *mbsave)
1402 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1406 if (((istat = amr_inb(amr, AMR_SREG_INTR)) & AMR_SINTR_VALID) == 0)
1410 amr_outb(amr, AMR_SREG_INTR, istat);
1412 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0,
1416 memcpy(mbsave, &amr->amr_mbox->mb_resp, sizeof(*mbsave));
1419 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_ACKINTR);
1425 amr_ccb_dump(struct amr_softc *amr, struct amr_ccb *ac)
1429 printf("%s: ", device_xname(amr->amr_dv));
1438 struct amr_softc *amr;
1440 if ((amr = device_lookup_private(&amr_cd, minor(dev))) == NULL)
1442 if ((amr->amr_flags & AMRF_OPEN) != 0)
1445 amr->amr_flags |= AMRF_OPEN;
1452 struct amr_softc *amr;
1454 amr = device_lookup_private(&amr_cd, minor(dev));
1455 amr->amr_flags &= ~AMRF_OPEN;
1478 struct amr_softc *amr;
1487 amr = device_lookup_private(&amr_cd, minor(dev));
1531 while (amr_ccb_alloc(amr, &ac) != 0) {
1545 error = amr_ccb_map(amr, ac, dp, (int)au_length,
1548 error = amr_ccb_wait(amr, ac);
1549 amr_ccb_unmap(amr, ac);
1554 amr_ccb_free(amr, ac);
1560 MODULE(MODULE_CLASS_DRIVER, amr, "pci");