static void bst_insert_repair(bst *t, bstnode *n) { bstnode *u; /* case 1: n is the root */ if (!n->parent) { n->color = BLACK; return; } /* case 2: n's parent is black */ if (n->parent->color == BLACK) return; /* case 3: n's uncle and father are both red */ if ((u = UNCLE(n)) && u->color == RED) { n->parent->color = BLACK; u->color = BLACK; GRANDPARENT(n)->color = RED; bst_insert_repair(t, GRANDPARENT(n)); return; } /* case 4: n has no or black uncle, red father and either n = n->parent->right && n->parent = n->parent->parent->left or n = n->parent->left && n->parent = n->parent->parent->right */ if (IS_RIGHT_CHILD(n) && IS_LEFT_CHILD(n->parent)) { bst_rotate_left(t, n->parent); n = n->left; } else if (IS_LEFT_CHILD(n) && IS_RIGHT_CHILD(n->parent)) { bst_rotate_right(t, n->parent); n = n->right; } /* case 5: n has no or black uncle, red father and either n = n->parent->left && n->parent = n->parent->parent->left or n = n->parent->right && n->parent = n->parent->parent->right */ n->parent->color = BLACK; GRANDPARENT(n)->color = RED; if (IS_LEFT_CHILD(n)) bst_rotate_right(t, GRANDPARENT(n)); else { bst_rotate_left(t, GRANDPARENT(n)); } }
static void ata_ali_reset(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); device_t *children; int nchildren, i; ata_generic_reset(dev); /* * workaround for datacorruption bug found on at least SUN Blade-100 * find the ISA function on the southbridge and disable then enable * the ATA channel tristate buffer */ if (ctlr->chip->chiprev == 0xc3 || ctlr->chip->chiprev == 0xc2) { if (!device_get_children(GRANDPARENT(dev), &children, &nchildren)) { for (i = 0; i < nchildren; i++) { if (pci_get_devid(children[i]) == ATA_ALI_1533) { pci_write_config(children[i], 0x58, pci_read_config(children[i], 0x58, 1) & ~(0x04 << ch->unit), 1); pci_write_config(children[i], 0x58, pci_read_config(children[i], 0x58, 1) | (0x04 << ch->unit), 1); break; } } free(children, M_TEMP); } } }
static void ata_pcichannel_setmode(device_t parent, device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev)); struct ata_device *atadev = device_get_softc(dev); int mode = atadev->mode; ctlr->setmode(dev, ATA_PIO_MAX); if (mode >= ATA_DMA) ctlr->setmode(dev, mode); }
static void ata_usbchannel_setmode(device_t parent, device_t dev) { struct atausb_softc *sc = device_get_softc(GRANDPARENT(dev)); struct ata_device *atadev = device_get_softc(dev); usbd_device_handle udev; usbd_interface2device_handle(sc->iface, &udev); if (usbd_get_speed(udev) == USB_SPEED_HIGH) atadev->mode = ATA_USB2; else atadev->mode = ATA_USB1; }
static void ata_amd_setmode(device_t dev, int mode) { device_t gparent = GRANDPARENT(dev); struct ata_pci_controller *ctlr = device_get_softc(gparent); struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 }; int devno = (ch->unit << 1) + atadev->unit; int reg = 0x53 - devno; int error; mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); if (ctlr->chip->cfg1 & AMD_CABLE) { if (mode > ATA_UDMA2 && !(pci_read_config(gparent, 0x42, 1) & (1 << devno))) { ata_print_cable(dev, "controller"); mode = ATA_UDMA2; } } else mode = ata_check_80pin(dev, mode); error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); if (bootverbose) device_printf(dev, "%ssetting %s on %s chip\n", (error) ? "FAILURE " : "", ata_mode2str(mode), ctlr->chip->text); if (!error) { pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1); if (mode >= ATA_UDMA0) pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1); else pci_write_config(gparent, reg, 0x8b, 1); atadev->mode = mode; } }
static void ata_ati_setmode(device_t dev, int mode) { device_t gparent = GRANDPARENT(dev); struct ata_pci_controller *ctlr = device_get_softc(gparent); struct ata_channel *ch = device_get_softc(device_get_parent(dev)); struct ata_device *atadev = device_get_softc(dev); int devno = (ch->unit << 1) + atadev->unit; int offset = (devno ^ 0x01) << 3; int error; int piomode; static const uint8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; static const uint8_t dmatimings[] = { 0x77, 0x21, 0x20 }; mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); mode = ata_check_80pin(dev, mode); error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); if (bootverbose) device_printf(dev, "%ssetting %s on %s chip\n", (error) ? "FAILURE " : "", ata_mode2str(mode), ctlr->chip->text); if (!error) { if (mode >= ATA_UDMA0) { /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */ pci_write_config(gparent, 0x56, (pci_read_config(gparent, 0x56, 2) & ~(0xf << (devno << 2))) | ((mode & ATA_MODE_MASK) << (devno << 2)), 2); pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) | (0x01 << devno), 1); pci_write_config(gparent, 0x44, (pci_read_config(gparent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[2] << offset), 4); piomode = ATA_PIO4; } else if (mode >= ATA_WDMA0) { /* Disable UDMA, set WDMA mode and timings, calculate PIO. */ pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) & ~(0x01 << devno), 1); pci_write_config(gparent, 0x44, (pci_read_config(gparent, 0x44, 4) & ~(0xff << offset)) | (dmatimings[mode & ATA_MODE_MASK] << offset), 4); piomode = (mode == ATA_WDMA0) ? ATA_PIO0 : (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4; } else { /* Disable UDMA, set requested PIO. */ pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 1) & ~(0x01 << devno), 1); piomode = mode; } /* Set PIO mode and timings, calculated above. */ pci_write_config(gparent, 0x4a, (pci_read_config(gparent, 0x4a, 2) & ~(0xf << (devno << 2))) | ((piomode - ATA_PIO0) << (devno<<2)),2); pci_write_config(gparent, 0x40, (pci_read_config(gparent, 0x40, 4) & ~(0xff << offset)) | (piotimings[ata_mode2idx(piomode)] << offset), 4); atadev->mode = mode; } }