int ida_get_ctl_info(int unit) { struct ida_ctl *ctlp = idadata[unit]; qcb_t qcb; qcb_t *qcbp = &qcb; ida_newqueue(unit); /* controller capacity statistics */ ctlp->inside = 0; ctlp->max_inside = 0; /* ask the controller to tell us about itself with an IDA_GET_CTL_INFO */ bzero(qcbp, sizeof(qcb_t)); qcbp->paddr = vtophys(qcbp); if (PCI_CONTROLLER(ctlp)) { qcbp->hdr.priority = 0x00; qcbp->hdr.flags = 0x24; } else { qcbp->hdr.priority = IDA_DEF_PRIORITY; qcbp->hdr.flags = 0x12; } qcbp->req.command = IDA_GET_CTL_INFO; qcbp->req.bcount = 1; qcbp->req.sgcount = 1; qcbp->sglist[0].len = sizeof(ida_buf); qcbp->sglist[0].addr = vtophys(&ida_buf); if (ida_submit_wait(unit, qcbp, sizeof(struct ida_qcb))) { printf("ida%d: idasubmit failed on IDA_GET_CTL_INFO\n", unit); return 0; } if (!PCI_CONTROLLER(ctlp)) { if (ctlp->com_status != IDA_COMPL_OK) { printf("ida%d: bad status 0x%02x from IDA_GET_CTL_INFO\n", unit, ctlp->com_status); return 0; } } /* got the information at last, print it and note the number of drives */ printf("ida%d: drvs=%d firm_rev=%c%c%c%c\n", unit, u_unpack(ida_buf.ctl.num_drvs), ida_buf.ctl.firm_rev[0], ida_buf.ctl.firm_rev[1], ida_buf.ctl.firm_rev[2], ida_buf.ctl.firm_rev[3]); ctlp->num_drvs = u_unpack(ida_buf.ctl.num_drvs); return 1; }
void __init pcibios_fixup_device_resources (struct pci_dev *dev, struct pci_bus *bus) { struct pci_controller *controller = PCI_CONTROLLER(dev); struct pci_window *window; int i, j; for (i = 0; i < PCI_NUM_RESOURCES; i++) { if (!dev->resource[i].start) continue; #define contains(win, res) ((res)->start >= (win)->start && \ (res)->end <= (win)->end) for (j = 0; j < controller->windows; j++) { window = &controller->window[j]; if (((dev->resource[i].flags & IORESOURCE_MEM && window->resource.flags & IORESOURCE_MEM) || (dev->resource[i].flags & IORESOURCE_IO && window->resource.flags & IORESOURCE_IO)) && contains(&window->resource, &dev->resource[i])) { dev->resource[i].start += window->offset; dev->resource[i].end += window->offset; } } } }
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region) { struct pci_controller *controller = PCI_CONTROLLER(dev); unsigned long offset = 0; int i; for (i = 0; i < controller->windows; i++) { struct pci_window *window = &controller->window[i]; if (!(window->resource.flags & res->flags)) continue; if (window->resource.start - window->offset > region->start) continue; if (window->resource.end - window->offset < region->end) continue; offset = window->offset; break; } res->start = region->start + offset; res->end = region->end + offset; }
int ida_attach_drives(int cntlr) { struct ida_ctl *ctlp = idadata[cntlr]; qcb_t qcb; qcb_t *qcbp = &qcb; struct ida_drv *drv; int drive; int unit; /* prepare to interrogate the drives */ bzero(qcbp, sizeof(qcb_t)); qcbp->req.command = IDA_GET_DRV_INFO; qcbp->paddr = vtophys(qcbp); if (PCI_CONTROLLER(ctlp)) { qcbp->hdr.priority = 0x00; qcbp->hdr.flags = 0x24; } else { qcbp->hdr.priority = IDA_DEF_PRIORITY; qcbp->hdr.flags = 0x12; } qcbp->req.bcount = 1; qcbp->req.sgcount = 1; qcbp->sglist[0].len = sizeof(ida_buf); qcbp->sglist[0].addr = vtophys(&ida_buf); for (drive = 0 ; drive < ctlp->num_drvs ; drive++) { qcbp->hdr.drive = drive; if (ida_submit_wait(cntlr, qcbp, sizeof(struct ida_qcb))) { printf("ida%d: ida_submit_wait failed on IDA_GET_DRV_INFO\n", cntlr); return 0; } if (!PCI_CONTROLLER(ctlp)) { if (ctlp->com_status != IDA_COMPL_OK) { printf("ida%d: bad status 0x%02x from IDA_GET_DRV_INFO\n", cntlr, ctlp->com_status); return 0; } } if ((drv = malloc(sizeof(struct ida_drv), M_TEMP, M_NOWAIT)) == NULL) { printf("ida%d: unable to allocate drive structure\n", cntlr); return 0; } bzero(drv, sizeof(struct ida_drv)); drv->ctl_unit = cntlr; drv->drv_unit = drive; drv->drv_info = ida_buf.drv; drv->flags |= ID_INIT; unit = id_unit; id_unit++; /* XXX unsure if this is the right way to do things */ id_drive[unit] = drv; printf("ida%d: unit %d (id%d): <%s>\n", cntlr, drive, unit, "Compaq Logical Drive"); printf("id%d: %luMB (%lu total sec), ", unit, (u_long)(u_unpack(drv->drv_info.secperunit) / 2048) * (u_unpack(drv->drv_info.secsize) / 512), (u_long)u_unpack(drv->drv_info.secperunit)); printf("%lu cyl, %lu head, %lu sec, bytes/sec %lu\n", (u_long)u_unpack(drv->drv_info.ncylinders), (u_long)u_unpack(drv->drv_info.ntracks), (u_long)u_unpack(drv->drv_info.nsectors), (u_long)u_unpack(drv->drv_info.secsize)); /* * Export the drive to the devstat interface. */ devstat_add_entry(&drv->dk_stats, "id", unit, (u_int32_t)drv->drv_info.secsize, DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_DA); #ifdef IDADEBUG if (ida_debug & IDA_SHOWMISC) { printf("ida%d: drive %d secsize=%d secperunit=%d ncylinders=%d ntracks=%d\n", unit, drive, u_unpack(ida_buf.drv.secsize), u_unpack(ida_buf.drv.secperunit), u_unpack(ida_buf.drv.ncylinders), u_unpack(ida_buf.drv.ntracks)); printf(" signature=0x%02x psectors=%d wprecomp=%d max_acc=%d control=0x%02x\n", u_unpack(ida_buf.drv.signature), u_unpack(ida_buf.drv.psectors), u_unpack(ida_buf.drv.wprecomp), u_unpack(ida_buf.drv.max_acc), u_unpack(ida_buf.drv.control)); printf(" pcylinders=%d ptracks=%d landing_zone=%d nsectors=%d checksum=0x%02x\n", u_unpack(ida_buf.drv.pcylinders), u_unpack(ida_buf.drv.ptracks), u_unpack(ida_buf.drv.landing_zone), u_unpack(ida_buf.drv.nsectors), u_unpack(ida_buf.drv.checksum)); } #endif } return 1; }