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); }
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); }
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); }
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)); }
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); }
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); }
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; }
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); }
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; }
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; }
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); }
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); }
/** * \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; }
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); }
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); }
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); }
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); }
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; }
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); }
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; }
/* * 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); }
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); }
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; }
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); }
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; }
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); }
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; }
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; }
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; }
/* 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; } }