Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
			}
		}
	}
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}