Ejemplo n.º 1
0
int
sd_thin_pages(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_hdr *pg;
	size_t len = 0;
	u_int8_t *pages;
	int i, score = 0;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_SUPPORTED, flags);
	if (rv != 0)
		goto done;

	len = _2btol(pg->page_length);

	dma_free(pg, sizeof(*pg));
	pg = dma_alloc(sizeof(*pg) + len, (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg) + len,
	    SI_PG_SUPPORTED, flags);
	if (rv != 0)
		goto done;

	pages = (u_int8_t *)(pg + 1);
	if (pages[0] != SI_PG_SUPPORTED) {
		rv = EIO;
		goto done;
	}

	for (i = 1; i < len; i++) {
		switch (pages[i]) {
		case SI_PG_DISK_LIMITS:
		case SI_PG_DISK_THIN:
			score++;
			break;
		}
	}

	if (score < 2)
		rv = EOPNOTSUPP;

 done:
	dma_free(pg, sizeof(*pg) + len);
	return (rv);
}
Ejemplo n.º 2
0
int
sd_vpd_thin(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_disk_thin *pg;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_DISK_THIN, flags);
	if (rv != 0)
		goto done;

#ifdef notyet
	if (ISSET(pg->flags, VPD_DISK_THIN_TPU))
		sc->sc_delete = sd_unmap;
	else if (ISSET(pg->flags, VPD_DISK_THIN_TPWS)) {
		sc->sc_delete = sd_write_same_16;
		sc->params.unmap_descs = 1; /* WRITE SAME 16 only does one */
	} else
		rv = EOPNOTSUPP;
#endif

 done:
	dma_free(pg, sizeof(*pg));
	return (rv);
}
Ejemplo n.º 3
0
int
sd_ioctl_inquiry(struct sd_softc *sc, struct dk_inquiry *di)
{
	struct scsi_vpd_serial *vpd;

	vpd = dma_alloc(sizeof(*vpd), PR_WAITOK | PR_ZERO);

	bzero(di, sizeof(struct dk_inquiry));
	scsi_strvis(di->vendor, sc->sc_link->inqdata.vendor,
	    sizeof(sc->sc_link->inqdata.vendor));
	scsi_strvis(di->product, sc->sc_link->inqdata.product,
	    sizeof(sc->sc_link->inqdata.product));
	scsi_strvis(di->revision, sc->sc_link->inqdata.revision,
	    sizeof(sc->sc_link->inqdata.revision));

	/* the serial vpd page is optional */
	if (scsi_inquire_vpd(sc->sc_link, vpd, sizeof(*vpd),
	    SI_PG_SERIAL, 0) == 0)
		scsi_strvis(di->serial, vpd->serial, sizeof(vpd->serial));
	else
		strlcpy(di->serial, "(unknown)", sizeof(vpd->serial));

	dma_free(vpd, sizeof(*vpd));
	return (0);
}
Ejemplo n.º 4
0
void
emc_attach(struct device *parent, struct device *self, void *aux)
{
	struct emc_softc *sc = (struct emc_softc *)self;
	struct scsi_attach_args *sa = aux;
	struct scsi_link *link = sa->sa_sc_link;
	int sp;

	printf("\n");

	/* init link */
	link->device_softc = sc;

	/* init path */
	scsi_xsh_set(&sc->sc_path.p_xsh, link, emc_mpath_start);
	sc->sc_path.p_link = link;

	/* init status handler */
	scsi_xsh_set(&sc->sc_xsh, link, emc_status);
	sc->sc_pg = dma_alloc(sizeof(*sc->sc_pg), PR_WAITOK);

	/* let's go */

	if (emc_sp_info(sc, &sp)) {
		printf("%s: unable to get sp info\n", DEVNAME(sc));
		return;
	}

	if (mpath_path_attach(&sc->sc_path, sp, &emc_mpath_ops) != 0)
		printf("%s: unable to attach path\n", DEVNAME(sc));
}
Ejemplo n.º 5
0
int
sd_vpd_block_limits(struct sd_softc *sc, int flags)
{
	struct scsi_vpd_disk_limits *pg;
	int rv;

	pg = dma_alloc(sizeof(*pg), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (pg == NULL)
		return (ENOMEM);

	rv = scsi_inquire_vpd(sc->sc_link, pg, sizeof(*pg),
	    SI_PG_DISK_LIMITS, flags);
	if (rv != 0)
		goto done;

	if (_2btol(pg->hdr.page_length) == SI_PG_DISK_LIMITS_LEN_THIN) {
		sc->params.unmap_sectors = _4btol(pg->max_unmap_lba_count);
		sc->params.unmap_descs = _4btol(pg->max_unmap_desc_count);
	} else
		rv = EOPNOTSUPP;

 done:
	dma_free(pg, sizeof(*pg));
	return (rv);
}
Ejemplo n.º 6
0
int
emc_inquiry(struct emc_softc *sc, char *model, char *serial)
{
	u_int8_t *buffer;
	struct scsi_inquiry *cdb;
	struct scsi_xfer *xs;
	size_t length;
	int error;
	u_int8_t slen, mlen;

	length = MIN(sc->sc_path.p_link->inqdata.additional_length + 5, 255);
	if (length < 160) {
		printf("%s: FC (Legacy)\n");
		return (0);
	}

	buffer = dma_alloc(length, PR_WAITOK);

	xs = scsi_xs_get(sc->sc_path.p_link, scsi_autoconf);
	if (xs == NULL) {
		error = EBUSY;
		goto done;
	}

	cdb = (struct scsi_inquiry *)xs->cmd;
	cdb->opcode = INQUIRY;
	_lto2b(length, cdb->length);

	xs->cmdlen = sizeof(*cdb);
	xs->flags |= SCSI_DATA_IN;
	xs->data = buffer;
	xs->datalen = length;

	error = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (error != 0)
		goto done;

	slen = buffer[160];
	if (slen == 0 || slen + 161 > length) {
		error = EIO;
		goto done;
	}

	mlen = buffer[99];
	if (mlen == 0 || slen + mlen + 161 > length) {
		error = EIO;
		goto done;
	}

	scsi_strvis(serial, buffer + 161, slen);
	scsi_strvis(model, buffer + 161 + slen, mlen);

	error = 0;
done:
	dma_free(buffer, length);
	return (error);
}
Ejemplo n.º 7
0
static void dos_extended_partition(struct block_device *blk, struct partition_desc *pd,
		struct partition *partition, uint32_t signature)
{
	uint8_t *buf = dma_alloc(SECTOR_SIZE);
	uint32_t ebr_sector = partition->first_sec;
	struct partition_entry *table = (struct partition_entry *)&buf[0x1be];
	unsigned partno = 5;

	while (pd->used_entries < ARRAY_SIZE(pd->parts)) {
		int rc, i;
		int n = pd->used_entries;

		dev_dbg(blk->dev, "expect EBR in sector %x\n", ebr_sector);

		rc = block_read(blk, buf, ebr_sector, 1);
		if (rc != 0) {
			dev_err(blk->dev, "Cannot read EBR partition table\n");
			goto out;
		}

		/* sanity checks */
		if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa) {
			dev_err(blk->dev, "sector %x doesn't contain an EBR signature\n", ebr_sector);
			goto out;
		}

		for (i = 0x1de; i < 0x1fe; ++i)
			if (buf[i]) {
				dev_err(blk->dev, "EBR's third or fourth partition non-empty\n");
				goto out;
			}
		/* /sanity checks */

		/* the first entry defines the extended partition */
		pd->parts[n].first_sec = ebr_sector +
			get_unaligned_le32(&table[0].partition_start);
		pd->parts[n].size = get_unaligned_le32(&table[0].partition_size);
		pd->parts[n].dos_partition_type = table[0].type;
		if (signature)
			sprintf(pd->parts[n].partuuid, "%08x-%02u",
				signature, partno);
		pd->used_entries++;
		partno++;

		/* the second entry defines the start of the next ebr if != 0 */
		if (get_unaligned_le32(&table[1].partition_start))
			ebr_sector = partition->first_sec +
				get_unaligned_le32(&table[1].partition_start);
		else
			break;
	}

out:
	dma_free(buf);
	return;
}
Ejemplo n.º 8
0
static void lcdc_set_logo(unsigned char lcdc_num, unsigned lcd_wd, unsigned lcd_ht, struct fbcon_config *fb_con)
{
	struct tcc_lcdc_image_update Image_info;
	
	#ifdef DISPLAY_SPLASH_SCREEN_DIRECT
		fb_con->stride = fb_con->width;
	#else
		fb_con->width = lcd_wd;
		fb_con->height = lcd_ht;
		fb_con->stride = fb_con->width;
		fb_con->bpp = LCDC_FB_BPP;
		fb_con->format = FB_FORMAT_RGB565;

		fb_con->base = dma_alloc(4096, fb_con->width * fb_con->height * (fb_con->bpp/8));

		if (fb_con->base == NULL)		{
			printf(INFO, "lcdc: framebuffer alloc failed!\n");
		}
	#endif//

	dprintf(INFO, "fb_cfg base:%p xres:%d yres:%d bpp:%d \n", fb_con->base, fb_con->width, fb_con->height, fb_con->bpp);

	Image_info.addr0 = (unsigned int)fb_con->base;
	Image_info.Lcdc_layer = 0;
	Image_info.enable = 1;

	Image_info.Frame_width = Image_info.Image_width = fb_con->width;
	Image_info.Frame_height = Image_info.Image_height = fb_con->height;

	if(Image_info.Image_width > lcd_wd)
		Image_info.Image_width = lcd_wd;

	if(lcd_wd > Image_info.Frame_width)
		Image_info.offset_x = (lcd_wd - Image_info.Frame_width)/2;
	else
		Image_info.offset_x =  0;

	if(lcd_ht > Image_info.Frame_height)
		Image_info.offset_y = (lcd_ht - Image_info.Frame_height)/2;
	else
		Image_info.offset_y = 0;
	
	#ifdef _LCD_32BPP_
	Image_info.fmt = TCC_LCDC_IMG_FMT_RGB888;
	#else
	Image_info.fmt = TCC_LCDC_IMG_FMT_RGB565;
	#endif

	tcclcd_image_ch_set(lcdc_num, &Image_info);

	mdelay(1);
}
Ejemplo n.º 9
0
static void *read_mbr(struct block_device *blk)
{
	void *buf = dma_alloc(SECTOR_SIZE);
	int ret;

	ret = block_read(blk, buf, 0, 1);
	if (ret) {
		free(buf);
		return NULL;
	}

	return buf;
}
Ejemplo n.º 10
0
Archivo: dma.c Proyecto: jgraef/meinOS
int cdi_dma_open(struct cdi_dma_handle* handle,uint8_t channel,uint8_t mode,size_t length,void* buffer) {
  if (dma_isready(channel) && length<=DMA_MAXCOUNT) {
    handle->dmabuf = dma_alloc(length);
    if (handle->dmabuf!=NULL) {
      handle->channel = channel;
      handle->mode = mode;
      handle->length = length;
      handle->buffer = buffer;
      return dma_start(channel,handle->dmabuf,length,mode);
    }
  }
  return -1;
}
Ejemplo n.º 11
0
int
sd_read_cap_16(struct sd_softc *sc, int flags)
{
	struct scsi_read_capacity_16 cdb;
	struct scsi_read_cap_data_16 *rdcap;
	struct scsi_xfer *xs;
	int rv = ENOMEM;

	CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST);

	rdcap = dma_alloc(sizeof(*rdcap), (ISSET(flags, SCSI_NOSLEEP) ?
	    PR_NOWAIT : PR_WAITOK) | PR_ZERO);
	if (rdcap == NULL)
		return (ENOMEM);

	xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
	if (xs == NULL)
		goto done;

	bzero(&cdb, sizeof(cdb));
	cdb.opcode = READ_CAPACITY_16;
	cdb.byte2 = SRC16_SERVICE_ACTION;
	_lto4b(sizeof(*rdcap), cdb.length);

	memcpy(xs->cmd, &cdb, sizeof(cdb));
	xs->cmdlen = sizeof(cdb);
	xs->data = (void *)rdcap;
	xs->datalen = sizeof(*rdcap);
	xs->timeout = 20000;

	rv = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (rv == 0) {
		sc->params.disksize = _8btol(rdcap->addr) + 1;
		sc->params.secsize = _4btol(rdcap->length);
		if (ISSET(_2btol(rdcap->lowest_aligned), READ_CAP_16_TPE))
			SET(sc->flags, SDF_THIN);
		else
			CLR(sc->flags, SDF_THIN);
	}

 done:
	dma_free(rdcap, sizeof(*rdcap));
	return (rv);
}
Ejemplo n.º 12
0
Archivo: dma.c Proyecto: imphil/sources
void optimsoc_dma_transfer(void *local, uint32_t remote_tile, void *remote,
                           size_t size, dma_direction_t dir)
{
    dma_transfer_handle_t dma_handle;

    /* allocate transfer handle */
    while(dma_alloc(&dma_handle) != DMA_SUCCESS) {
        optimsoc_thread_yield(optimsoc_thread_current());
    }

    assert(size % 4 == 0);
    dma_transfer(local, remote_tile, remote, size/4, dir, dma_handle);

    dma_wait(dma_handle);

    dma_free(dma_handle);
}
Ejemplo n.º 13
0
/**
 * \brief Allocate buffer structure with dma memory
 *
 * Allocates a buffer structure and dma memory of size \a size.
 * Initilalizes the buffer structure with dma memory parameters.
 *
 * \param size Size of the dma memory region to allocate
 * \return A new buffer structure, or NULL if the buffer pool or dma
 * pool is exhausted.
 */
struct buffer *buffer_dma_alloc(size_t size)
{
	struct buffer	*buf;
	dma_addr_t	addr;

	buf = buffer_alloc();
	if (buf == NULL)
		return NULL;

	addr = dma_alloc(size);
	if (dma_addr_is_failed(addr)) {
		buffer_free(buf);
		return NULL;
	}

	buf->addr = addr;
	buf->len = size;

	return buf;
}
Ejemplo n.º 14
0
int
emc_sp_info(struct emc_softc *sc)
{
	struct emc_vpd_sp_info *pg;
	int error;

	pg = dma_alloc(sizeof(*pg), PR_WAITOK);

	error = scsi_inquire_vpd(sc->sc_path.p_link, &pg, sizeof(pg),
	    EMC_VPD_SP_INFO, scsi_autoconf);
	if (error != 0)
		goto done;

	sc->sc_sp = pg->current_sp;
	sc->sc_port = pg->port;
	sc->sc_lun_state = pg->lun_state;

	error = 0;
done:
	dma_free(pg, sizeof(*pg));
	return (error);
}
Ejemplo n.º 15
0
int
safte_bio_blink(struct safte_softc *sc, struct bioc_blink *blink)
{
	struct safte_writebuf_cmd *cmd;
	struct safte_slotop *op;
	struct scsi_xfer *xs;
	int error, slot, flags = 0, wantblink;

	switch (blink->bb_status) {
	case BIOC_SBBLINK:
		wantblink = 1;
		break;
	case BIOC_SBUNBLINK:
		wantblink = 0;
		break;
	default:
		return (EINVAL);
	}

	rw_enter_read(&sc->sc_lock);
	for (slot = 0; slot < sc->sc_nslots; slot++) {
		if (sc->sc_slots[slot] == blink->bb_target)
			break;
	}
	rw_exit_read(&sc->sc_lock);

	if (slot >= sc->sc_nslots)
		return (ENODEV);

	op = dma_alloc(sizeof(*op), PR_WAITOK | PR_ZERO);

	op->opcode = SAFTE_WRITE_SLOTOP;
	op->slot = slot;
	op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0;

	if (cold)
		flags |= SCSI_AUTOCONF;
	xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT);
	if (xs == NULL) {
		dma_free(op, sizeof(*op));
		return (ENOMEM);
	}
	xs->cmdlen = sizeof(*cmd);
	xs->data = (void *)op;
	xs->datalen = sizeof(*op);
	xs->retries = 2;
	xs->timeout = 30000;

	cmd = (struct safte_writebuf_cmd *)xs->cmd;
	cmd->opcode = WRITE_BUFFER;
	cmd->flags |= SAFTE_WR_MODE;
	cmd->length = htobe16(sizeof(struct safte_slotop));

	error = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (error != 0) {
		error = EIO;
	}
	dma_free(op, sizeof(*op));

	return (error);
}
Ejemplo n.º 16
0
int
safte_read_config(struct safte_softc *sc)
{
	struct safte_config *config = NULL;
	struct safte_readbuf_cmd *cmd;
	struct safte_sensor *s;
	struct scsi_xfer *xs;
	int error = 0, flags = 0, i, j;

	config = dma_alloc(sizeof(*config), PR_NOWAIT);
	if (config == NULL)
		return (1);

	if (cold)
		flags |= SCSI_AUTOCONF;
	xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
	if (xs == NULL) {
		error = 1;
		goto done;
	}
	xs->cmdlen = sizeof(*cmd);
	xs->data = (void *)config;
	xs->datalen = sizeof(*config);
	xs->retries = 2;
	xs->timeout = 30000;

	cmd = (struct safte_readbuf_cmd *)xs->cmd;
	cmd->opcode = READ_BUFFER;
	cmd->flags |= SAFTE_RD_MODE;
	cmd->bufferid = SAFTE_RD_CONFIG;
	cmd->length = htobe16(sizeof(*config));

	error = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (error != 0) {
		error = 1;
		goto done;
	}

	DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
	    " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config->nfans,
	    config->npwrsup, config->nslots, config->doorlock, config->ntemps,
	    config->alarm, SAFTE_CFG_CELSIUS(config->therm),
	    SAFTE_CFG_NTHERM(config->therm)));

	sc->sc_encbuflen = config->nfans * sizeof(u_int8_t) + /* fan status */
	    config->npwrsup * sizeof(u_int8_t) + /* power supply status */
	    config->nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
	    sizeof(u_int8_t) + /* door lock status */
	    sizeof(u_int8_t) + /* speaker status */
	    config->ntemps * sizeof(u_int8_t) + /* temp sensors */
	    sizeof(u_int16_t); /* temp out of range sensors */

	sc->sc_encbuf = dma_alloc(sc->sc_encbuflen, PR_NOWAIT);
	if (sc->sc_encbuf == NULL) {
		error = 1;
		goto done;
	}

	sc->sc_nsensors = config->nfans + config->npwrsup + config->ntemps +
		(config->doorlock ? 1 : 0) + (config->alarm ? 1 : 0);

	sc->sc_sensors = mallocarray(sc->sc_nsensors, sizeof(struct safte_sensor),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_sensors == NULL) {
		dma_free(sc->sc_encbuf, sc->sc_encbuflen);
		sc->sc_encbuf = NULL;
		sc->sc_nsensors = 0;
		error = 1;
		goto done;
	}

	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
	    sizeof(sc->sc_sensordev.xname));

	s = sc->sc_sensors;

	for (i = 0; i < config->nfans; i++) {
		s->se_type = SAFTE_T_FAN;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "Fan%d", i);

		s++;
	}
	j = config->nfans;

	for (i = 0; i < config->npwrsup; i++) {
		s->se_type = SAFTE_T_PWRSUP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "PSU%d", i);

		s++;
	}
	j += config->npwrsup;

#if NBIO > 0
	sc->sc_nslots = config->nslots;
	sc->sc_slots = (u_int8_t *)(sc->sc_encbuf + j);
#endif
	j += config->nslots;

	if (config->doorlock) {
		s->se_type = SAFTE_T_DOORLOCK;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "doorlock",
		    sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	if (config->alarm) {
		s->se_type = SAFTE_T_ALARM;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "alarm", sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	/*
	 * stash the temp info so we can get out of range status. limit the
	 * number so the out of temp checks cant go into memory it doesnt own
	 */
	sc->sc_ntemps = (config->ntemps > 15) ? 15 : config->ntemps;
	sc->sc_temps = s;
	sc->sc_celsius = SAFTE_CFG_CELSIUS(config->therm);
	for (i = 0; i < config->ntemps; i++) {
		s->se_type = SAFTE_T_TEMP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_TEMP;

		s++;
	}
	j += config->ntemps;

	sc->sc_temperrs = (u_int8_t *)(sc->sc_encbuf + j);
done:
	dma_free(config, sizeof(*config));
	return (error);
}
Ejemplo n.º 17
0
int
safte_match(struct device *parent, void *match, void *aux)
{
	struct scsi_inquiry_data *inqbuf;
	struct scsi_attach_args	*sa = aux;
	struct scsi_inquiry_data *inq = sa->sa_inqbuf;
	struct scsi_xfer *xs;
	struct safte_inq *si;
	int error, flags = 0, length;

	if (inq == NULL)
		return (0);

	/* match on dell enclosures */
	if ((inq->device & SID_TYPE) == T_PROCESSOR &&
	    SCSISPC(inq->version) == 3)
		return (2);

	if ((inq->device & SID_TYPE) != T_PROCESSOR ||
	    SCSISPC(inq->version) != 2 ||
	    (inq->response_format & SID_ANSII) != 2)
		return (0);

	length = inq->additional_length + SAFTE_EXTRA_OFFSET;
	if (length < SAFTE_INQ_LEN)
		return (0);
	if (length > sizeof(*inqbuf))
		length = sizeof(*inqbuf);

	inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO);
	if (inqbuf == NULL)
		return (0);

	memset(inqbuf->extra, ' ', sizeof(inqbuf->extra));

	if (cold)
		flags |= SCSI_AUTOCONF;
	xs = scsi_xs_get(sa->sa_sc_link, flags | SCSI_DATA_IN);
	if (xs == NULL)
		goto fail;

	xs->retries = 2;
	xs->timeout = 10000;

	scsi_init_inquiry(xs, 0, 0, inqbuf, length);

	error = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (error)
		goto fail;

	si = (struct safte_inq *)&inqbuf->extra;
	if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) {
		dma_free(inqbuf, sizeof(*inqbuf));
		return (2);
	}

fail:
	dma_free(inqbuf, sizeof(*inqbuf));
	return (0);
}
Ejemplo n.º 18
0
void
viomb_attach(struct device *parent, struct device *self, void *aux)
{
	struct viomb_softc *sc = (struct viomb_softc *)self;
	struct virtio_softc *vsc = (struct virtio_softc *)parent;
	u_int32_t features;
	int i;

	if (vsc->sc_child != NULL) {
		printf("child already attached for %s; something wrong...\n",
		    parent->dv_xname);
		return;
	}

	/* fail on non-4K page size archs */
	if (VIRTIO_PAGE_SIZE != PAGE_SIZE){
		printf("non-4K page size arch found, needs %d, got %d\n",
		    VIRTIO_PAGE_SIZE, PAGE_SIZE);
		return;
	}

	sc->sc_virtio = vsc;
	vsc->sc_vqs = &sc->sc_vq[VQ_INFLATE];
	vsc->sc_nvqs = 0;
	vsc->sc_child = self;
	vsc->sc_ipl = IPL_BIO;
	vsc->sc_config_change = viomb_config_change;
	vsc->sc_intrhand = virtio_vq_intr;

	/* negotiate features */
	features = VIRTIO_F_RING_INDIRECT_DESC;
	features = virtio_negotiate_features(vsc, features,
					     viomb_feature_names);

	if ((virtio_alloc_vq(vsc, &sc->sc_vq[VQ_INFLATE], VQ_INFLATE,
	     sizeof(u_int32_t) * PGS_PER_REQ, 1, "inflate") != 0))
		goto err;
	vsc->sc_nvqs++;
	if ((virtio_alloc_vq(vsc, &sc->sc_vq[VQ_DEFLATE], VQ_DEFLATE,
	     sizeof(u_int32_t) * PGS_PER_REQ, 1, "deflate") != 0))
		goto err;
	vsc->sc_nvqs++;

	sc->sc_vq[VQ_INFLATE].vq_done = viomb_inflate_intr;
	sc->sc_vq[VQ_DEFLATE].vq_done = viomb_deflate_intr;
	virtio_start_vq_intr(vsc, &sc->sc_vq[VQ_INFLATE]);
	virtio_start_vq_intr(vsc, &sc->sc_vq[VQ_DEFLATE]);

	viomb_read_config(sc);
	TAILQ_INIT(&sc->sc_balloon_pages);

	if ((sc->sc_req.bl_pages = dma_alloc(sizeof(u_int32_t) * PGS_PER_REQ,
	    PR_NOWAIT|PR_ZERO)) == NULL) {
		printf("%s: Can't alloc DMA memory.\n", DEVNAME(sc));
		goto err;
	}
	if (bus_dmamap_create(vsc->sc_dmat, sizeof(u_int32_t) * PGS_PER_REQ,
			      1, sizeof(u_int32_t) * PGS_PER_REQ, 0,
			      BUS_DMA_NOWAIT, &sc->sc_req.bl_dmamap)) {
		printf("%s: dmamap creation failed.\n", DEVNAME(sc));
		goto err;
	}
	if (bus_dmamap_load(vsc->sc_dmat, sc->sc_req.bl_dmamap,
			    &sc->sc_req.bl_pages[0],
			    sizeof(uint32_t) * PGS_PER_REQ,
			    NULL, BUS_DMA_NOWAIT)) {
		printf("%s: dmamap load failed.\n", DEVNAME(sc));
		goto err_dmamap;
	}

	sc->sc_taskq = taskq_create("viomb", 1, IPL_BIO);
	if (sc->sc_taskq == NULL)
		goto err_dmamap;
	task_set(&sc->sc_task, viomb_worker, sc, NULL);

	printf("\n");
	return;
err_dmamap:
	bus_dmamap_destroy(vsc->sc_dmat, sc->sc_req.bl_dmamap);
err:
	if (sc->sc_req.bl_pages)
		dma_free(sc->sc_req.bl_pages, sizeof(u_int32_t) * PGS_PER_REQ);
	for (i = 0; i < vsc->sc_nvqs; i++)
		virtio_free_vq(vsc, &sc->sc_vq[i]);
	vsc->sc_nvqs = 0;
	vsc->sc_child = VIRTIO_CHILD_ERROR;
	return;
}
Ejemplo n.º 19
0
int
scsi_ioc_ata_cmd(struct scsi_link *link, atareq_t *atareq)
{
	struct scsi_xfer *xs;
	struct scsi_ata_passthru_12 *cdb;
	int err = 0;

	if (atareq->datalen > MAXPHYS)
		return (EINVAL);

	xs = scsi_xs_get(link, 0);
	if (xs == NULL)
		return (ENOMEM);

	cdb = (struct scsi_ata_passthru_12 *)xs->cmd;
	cdb->opcode = ATA_PASSTHRU_12;

	if (atareq->datalen > 0) {
		if (atareq->flags & ATACMD_READ) {
			cdb->count_proto = ATA_PASSTHRU_PROTO_PIO_DATAIN;
			cdb->flags = ATA_PASSTHRU_T_DIR_READ;
		} else {
			cdb->count_proto = ATA_PASSTHRU_PROTO_PIO_DATAOUT;
			cdb->flags = ATA_PASSTHRU_T_DIR_WRITE;
		}
		cdb->flags |= ATA_PASSTHRU_T_LEN_SECTOR_COUNT;
	} else {
		cdb->count_proto = ATA_PASSTHRU_PROTO_NON_DATA;
		cdb->flags = ATA_PASSTHRU_T_LEN_NONE;
	}
	cdb->features = atareq->features;
	cdb->sector_count = atareq->sec_count;
	cdb->lba_low = atareq->sec_num;
	cdb->lba_mid = atareq->cylinder;
	cdb->lba_high = atareq->cylinder >> 8;
	cdb->device = atareq->head & 0x0f;
	cdb->command = atareq->command;

	xs->cmdlen = sizeof(*cdb);

	if (atareq->datalen > 0) {
		xs->data = dma_alloc(atareq->datalen, PR_WAITOK | PR_ZERO);
		if (xs->data == NULL) {
			err = ENOMEM;
			goto err;
		}
		xs->datalen = atareq->datalen;
	}

	if (atareq->flags & ATACMD_READ)
		xs->flags |= SCSI_DATA_IN;
	if (atareq->flags & ATACMD_WRITE) {
		if (atareq->datalen > 0) {
			err = copyin(atareq->databuf, xs->data,
			    atareq->datalen);
			if (err != 0)
				goto err;
		}

		xs->flags |= SCSI_DATA_OUT;
	}

	xs->flags |= SCSI_SILENT;	/* User is responsible for errors. */
	xs->retries = 0; /* user must do the retries *//* ignored */

	scsi_xs_sync(xs);

	atareq->retsts = ATACMD_ERROR;
	switch (xs->error) {
	case XS_SENSE:
	case XS_SHORTSENSE:
#ifdef SCSIDEBUG
		scsi_sense_print_debug(xs);
#endif
		/* XXX this is not right */
	case XS_NOERROR:
		atareq->retsts = ATACMD_OK;
		break;
	default:
		atareq->retsts = ATACMD_ERROR;
		break;
	}

	if (atareq->datalen > 0 && atareq->flags & ATACMD_READ) {
		err = copyout(xs->data, atareq->databuf, atareq->datalen);
		if (err != 0)
			goto err;
	}

err:
	if (xs->data)
		dma_free(xs->data, atareq->datalen);
	scsi_xs_put(xs);

	return (err);
}
Ejemplo n.º 20
0
struct fbcon_config *lcdc_init(void)
{
#if defined(_M805_8923_) || defined(_M805_8925_) || (HW_REV == 0x1006) || (HW_REV == 0x1008)
	#define LCDC_NUM	0
#else
	#define LCDC_NUM 	1
#endif
	struct lcd_panel *panel_info;
	struct fbcon_config *fbcon_cfg;
	struct tcc_lcdc_image_update Image_info;

	unsigned int 	lclk;

#if 0
// reset VIOD
	BITSET(pDDICfg->SWRESET, Hw3);
	BITSET(pDDICfg->SWRESET, Hw2);

	BITCLR(pDDICfg->SWRESET, Hw3);
	BITCLR(pDDICfg->SWRESET, Hw2);	
#endif//

	panel_info = tccfb_get_panel();
	panel_info->dev.power_on = GPIO_LCD_ON;
	panel_info->dev.display_on = GPIO_LCD_DISPLAY;
	panel_info->dev.bl_on = GPIO_LCD_BL;
	panel_info->dev.reset = GPIO_LCD_RESET;

	panel_info->dev.lcdc_num = LCDC_NUM;

	panel_info->init(panel_info);

	if(panel_info->dev.lcdc_num)
	{
		tca_ckc_setperi(PERI_LCD1,ENABLE, panel_info->clk_freq * panel_info->clk_div);
		lclk  = tca_ckc_getperi(PERI_LCD1);
	}
	else
	{
		tca_ckc_setperi(PERI_LCD0,ENABLE, panel_info->clk_freq * panel_info->clk_div);
		lclk  = tca_ckc_getperi(PERI_LCD0);
	}
	printf("telechips tcc88xx %s lcdc:%d clk:%d set clk:%d \n", __func__, LCDC_NUM, panel_info->clk_freq, lclk);

	
	dprintf(INFO, "lcdc: panel is %d x %d %dbpp\n",	panel_info->xres, panel_info->yres, fb_cfg.bpp);

	#ifdef DISPLAY_SPLASH_SCREEN_DIRECT
	fb_cfg.stride = fb_cfg.width;
	#else
	fb_cfg.width = panel_info->xres;
	fb_cfg.height = panel_info->yres;
	fb_cfg.stride = fb_cfg.width;
	fb_cfg.bpp = LCDC_FB_BPP;
	fb_cfg.format = FB_FORMAT_RGB565;

	fb_cfg.base = dma_alloc(4096, fb_cfg.width * fb_cfg.height * (fb_cfg.bpp/8));

	if (fb_cfg.base == NULL)
	  dprintf(INFO, "lcdc: framebuffer alloc failed!\n");
	#endif//

	dprintf(INFO, "fb_cfg base:0x%x xres:%d yres:%d bpp:%d \n",fb_cfg.base, fb_cfg.width, fb_cfg.height, fb_cfg.bpp);

	Image_info.addr0 = (unsigned int)fb_cfg.base;
	Image_info.Lcdc_layer = 0;
	Image_info.enable = 1;

	Image_info.Frame_width = Image_info.Image_width = fb_cfg.width;
	Image_info.Frame_height = Image_info.Image_height = fb_cfg.height;
	
	printf(INFO, "Frame_width:%d Image_width:%d width:%d \n",Image_info.Frame_width, Image_info.Image_width, fb_cfg.width);
	printf(INFO, "Frame_height:%d Image_height:%d width:%d \n",Image_info.Frame_height, Image_info.Image_height, fb_cfg.height);

	if(Image_info.Image_width > panel_info->xres)
		Image_info.Image_width = panel_info->xres;

	if(panel_info->xres > Image_info.Frame_width)
		Image_info.offset_x = (panel_info->xres - Image_info.Frame_width)/2;
	else
		Image_info.offset_x =  0;

	if(panel_info->yres > Image_info.Frame_height)
		Image_info.offset_y = (panel_info->yres - Image_info.Frame_height)/2;
	else
		Image_info.offset_y = 0;
	
	#ifdef _LCD_32BPP_
	Image_info.fmt = TCC_LCDC_IMG_FMT_RGB888;
	#else
	Image_info.fmt = TCC_LCDC_IMG_FMT_RGB565;
	#endif
	
	tcclcd_image_ch_set(panel_info->dev.lcdc_num, &Image_info);

       panel_info->set_power(panel_info, 1);

	mdelay(1);
	panel_info->set_backlight_level(panel_info, DEFAULT_BACKLIGTH);

	fbcon_cfg = &fb_cfg;

	return fbcon_cfg;
}
Ejemplo n.º 21
0
/*
 * Fill out the disk parameter structure. Return SDGP_RESULT_OK if the
 * structure is correctly filled in, SDGP_RESULT_OFFLINE otherwise. The caller
 * is responsible for clearing the SDEV_MEDIA_LOADED flag if the structure
 * cannot be completed.
 */
int
sd_get_parms(struct sd_softc *sc, struct disk_parms *dp, int flags)
{
	union scsi_mode_sense_buf *buf = NULL;
	struct page_rigid_geometry *rigid = NULL;
	struct page_flex_geometry *flex = NULL;
	struct page_reduced_geometry *reduced = NULL;
	u_char *page0 = NULL;
	u_int32_t heads = 0, sectors = 0, cyls = 0, secsize = 0;
	int err = 0, big;

	if (sd_size(sc, flags) != 0)
		return (SDGP_RESULT_OFFLINE);

	if (ISSET(sc->flags, SDF_THIN) && sd_thin_params(sc, flags) != 0) {
		/* we dont know the unmap limits, so we cant use thin shizz */
		CLR(sc->flags, SDF_THIN);
	}

	buf = dma_alloc(sizeof(*buf), PR_NOWAIT);
	if (buf == NULL)
		goto validate;

	/*
	 * Ask for page 0 (vendor specific) mode sense data to find
	 * READONLY info. The only thing USB devices will ask for. 
	 */
	err = scsi_do_mode_sense(sc->sc_link, 0, buf, (void **)&page0,
	    NULL, NULL, NULL, 1, flags | SCSI_SILENT, &big);
	if (err == 0) {
		if (big && buf->hdr_big.dev_spec & SMH_DSP_WRITE_PROT)
			SET(sc->sc_link->flags, SDEV_READONLY);
		else if (!big && buf->hdr.dev_spec & SMH_DSP_WRITE_PROT)
			SET(sc->sc_link->flags, SDEV_READONLY);
		else
			CLR(sc->sc_link->flags, SDEV_READONLY);
	}

	/*
	 * Many UMASS devices choke when asked about their geometry. Most
	 * don't have a meaningful geometry anyway, so just fake it if
	 * scsi_size() worked.
	 */
	if ((sc->sc_link->flags & SDEV_UMASS) && (dp->disksize > 0))
		goto validate;

	switch (sc->sc_link->inqdata.device & SID_TYPE) {
	case T_OPTICAL:
		/* No more information needed or available. */
		break;

	case T_RDIRECT:
		/* T_RDIRECT supports only PAGE_REDUCED_GEOMETRY (6). */
		err = scsi_do_mode_sense(sc->sc_link, PAGE_REDUCED_GEOMETRY,
		    buf, (void **)&reduced, NULL, NULL, &secsize,
		    sizeof(*reduced), flags | SCSI_SILENT, NULL);
		if (!err && reduced &&
		    DISK_PGCODE(reduced, PAGE_REDUCED_GEOMETRY)) {
			if (dp->disksize == 0)
				dp->disksize = _5btol(reduced->sectors);
			if (secsize == 0)
				secsize = _2btol(reduced->bytes_s);
		}
		break;

	default:
		/*
		 * NOTE: Some devices leave off the last four bytes of 
		 * PAGE_RIGID_GEOMETRY and PAGE_FLEX_GEOMETRY mode sense pages.
		 * The only information in those four bytes is RPM information
		 * so accept the page. The extra bytes will be zero and RPM will
		 * end up with the default value of 3600.
		 */
		if (((sc->sc_link->flags & SDEV_ATAPI) == 0) ||
		    ((sc->sc_link->flags & SDEV_REMOVABLE) == 0))
			err = scsi_do_mode_sense(sc->sc_link,
			    PAGE_RIGID_GEOMETRY, buf, (void **)&rigid, NULL,
			    NULL, &secsize, sizeof(*rigid) - 4,
			    flags | SCSI_SILENT, NULL);
		if (!err && rigid && DISK_PGCODE(rigid, PAGE_RIGID_GEOMETRY)) {
			heads = rigid->nheads;
			cyls = _3btol(rigid->ncyl);
			if (heads * cyls > 0)
				sectors = dp->disksize / (heads * cyls);
		} else {
			err = scsi_do_mode_sense(sc->sc_link,
			    PAGE_FLEX_GEOMETRY, buf, (void **)&flex, NULL, NULL,
			    &secsize, sizeof(*flex) - 4,
			    flags | SCSI_SILENT, NULL);
			if (!err && flex &&
			    DISK_PGCODE(flex, PAGE_FLEX_GEOMETRY)) {
				sectors = flex->ph_sec_tr;
				heads = flex->nheads;
				cyls = _2btol(flex->ncyl);
				if (secsize == 0)
					secsize = _2btol(flex->bytes_s);
				if (dp->disksize == 0)
					dp->disksize = heads * cyls * sectors;
			}
		}
		break;
	}

validate:
	if (buf)
		dma_free(buf, sizeof(*buf));

	if (dp->disksize == 0)
		return (SDGP_RESULT_OFFLINE);

	if (dp->secsize == 0)
		dp->secsize = (secsize == 0) ? 512 : secsize;

	/*
	 * Restrict secsize values to powers of two between 512 and 64k.
	 */
	switch (dp->secsize) {
	case 0x200:	/* == 512, == DEV_BSIZE on all architectures. */
	case 0x400:
	case 0x800:
	case 0x1000:
	case 0x2000:
	case 0x4000:
	case 0x8000:
	case 0x10000:
		break;
	default:
		SC_DEBUG(sc->sc_link, SDEV_DB1,
		    ("sd_get_parms: bad secsize: %#x\n", dp->secsize));
		return (SDGP_RESULT_OFFLINE);
	}

	/*
	 * XXX THINK ABOUT THIS!!  Using values such that sectors * heads *
	 * cyls is <= disk_size can lead to wasted space. We need a more
	 * careful calculation/validation to make everything work out
	 * optimally.
	 */
	if (dp->disksize > 0xffffffff && (dp->heads * dp->sectors) < 0xffff) {
		dp->heads = 511;
		dp->sectors = 255;
		cyls = 0;
	} else {
		/*
		 * Use standard geometry values for anything we still don't
		 * know.
		 */
		dp->heads = (heads == 0) ? 255 : heads;
		dp->sectors = (sectors == 0) ? 63 : sectors;
	}

	dp->cyls = (cyls == 0) ? dp->disksize / (dp->heads * dp->sectors) :
	    cyls;

	if (dp->cyls == 0) {
		dp->heads = dp->cyls = 1;
		dp->sectors = dp->disksize;
	}

	return (SDGP_RESULT_OK);
}
Ejemplo n.º 22
0
int
scsi_probe_target(struct scsibus_softc *sc, int target)
{
	struct scsi_link *alink = sc->adapter_link;
	struct scsi_link *link;
	struct scsi_report_luns_data *report;
	int i, nluns, lun;

	if (scsi_probe_lun(sc, target, 0) == EINVAL)
		return (EINVAL);

	link = scsi_get_link(sc, target, 0);
	if (link == NULL)
		return (ENXIO);

	if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 &&
	    SCSISPC(link->inqdata.version) > 2) {
		report = dma_alloc(sizeof(*report), PR_WAITOK);
		if (report == NULL)
			goto dumbscan;

		if (scsi_report_luns(link, REPORT_NORMAL, report,
		    sizeof(*report), scsi_autoconf | SCSI_SILENT |
		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY |
		    SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) {
			dma_free(report, sizeof(*report));
			goto dumbscan;
		}

		/*
		 * XXX In theory we should check if data is full, which
		 * would indicate it needs to be enlarged and REPORT
		 * LUNS tried again. Solaris tries up to 3 times with
		 * larger sizes for data.
		 */
		nluns = _4btol(report->length) / RPL_LUNDATA_SIZE;
		for (i = 0; i < nluns; i++) {
			if (report->luns[i].lundata[0] != 0)
				continue;
			lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN];
			if (lun == 0)
				continue;

			/* Probe the provided LUN. Don't check LUN 0. */
			scsi_remove_link(sc, link);
			scsi_probe_lun(sc, target, lun);
			scsi_add_link(sc, link);
		}

		dma_free(report, sizeof(*report));
		return (0);
	}

dumbscan:
	for (i = 1; i < alink->luns; i++) {
		if (scsi_probe_lun(sc, target, i) == EINVAL)
			break;
	}

	return (0);
}
Ejemplo n.º 23
0
static int au1k_irda_net_init(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	int i, retval = 0, err;
	db_dest_t *pDB, *pDBfree;
	dma_addr_t temp;

	err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
	if (err)
		goto out1;

	dev->netdev_ops = &au1k_irda_netdev_ops;

	irda_init_max_qos_capabilies(&aup->qos);

	/* The only value we must override it the baudrate */
	aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000 |(IR_4000000 << 8);

	aup->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&aup->qos);

	retval = -ENOMEM;

	/* Tx ring follows rx ring + 512 bytes */
	/* we need a 1k aligned buffer */
	aup->rx_ring[0] = (ring_dest_t *)
		dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
	if (!aup->rx_ring[0])
		goto out2;

	/* allocate the data buffers */
	aup->db[0].vaddr =
		(void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
	if (!aup->db[0].vaddr)
		goto out3;

	setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);

	pDBfree = NULL;
	pDB = aup->db;
	for (i=0; i<(2*NUM_IR_DESC); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr =
			(u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	/* attach a data buffer to each descriptor */
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->rx_db_inuse[i] = pDB;
	}
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->tx_ring[i]->count_0 = 0;
		aup->tx_ring[i]->count_1 = 0;
		aup->tx_ring[i]->flags = 0;
		aup->tx_db_inuse[i] = pDB;
	}

#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
	/* power on */
	bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
			      BCSR_RESETS_IRDA_MODE_FULL);
#endif

	return 0;

out3:
	dma_free((void *)aup->rx_ring[0],
		2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
out2:
	kfree(aup->rx_buff.head);
out1:
	printk(KERN_ERR "au1k_init_module failed.  Returns %d\n", retval);
	return retval;
}
Ejemplo n.º 24
0
int
scsi_ioc_cmd(struct scsi_link *link, scsireq_t *screq)
{
	struct scsi_xfer *xs;
	int err = 0;

	if (screq->cmdlen > sizeof(struct scsi_generic))
		return (EFAULT);
	if (screq->datalen > MAXPHYS)
		return (EINVAL);

	xs = scsi_xs_get(link, 0);
	if (xs == NULL)
		return (ENOMEM);

	memcpy(xs->cmd, screq->cmd, screq->cmdlen);
	xs->cmdlen = screq->cmdlen;

	if (screq->datalen > 0) {
		xs->data = dma_alloc(screq->datalen, PR_WAITOK | PR_ZERO);
		if (xs->data == NULL) {
			err = ENOMEM;
			goto err;
		}
		xs->datalen = screq->datalen;
	}

	if (screq->flags & SCCMD_READ)
		xs->flags |= SCSI_DATA_IN;
	if (screq->flags & SCCMD_WRITE) {
		if (screq->datalen > 0) {
			err = copyin(screq->databuf, xs->data, screq->datalen);
			if (err != 0)
				goto err;
		}

		xs->flags |= SCSI_DATA_OUT;
	}

	xs->flags |= SCSI_SILENT;	/* User is responsible for errors. */
	xs->timeout = screq->timeout;
	xs->retries = 0; /* user must do the retries *//* ignored */

	scsi_xs_sync(xs);

	screq->retsts = 0;
	screq->status = xs->status;
	switch (xs->error) {
	case XS_NOERROR:
		/* probably rubbish */
		screq->datalen_used = xs->datalen - xs->resid;
		screq->retsts = SCCMD_OK;
		break;
	case XS_SENSE:
#ifdef SCSIDEBUG
		scsi_sense_print_debug(xs);
#endif
		screq->senselen_used = min(sizeof(xs->sense),
		    sizeof(screq->sense));
		bcopy(&xs->sense, screq->sense, screq->senselen_used);
		screq->retsts = SCCMD_SENSE;
		break;
	case XS_SHORTSENSE:
#ifdef SCSIDEBUG
		scsi_sense_print_debug(xs);
#endif
		printf("XS_SHORTSENSE\n");
		screq->senselen_used = min(sizeof(xs->sense),
		    sizeof(screq->sense));
		bcopy(&xs->sense, screq->sense, screq->senselen_used);
		screq->retsts = SCCMD_UNKNOWN;
		break;
	case XS_DRIVER_STUFFUP:
		screq->retsts = SCCMD_UNKNOWN;
		break;
	case XS_TIMEOUT:
		screq->retsts = SCCMD_TIMEOUT;
		break;
	case XS_BUSY:
		screq->retsts = SCCMD_BUSY;
		break;
	default:
		screq->retsts = SCCMD_UNKNOWN;
		break;
	}

	if (screq->datalen > 0 && screq->flags & SCCMD_READ) {
		err = copyout(xs->data, screq->databuf, screq->datalen);
		if (err != 0)
			goto err;
	}

err:
	if (xs->data)
		dma_free(xs->data, screq->datalen);
	scsi_xs_put(xs);

	return (err);
}
Ejemplo n.º 25
0
void
viornd_attach(struct device *parent, struct device *self, void *aux)
{
	struct viornd_softc *sc = (struct viornd_softc *)self;
	struct virtio_softc *vsc = (struct virtio_softc *)parent;
	unsigned int shift;

	vsc->sc_vqs = &sc->sc_vq;
	vsc->sc_nvqs = 1;
	vsc->sc_config_change = 0;
	if (vsc->sc_child != NULL)
		panic("already attached to something else");
	vsc->sc_child = self;
	vsc->sc_ipl = IPL_NET;
	vsc->sc_intrhand = virtio_vq_intr;
	sc->sc_virtio = vsc;

	virtio_negotiate_features(vsc, 0, NULL);

	if (sc->sc_dev.dv_cfdata->cf_flags & VIORND_ONESHOT) {
		sc->sc_interval = 0;
	} else {
		shift = VIORND_INTERVAL_SHIFT(sc->sc_dev.dv_cfdata->cf_flags);
		if (shift == 0)
			shift = VIORND_INTERVAL_SHIFT_DEFAULT;
		sc->sc_interval = 15 * (1 << shift);
	}
#if VIORND_DEBUG
	printf(": request interval: %us\n", sc->sc_interval);
#endif

	sc->sc_buf = dma_alloc(VIORND_BUFSIZE, PR_NOWAIT|PR_ZERO);
	if (sc->sc_buf == NULL) {
		printf(": Can't alloc dma buffer\n");
		goto err;
	}
	if (bus_dmamap_create(sc->sc_virtio->sc_dmat, VIORND_BUFSIZE, 1,
	    VIORND_BUFSIZE, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
	    &sc->sc_dmamap)) {
		printf(": Can't alloc dmamap\n");
		goto err;
	}
	if (bus_dmamap_load(sc->sc_virtio->sc_dmat, sc->sc_dmamap,
	    sc->sc_buf, VIORND_BUFSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_READ)) {
		printf(": Can't load dmamap\n");
		goto err2;
	}

	if (virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1,
	    "Entropy request") != 0) {
		printf(": Can't alloc virtqueue\n");
		goto err2;
	}

	sc->sc_vq.vq_done = viornd_vq_done;
	virtio_start_vq_intr(vsc, &sc->sc_vq);
	timeout_set(&sc->sc_tick, viornd_tick, sc);
	timeout_add(&sc->sc_tick, 1);

	printf("\n");
	return;
err2:
	bus_dmamap_destroy(vsc->sc_dmat, sc->sc_dmamap);
err:
	vsc->sc_child = VIRTIO_CHILD_ERROR;
	if (sc->sc_buf != NULL) {
		dma_free(sc->sc_buf, VIORND_BUFSIZE);
		sc->sc_buf = NULL;
	}
	return;
}
Ejemplo n.º 26
0
int
sd_ioctl_cache(struct sd_softc *sc, long cmd, struct dk_cache *dkc)
{
	union scsi_mode_sense_buf *buf;
	struct page_caching_mode *mode = NULL;
	u_int wrcache, rdcache;
	int big;
	int rv;

	if (ISSET(sc->sc_link->flags, SDEV_UMASS))
		return (EOPNOTSUPP);

	/* see if the adapter has special handling */
	rv = scsi_do_ioctl(sc->sc_link, cmd, (caddr_t)dkc, 0);
	if (rv != ENOTTY)
		return (rv);

	buf = dma_alloc(sizeof(*buf), PR_WAITOK);
	if (buf == NULL)
		return (ENOMEM);

	rv = scsi_do_mode_sense(sc->sc_link, PAGE_CACHING_MODE,
	    buf, (void **)&mode, NULL, NULL, NULL,
	    sizeof(*mode) - 4, scsi_autoconf | SCSI_SILENT, &big);
	if (rv != 0)
		goto done;

	if ((mode == NULL) || (!DISK_PGCODE(mode, PAGE_CACHING_MODE))) {
		rv = EIO;
		goto done;
	}

	wrcache = (ISSET(mode->flags, PG_CACHE_FL_WCE) ? 1 : 0);
	rdcache = (ISSET(mode->flags, PG_CACHE_FL_RCD) ? 0 : 1);

	switch (cmd) {
	case DIOCGCACHE:
		dkc->wrcache = wrcache;
		dkc->rdcache = rdcache;
		break;

	case DIOCSCACHE:
		if (dkc->wrcache == wrcache && dkc->rdcache == rdcache)
			break;

		if (dkc->wrcache)
			SET(mode->flags, PG_CACHE_FL_WCE);
		else
			CLR(mode->flags, PG_CACHE_FL_WCE);

		if (dkc->rdcache)
			CLR(mode->flags, PG_CACHE_FL_RCD);
		else
			SET(mode->flags, PG_CACHE_FL_RCD);

		if (big) {
			rv = scsi_mode_select_big(sc->sc_link, SMS_PF,
			    &buf->hdr_big, scsi_autoconf | SCSI_SILENT, 20000);
		} else {
			rv = scsi_mode_select(sc->sc_link, SMS_PF,
			    &buf->hdr, scsi_autoconf | SCSI_SILENT, 20000);
		}
		break;
	}

done:
	dma_free(buf, sizeof(*buf));
	return (rv);
}
Ejemplo n.º 27
0
static struct net_device *
au1000_probe(u32 ioaddr, int irq, int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	struct net_device *dev = NULL;
	db_dest_t *pDB, *pDBfree;
	char *pmac, *argptr;
	char ethaddr[6];
	int i, err;

	if (!request_region(ioaddr, MAC_IOSIZE, "Au1x00 ENET"))
		return NULL;

	if (version_printed++ == 0) 
		printk(version);

	dev = alloc_etherdev(sizeof(struct au1000_private));
	if (!dev) {
		printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
		return NULL;
	}

	if ((err = register_netdev(dev))) {
		printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n",
				err);
		kfree(dev);
		return NULL;
	}

	printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", 
			dev->name, ioaddr, irq);

	aup = dev->priv;

	/* Allocate the data buffers */
	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
	if (!aup->vaddr) {
		kfree(dev);
		release_region(ioaddr, MAC_IOSIZE);
		return NULL;
	}

	/* aup->mac is the base address of the MAC's registers */
	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
	/* Setup some variables for quick register address access */
	if (ioaddr == iflist[0].base_addr)
	{
		/* check env variables first */
		if (!get_ethernet_addr(ethaddr)) { 
			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
		} else {
			/* Check command line */
			argptr = prom_getcmdline();
			if ((pmac = strstr(argptr, "ethaddr=")) == NULL) {
				printk(KERN_INFO "%s: No mac address found\n", 
						dev->name);
				/* use the hard coded mac addresses */
			} else {
				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
				memcpy(au1000_mac_addr, ethaddr, 
						sizeof(dev->dev_addr));
			}
		}
			aup->enable = (volatile u32 *) 
				((unsigned long)iflist[0].macen_addr);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
		aup->mac_id = 0;
		au_macs[0] = aup;
	}
		else
	if (ioaddr == iflist[1].base_addr)
	{
			aup->enable = (volatile u32 *) 
				((unsigned long)iflist[1].macen_addr);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		dev->dev_addr[4] += 0x10;
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
		aup->mac_id = 1;
		au_macs[1] = aup;
	}
	else
	{
		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
	}

	/* bring the device out of reset, otherwise probing the mii
	 * will hang */
	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);

	aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL);
	if (!aup->mii) {
		printk(KERN_ERR "%s: out of memory\n", dev->name);
		goto err_out;
	}
	aup->mii->mii_control_reg = 0;
	aup->mii->mii_data_reg = 0;

	if (mii_probe(dev) != 0) {
		goto err_out;
	}

	pDBfree = NULL;
	/* setup the data buffer descriptors and attach a buffer to each one */
	pDB = aup->db;
	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i = 0; i < NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	spin_lock_init(&aup->lock);
	dev->base_addr = ioaddr;
	dev->irq = irq;
	dev->open = au1000_open;
	dev->hard_start_xmit = au1000_tx;
	dev->stop = au1000_close;
	dev->get_stats = au1000_get_stats;
	dev->set_multicast_list = &set_rx_mode;
	dev->do_ioctl = &au1000_ioctl;
	dev->set_config = &au1000_set_config;
	dev->tx_timeout = au1000_tx_timeout;
	dev->watchdog_timeo = ETH_TX_TIMEOUT;

	/* 
	 * The boot code uses the ethernet controller, so reset it to start 
	 * fresh.  au1000_init() expects that the device is in reset state.
	 */
	reset_mac(dev);

	return dev;

err_out:
	/* here we should have a valid dev plus aup-> register addresses
	 * so we can reset the mac properly.*/
	reset_mac(dev);
	if (aup->mii)
		kfree(aup->mii);
	for (i = 0; i < NUM_RX_DMA; i++) {
		if (aup->rx_db_inuse[i])
			ReleaseDB(aup, aup->rx_db_inuse[i]);
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		if (aup->tx_db_inuse[i])
			ReleaseDB(aup, aup->tx_db_inuse[i]);
	}
	dma_free((void *)aup->vaddr, MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS));
	unregister_netdev(dev);
	kfree(dev);
	release_region(ioaddr, MAC_IOSIZE);
	return NULL;
}
Ejemplo n.º 28
0
static int au1k_irda_net_init(struct net_device *dev)
{
	struct au1k_private *aup = NULL;
	int i, retval = 0, err;
	db_dest_t *pDB, *pDBfree;
	dma_addr_t temp;

	dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL);
	if (dev->priv == NULL) {
		retval = -ENOMEM;
		goto out;
	}
	memset(dev->priv, 0, sizeof(struct au1k_private));
	aup = dev->priv;

	err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
	if (err)
		goto out;

	dev->open = au1k_irda_start;
	dev->hard_start_xmit = au1k_irda_hard_xmit;
	dev->stop = au1k_irda_stop;
	dev->get_stats = au1k_irda_stats;
	dev->do_ioctl = au1k_irda_ioctl;
	dev->tx_timeout = au1k_tx_timeout;

	irda_device_setup(dev);
	irda_init_max_qos_capabilies(&aup->qos);

	/* The only value we must override it the baudrate */
	aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
		IR_115200|IR_576000 |(IR_4000000 << 8);
	
	aup->qos.min_turn_time.bits = qos_mtt_bits;
	irda_qos_bits_to_value(&aup->qos);


	/* Tx ring follows rx ring + 512 bytes */
	/* we need a 1k aligned buffer */
	aup->rx_ring[0] = (ring_dest_t *)
		dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);

	/* allocate the data buffers */
	aup->db[0].vaddr = 
		(void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
	if (!aup->db[0].vaddr || !aup->rx_ring[0]) {
		retval = -ENOMEM;
		goto out;
	}

	setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);

	pDBfree = NULL;
	pDB = aup->db;
	for (i=0; i<(2*NUM_IR_DESC); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = 
			(u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	/* attach a data buffer to each descriptor */
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->rx_db_inuse[i] = pDB;
	}
	for (i=0; i<NUM_IR_DESC; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto out;
		aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
		aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
		aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
		aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
		aup->tx_ring[i]->count_0 = 0;
		aup->tx_ring[i]->count_1 = 0;
		aup->tx_ring[i]->flags = 0;
		aup->tx_db_inuse[i] = pDB;
	}

#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
	/* power on */
	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
	bcsr->resets |= BCSR_RESETS_IRDA_MODE_FULL;
	au_sync();
#endif

	return 0;

out:
	if (aup->db[0].vaddr) 
		dma_free((void *)aup->db[0].vaddr, 
				MAX_BUF_SIZE * 2*NUM_IR_DESC);
	if (aup->rx_ring[0])
		kfree((void *)aup->rx_ring[0]);
	if (aup->rx_buff.head)
		kfree(aup->rx_buff.head);
	if (dev->priv != NULL)
		kfree(dev->priv);
	unregister_netdevice(dev);
	printk(KERN_ERR "%s: au1k_init_module failed.  Returns %d\n",
	       dev->name, retval);
	return retval;
}
Ejemplo n.º 29
0
static int __init
au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	int i, retval = 0;
	db_dest_t *pDB, *pDBfree;
	char *pmac, *argptr;
	char ethaddr[6];

	if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) {
		 return -ENODEV;
	}

	if (version_printed++ == 0) printk(version);

	if (!dev) {
		dev = init_etherdev(0, sizeof(struct au1000_private));
	}
	if (!dev) {
		 printk (KERN_ERR "au1000 eth: init_etherdev failed\n");  
		 return -ENODEV;
	}

	printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
			dev->name, ioaddr, irq);

	/* Initialize our private structure */
	if (dev->priv == NULL) {
		aup = (struct au1000_private *) 
			kmalloc(sizeof(*aup), GFP_KERNEL);
		if (aup == NULL) {
			retval = -ENOMEM;
			goto free_region;
		}
		dev->priv = aup;
	}

	aup = dev->priv;
	memset(aup, 0, sizeof(*aup));


	/* Allocate the data buffers */
	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
	if (!aup->vaddr) {
		retval = -ENOMEM;
		goto free_region;
	}

	/* aup->mac is the base address of the MAC's registers */
	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
	/* Setup some variables for quick register address access */
	switch (ioaddr) {
	case AU1000_ETH0_BASE:
	case AU1500_ETH0_BASE:
		/* check env variables first */
		if (!get_ethernet_addr(ethaddr)) { 
			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
		} else {
			/* Check command line */
			argptr = prom_getcmdline();
			if ((pmac = strstr(argptr, "ethaddr=")) == NULL) {
				printk(KERN_INFO "%s: No mac address found\n", 
						dev->name);
				/* use the hard coded mac addresses */
			} else {
				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
				memcpy(au1000_mac_addr, ethaddr, 
						sizeof(dev->dev_addr));
			}
		}
		if (ioaddr == AU1000_ETH0_BASE)
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1000_MAC0_ENABLE);
		else
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1500_MAC0_ENABLE);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
			break;
	case AU1000_ETH1_BASE:
	case AU1500_ETH1_BASE:
		if (ioaddr == AU1000_ETH1_BASE)
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1000_MAC1_ENABLE);
		else
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1500_MAC1_ENABLE);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		dev->dev_addr[4] += 0x10;
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
			break;
	default:
		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
		break;

	}

	aup->phy_addr = PHY_ADDRESS;

	/* bring the device out of reset, otherwise probing the mii
	 * will hang */
	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);

	if (mii_probe(dev) != 0) {
		 goto free_region;
	}

	pDBfree = NULL;
	/* setup the data buffer descriptors and attach a buffer to each one */
	pDB = aup->db;
	for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i=0; i<NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto free_region;
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i=0; i<NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto free_region;
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	spin_lock_init(&aup->lock);
	dev->base_addr = ioaddr;
	dev->irq = irq;
	dev->open = au1000_open;
	dev->hard_start_xmit = au1000_tx;
	dev->stop = au1000_close;
	dev->get_stats = au1000_get_stats;
	dev->set_multicast_list = &set_rx_mode;
	dev->do_ioctl = &au1000_ioctl;
	dev->set_config = &au1000_set_config;
	dev->tx_timeout = au1000_tx_timeout;
	dev->watchdog_timeo = ETH_TX_TIMEOUT;


	/* Fill in the fields of the device structure with ethernet values. */
	ether_setup(dev);

	/* 
	 * The boot code uses the ethernet controller, so reset it to start 
	 * fresh.  au1000_init() expects that the device is in reset state.
	 */
	reset_mac(dev);
	return 0;

free_region:
	release_region(ioaddr, MAC_IOSIZE);
	unregister_netdev(dev);
	if (aup->vaddr) 
		dma_free((void *)aup->vaddr, 
				MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
	if (dev->priv != NULL)
		kfree(dev->priv);
	printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
	       dev->name, retval);
	kfree(dev);
	return retval;
}
Ejemplo n.º 30
0
Archivo: ata.c Proyecto: bluhm/sys
/* Get the disk's parameters */
int
ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
    struct ataparams *prms)
{
	char *tb;
	struct wdc_command wdc_c;
	int i;
	u_int16_t *p;
	int ret;

	WDCDEBUG_PRINT(("ata_get_params\n"), DEBUG_FUNCS);

	bzero(&wdc_c, sizeof(struct wdc_command));

	if (drvp->drive_flags & DRIVE_ATA) {
		wdc_c.r_command = WDCC_IDENTIFY;
		wdc_c.r_st_bmask = WDCS_DRDY;
		wdc_c.r_st_pmask = 0;
		wdc_c.timeout = 3000; /* 3s */
	} else if (drvp->drive_flags & DRIVE_ATAPI) {
		wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
		wdc_c.r_st_bmask = 0;
		wdc_c.r_st_pmask = 0;
		wdc_c.timeout = 10000; /* 10s */
	} else {
		WDCDEBUG_PRINT(("ata_get_params: no disks\n"),
		    DEBUG_FUNCS|DEBUG_PROBE);
		return CMD_ERR;
	}

	tb = dma_alloc(ATAPARAMS_SIZE, PR_NOWAIT | PR_ZERO);
	if (tb == NULL)
		return CMD_AGAIN;
	wdc_c.flags = AT_READ | flags;
	wdc_c.data = tb;
	wdc_c.bcount = ATAPARAMS_SIZE;

	if ((ret = wdc_exec_command(drvp, &wdc_c)) != WDC_COMPLETE) {
		WDCDEBUG_PRINT(("%s: wdc_exec_command failed: %d\n",
		    __func__, ret), DEBUG_PROBE);
		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_AGAIN;
	}

	if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
		WDCDEBUG_PRINT(("%s: IDENTIFY failed: 0x%x\n", __func__,
		    wdc_c.flags), DEBUG_PROBE);

		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_ERR;
	} else {
#if BYTE_ORDER == BIG_ENDIAN
		/* All the fields in the params structure are 16-bit
		   integers except for the ID strings which are char
		   strings.  The 16-bit integers are currently in
		   memory in little-endian, regardless of architecture.
		   So, they need to be swapped on big-endian architectures
		   before they are accessed through the ataparams structure.

		   The swaps below avoid touching the char strings.
		*/

		swap16_multi((u_int16_t *)tb, 10);
		swap16_multi((u_int16_t *)tb + 20, 3);
		swap16_multi((u_int16_t *)tb + 47, ATAPARAMS_SIZE / 2 - 47);
#endif
		/* Read in parameter block. */
		bcopy(tb, prms, sizeof(struct ataparams));

		/*
		 * Shuffle string byte order.
		 * ATAPI Mitsumi and NEC drives don't need this.
		 */
		if ((prms->atap_config & WDC_CFG_ATAPI_MASK) ==
		    WDC_CFG_ATAPI &&
		    ((prms->atap_model[0] == 'N' &&
			prms->atap_model[1] == 'E') ||
		     (prms->atap_model[0] == 'F' &&
			 prms->atap_model[1] == 'X'))) {
			dma_free(tb, ATAPARAMS_SIZE);
			return CMD_OK;
		}
		for (i = 0; i < sizeof(prms->atap_model); i += 2) {
			p = (u_short *)(prms->atap_model + i);
			*p = swap16(*p);
		}
		for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
			p = (u_short *)(prms->atap_serial + i);
			*p = swap16(*p);
		}
		for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
			p = (u_short *)(prms->atap_revision + i);
			*p = swap16(*p);
		}

		dma_free(tb, ATAPARAMS_SIZE);
		return CMD_OK;
	}
}