diff options
Diffstat (limited to 'sys')
30 files changed, 395 insertions, 243 deletions
diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c index d7fcffa..ed501c5 100644 --- a/sys/arm/arm/busdma_machdep-v6.c +++ b/sys/arm/arm/busdma_machdep-v6.c @@ -858,8 +858,6 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) else ba = standard_allocator; - /* Be careful not to access map from here on. */ - bufzone = busdma_bufalloc_findzone(ba, dmat->maxsize); if (bufzone != NULL && dmat->alignment <= bufzone->size && diff --git a/sys/arm/ti/am335x/am335x_prcm.c b/sys/arm/ti/am335x/am335x_prcm.c index 65b7ba2..4b3a245 100644 --- a/sys/arm/ti/am335x/am335x_prcm.c +++ b/sys/arm/ti/am335x/am335x_prcm.c @@ -502,7 +502,7 @@ am335x_clk_gpio_activate(struct ti_clock_dev *clkdev) /* set *_CLKCTRL register MODULEMODE[1:0] to enable(2) */ /* set *_CLKCTRL register OPTFCLKEN_GPIO_1_G DBCLK[18] to FCLK_EN(1) */ prcm_write_4(clk_details->clkctrl_reg, 2 | (1 << 18)); - while ((prcm_read_4(clk_details->clkctrl_reg) & + while ((prcm_read_4(clk_details->clkctrl_reg) & (3 | (1 << 18) )) != (2 | (1 << 18))) DELAY(10); @@ -724,11 +724,11 @@ am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev) prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x4); /* Make sure it's in bypass mode */ - while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) + while (!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) & (1 << 8))) DELAY(10); - /* + /* * For now set frequency to 99*SYSFREQ/8 which is twice as * HDMI 1080p pixel clock (minimum LCDC freq divisor is 2) */ @@ -738,7 +738,7 @@ am335x_clk_lcdc_activate(struct ti_clock_dev *clkdev) prcm_write_4(CM_WKUP_CM_CLKMODE_DPLL_DISP, 0x7); int timeout = 10000; - while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) + while ((!(prcm_read_4(CM_WKUP_CM_IDLEST_DPLL_DISP) & (1 << 0))) && timeout--) DELAY(10); @@ -786,9 +786,9 @@ am335x_clk_pruss_activate(struct ti_clock_dev *clkdev) while ((prcm_read_4(CM_PER_PRUSS_CLKSTCTRL) & (1<<6)) == 0) DELAY(10); - /* Select DISP DPLL as OCP clock */ - prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 1); - while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 1) + /* Select L3F as OCP clock */ + prcm_write_4(CLKSEL_PRUSS_OCP_CLK, 0); + while ((prcm_read_4(CLKSEL_PRUSS_OCP_CLK) & 0x3) != 0) DELAY(10); /* Clear the RESET bit */ diff --git a/sys/boot/fdt/fdt_loader_cmd.c b/sys/boot/fdt/fdt_loader_cmd.c index dec9d52..aff2230 100644 --- a/sys/boot/fdt/fdt_loader_cmd.c +++ b/sys/boot/fdt/fdt_loader_cmd.c @@ -566,17 +566,6 @@ fdt_fixup_memory(struct fdt_mem_region *region, size_t num) return; } - if ((reg = (uint32_t *)fdt_getprop(fdtp, memory, "reg", - &len)) != NULL) { - - if (fdt_reg_valid(reg, len, addr_cells, size_cells) == 0) - /* - * Do not apply fixup if existing 'reg' property - * seems to be valid. - */ - return; - } - len = (addr_cells + size_cells) * realmrno * sizeof(uint32_t); sb = buf = (uint8_t *)malloc(len); if (!buf) diff --git a/sys/boot/powerpc/kboot/host_syscall.S b/sys/boot/powerpc/kboot/host_syscall.S index 9e8a797..3607fdb 100644 --- a/sys/boot/powerpc/kboot/host_syscall.S +++ b/sys/boot/powerpc/kboot/host_syscall.S @@ -1,3 +1,8 @@ +/* + * + * $FreeBSD$ + */ + #include <machine/asm.h> ENTRY(host_read) @@ -16,7 +21,10 @@ ENTRY(host_write) blr ENTRY(host_seek) - li %r0, 19 # SYS_lseek + mr %r4,%r5 + mr %r5,%r6 + mr %r6,%r7 + li %r0, 140 # SYS_llseek sc blr diff --git a/sys/boot/powerpc/kboot/host_syscall.h b/sys/boot/powerpc/kboot/host_syscall.h index 58518a9..0d47bd5 100644 --- a/sys/boot/powerpc/kboot/host_syscall.h +++ b/sys/boot/powerpc/kboot/host_syscall.h @@ -32,7 +32,7 @@ ssize_t host_read(int fd, void *buf, size_t nbyte); ssize_t host_write(int fd, const void *buf, size_t nbyte); -ssize_t host_seek(int fd, int offset, int whence); +ssize_t host_seek(int fd, int64_t offset, int whence); int host_open(char *path, int flags, int mode); int host_close(int fd); void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, int); diff --git a/sys/boot/powerpc/kboot/hostdisk.c b/sys/boot/powerpc/kboot/hostdisk.c index c6be8af..2deb956 100644 --- a/sys/boot/powerpc/kboot/hostdisk.c +++ b/sys/boot/powerpc/kboot/hostdisk.c @@ -40,7 +40,7 @@ static int hostdisk_ioctl(struct open_file *f, u_long cmd, void *data); static void hostdisk_print(int verbose); struct devsw hostdisk = { - "s", + "/dev", DEVT_DISK, hostdisk_init, hostdisk_strategy, @@ -67,8 +67,10 @@ hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, pos = dblk * 512; - if (host_seek(desc->d_unit, pos, 0) < 0) + if (host_seek(desc->d_unit, pos, 0) < 0) { + printf("Seek error\n"); return (EIO); + } n = host_read(desc->d_unit, buf, size); if (n < 0) @@ -82,22 +84,19 @@ static int hostdisk_open(struct open_file *f, ...) { struct devdesc *desc; - char *path; va_list vl; va_start(vl, f); desc = va_arg(vl, struct devdesc *); va_end(vl); - path = malloc(strlen((char *)(desc->d_opendata)) + 6); - strcpy(path, "/dev/"); - strcat(path, (char *)(desc->d_opendata)); + desc->d_unit = host_open(desc->d_opendata, O_RDONLY, 0); - desc->d_unit = host_open(path, O_RDONLY, 0); - free(path); - - if (desc->d_unit <= 0) + if (desc->d_unit <= 0) { + printf("hostdisk_open: couldn't open %s: %d\n", + desc->d_opendata, desc->d_unit); return (ENOENT); + } return (0); } diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index fb66b45..e6305aa 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -398,12 +398,11 @@ static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, struct ctl_ooa_entry *kern_entries); static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td); -static uint32_t ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun); -static uint32_t ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun); static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun, struct ctl_be_lun *be_lun, struct ctl_id target_id); static int ctl_free_lun(struct ctl_lun *lun); static void ctl_create_lun(struct ctl_be_lun *be_lun); +static struct ctl_port * ctl_io_port(struct ctl_io_hdr *io_hdr); /** static void ctl_failover_change_pages(struct ctl_softc *softc, struct ctl_scsiio *ctsio, int master); @@ -3411,6 +3410,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct ctl_lun_list *list; struct ctl_option *opt; int j; + uint32_t plun; list = (struct ctl_lun_list *)addr; @@ -3491,6 +3491,18 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, break; } + if (port->lun_map != NULL) { + sbuf_printf(sb, "\t<lun_map>on</lun_map>\n"); + for (j = 0; j < CTL_MAX_LUNS; j++) { + plun = ctl_lun_map_from_port(port, j); + if (plun >= CTL_MAX_LUNS) + continue; + sbuf_printf(sb, + "\t<lun id=\"%u\">%u</lun>\n", + j, plun); + } + } + for (j = 0; j < CTL_MAX_INIT_PER_PORT; j++) { if (port->wwpn_iid[j].in_use == 0 || (port->wwpn_iid[j].wwpn == 0 && @@ -3538,6 +3550,38 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, sbuf_delete(sb); break; } + case CTL_LUN_MAP: { + struct ctl_lun_map *lm = (struct ctl_lun_map *)addr; + struct ctl_port *port; + + mtx_lock(&softc->ctl_lock); + if (lm->port >= CTL_MAX_PORTS || + (port = softc->ctl_ports[lm->port]) == NULL) { + mtx_unlock(&softc->ctl_lock); + return (ENXIO); + } + if (lm->plun < CTL_MAX_LUNS) { + if (lm->lun == UINT32_MAX) + retval = ctl_lun_map_unset(port, lm->plun); + else if (lm->lun < CTL_MAX_LUNS && + softc->ctl_luns[lm->lun] != NULL) + retval = ctl_lun_map_set(port, lm->plun, lm->lun); + else { + mtx_unlock(&softc->ctl_lock); + return (ENXIO); + } + } else if (lm->plun == UINT32_MAX) { + if (lm->lun == UINT32_MAX) + retval = ctl_lun_map_deinit(port); + else + retval = ctl_lun_map_init(port); + } else { + mtx_unlock(&softc->ctl_lock); + return (ENXIO); + } + mtx_unlock(&softc->ctl_lock); + break; + } default: { /* XXX KDM should we fix this? */ #if 0 @@ -3602,35 +3646,106 @@ ctl_port_idx(int port_num) return(port_num - CTL_MAX_PORTS); } -static uint32_t -ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun_id) +int +ctl_lun_map_init(struct ctl_port *port) +{ + uint32_t i; + + if (port->lun_map == NULL) + port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS, + M_CTL, M_NOWAIT); + if (port->lun_map == NULL) + return (ENOMEM); + for (i = 0; i < CTL_MAX_LUNS; i++) + port->lun_map[i] = UINT32_MAX; + return (0); +} + +int +ctl_lun_map_deinit(struct ctl_port *port) +{ + + if (port->lun_map == NULL) + return (0); + free(port->lun_map, M_CTL); + port->lun_map = NULL; + return (0); +} + +int +ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun) +{ + int status; + + if (port->lun_map == NULL) { + status = ctl_lun_map_init(port); + if (status != 0) + return (status); + } + port->lun_map[plun] = glun; + return (0); +} + +int +ctl_lun_map_unset(struct ctl_port *port, uint32_t plun) +{ + + if (port->lun_map == NULL) + return (0); + port->lun_map[plun] = UINT32_MAX; + return (0); +} + +int +ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun) +{ + int i; + + if (port->lun_map == NULL) + return (0); + for (i = 0; i < CTL_MAX_LUNS; i++) { + if (port->lun_map[i] == glun) + port->lun_map[i] = UINT32_MAX; + } + return (0); +} + +uint32_t +ctl_lun_map_from_port(struct ctl_port *port, uint32_t lun_id) { - struct ctl_port *port; - port = softc->ctl_ports[ctl_port_idx(port_num)]; if (port == NULL) return (UINT32_MAX); - if (port->lun_map == NULL) + if (port->lun_map == NULL || lun_id >= CTL_MAX_LUNS) return (lun_id); - return (port->lun_map(port->targ_lun_arg, lun_id)); + return (port->lun_map[lun_id]); } -static uint32_t -ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun_id) +uint32_t +ctl_lun_map_to_port(struct ctl_port *port, uint32_t lun_id) { - struct ctl_port *port; uint32_t i; - port = softc->ctl_ports[ctl_port_idx(port_num)]; + if (port == NULL) + return (UINT32_MAX); if (port->lun_map == NULL) return (lun_id); for (i = 0; i < CTL_MAX_LUNS; i++) { - if (port->lun_map(port->targ_lun_arg, i) == lun_id) + if (port->lun_map[i] == lun_id) return (i); } return (UINT32_MAX); } +static struct ctl_port * +ctl_io_port(struct ctl_io_hdr *io_hdr) +{ + int port_num; + + port_num = io_hdr->nexus.targ_port; + return (control_softc->ctl_ports[ctl_port_idx(port_num)]); +} + /* * Note: This only works for bitmask sizes that are at least 32 bits, and * that are a power of 2. @@ -4676,9 +4791,7 @@ static int ctl_free_lun(struct ctl_lun *lun) { struct ctl_softc *softc; -#if 0 struct ctl_port *port; -#endif struct ctl_lun *nlun; int i; @@ -4686,6 +4799,9 @@ ctl_free_lun(struct ctl_lun *lun) mtx_assert(&softc->ctl_lock, MA_OWNED); + STAILQ_FOREACH(port, &softc->port_list, links) + ctl_lun_map_unsetg(port, lun->lun); + STAILQ_REMOVE(&softc->lun_list, lun, ctl_lun, links); ctl_clear_mask(softc->ctl_lun_mask, lun->lun); @@ -7343,8 +7459,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) STAILQ_FOREACH(port, &softc->port_list, links) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; - if (ctl_map_lun_back(softc, port->targ_port, lun->lun) >= - CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) continue; num_target_ports++; } @@ -7417,8 +7532,7 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) STAILQ_FOREACH(port, &softc->port_list, links) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; - if (ctl_map_lun_back(softc, port->targ_port, lun->lun) - >= CTL_MAX_LUNS) + if (ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) continue; p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS; scsi_ulto2b(p, tpg_desc->descriptors[pc]. @@ -9260,6 +9374,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio) struct scsi_report_luns *cdb; struct scsi_report_luns_data *lun_data; struct ctl_lun *lun, *request_lun; + struct ctl_port *port; int num_luns, retval; uint32_t alloc_len, lun_datalen; int num_filled, well_known; @@ -9316,6 +9431,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio) request_lun = (struct ctl_lun *) ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + port = ctl_io_port(&ctsio->io_hdr); lun_datalen = sizeof(*lun_data) + (num_luns * sizeof(struct scsi_report_luns_lundata)); @@ -9328,8 +9444,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio) mtx_lock(&softc->ctl_lock); for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) { - lun_id = ctl_map_lun(softc, ctsio->io_hdr.nexus.targ_port, - targ_lun_id); + lun_id = ctl_lun_map_from_port(port, targ_lun_id); if (lun_id >= CTL_MAX_LUNS) continue; lun = softc->ctl_luns[lun_id]; @@ -10014,8 +10129,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_map_lun_back(softc, port->targ_port, lun->lun) >= - CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) continue; num_target_ports++; if (port->init_devid) @@ -10068,8 +10182,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_map_lun_back(softc, port->targ_port, lun->lun) - >= CTL_MAX_LUNS) + ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) continue; p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS; scsi_ulto2b(p, pd->relative_port_id); @@ -13745,6 +13858,7 @@ int ctl_queue_sense(union ctl_io *io) { struct ctl_lun *lun; + struct ctl_port *port; struct ctl_softc *softc; uint32_t initidx, targ_lun; @@ -13765,8 +13879,8 @@ ctl_queue_sense(union ctl_io *io) * If we don't have a LUN for this, just toss the sense * information. */ - targ_lun = io->io_hdr.nexus.targ_lun; - targ_lun = ctl_map_lun(softc, io->io_hdr.nexus.targ_port, targ_lun); + port = ctl_io_port(&ctsio->io_hdr); + targ_lun = ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun); if ((targ_lun < CTL_MAX_LUNS) && (softc->ctl_luns[targ_lun] != NULL)) lun = softc->ctl_luns[targ_lun]; @@ -13806,6 +13920,7 @@ bailout: int ctl_queue(union ctl_io *io) { + struct ctl_port *port; CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0])); @@ -13815,9 +13930,9 @@ ctl_queue(union ctl_io *io) #endif /* CTL_TIME_IO */ /* Map FE-specific LUN ID into global one. */ + port = ctl_io_port(&io->io_hdr); io->io_hdr.nexus.targ_mapped_lun = - ctl_map_lun(control_softc, io->io_hdr.nexus.targ_port, - io->io_hdr.nexus.targ_lun); + ctl_lun_map_from_port(port, io->io_hdr.nexus.targ_lun); switch (io->io_hdr.io_type) { case CTL_IO_SCSI: diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c index 982675e..c38e527 100644 --- a/sys/cam/ctl/ctl_frontend.c +++ b/sys/cam/ctl/ctl_frontend.c @@ -234,6 +234,7 @@ ctl_port_deregister(struct ctl_port *port) ctl_pool_free(pool); ctl_free_opts(&port->options); + ctl_lun_map_deinit(port); free(port->port_devid, M_CTL); port->port_devid = NULL; free(port->target_devid, M_CTL); diff --git a/sys/cam/ctl/ctl_frontend.h b/sys/cam/ctl/ctl_frontend.h index 06ae5a1..f1cc1c4 100644 --- a/sys/cam/ctl/ctl_frontend.h +++ b/sys/cam/ctl/ctl_frontend.h @@ -51,7 +51,6 @@ typedef void (*fe_shutdown_t)(void); typedef void (*port_func_t)(void *onoff_arg); typedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb); typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id); -typedef uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id); typedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td); @@ -226,7 +225,7 @@ struct ctl_port { void *onoff_arg; /* passed to CTL */ lun_func_t lun_enable; /* passed to CTL */ lun_func_t lun_disable; /* passed to CTL */ - lun_map_func_t lun_map; /* passed to CTL */ + uint32_t *lun_map; /* passed to CTL */ void *targ_lun_arg; /* passed to CTL */ void (*fe_datamove)(union ctl_io *io); /* passed to CTL */ void (*fe_done)(union ctl_io *io); /* passed to CTL */ diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 99d698b..a922d5b 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -151,7 +151,6 @@ static int cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id); static int cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id); -static uint32_t cfiscsi_lun_map(void *arg, uint32_t lun); static int cfiscsi_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td); static void cfiscsi_datamove(union ctl_io *io); @@ -2031,7 +2030,6 @@ cfiscsi_ioctl_port_create(struct ctl_req *req) port->onoff_arg = ct; port->lun_enable = cfiscsi_lun_enable; port->lun_disable = cfiscsi_lun_disable; - port->lun_map = cfiscsi_lun_map; port->targ_lun_arg = ct; port->fe_datamove = cfiscsi_datamove; port->fe_done = cfiscsi_done; @@ -2081,7 +2079,7 @@ cfiscsi_ioctl_port_create(struct ctl_req *req) free(port->target_devid, M_CFISCSI); req->status = CTL_LUN_ERROR; snprintf(req->error_str, sizeof(req->error_str), - "ctl_frontend_register() failed with error %d", retval); + "ctl_port_register() failed with error %d", retval); return; } done: @@ -2259,7 +2257,6 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name, const char *alias) { struct cfiscsi_target *ct, *newct; - int i; if (name[0] == '\0' || strlen(name) >= CTL_ISCSI_NAME_LEN) return (NULL); @@ -2277,9 +2274,6 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name, return (ct); } - for (i = 0; i < CTL_MAX_LUNS; i++) - newct->ct_luns[i] = UINT32_MAX; - strlcpy(newct->ct_name, name, sizeof(newct->ct_name)); if (alias != NULL) strlcpy(newct->ct_alias, alias, sizeof(newct->ct_alias)); @@ -2294,108 +2288,17 @@ cfiscsi_target_find_or_create(struct cfiscsi_softc *softc, const char *name, return (newct); } -/* - * Takes LUN from the target space and returns LUN from the CTL space. - */ -static uint32_t -cfiscsi_lun_map(void *arg, uint32_t lun) -{ - struct cfiscsi_target *ct = arg; - - if (lun >= CTL_MAX_LUNS) { - CFISCSI_DEBUG("requested lun number %d is higher " - "than maximum %d", lun, CTL_MAX_LUNS - 1); - return (UINT32_MAX); - } - return (ct->ct_luns[lun]); -} - -static int -cfiscsi_target_set_lun(struct cfiscsi_target *ct, - unsigned long lun_id, unsigned long ctl_lun_id) -{ - - if (lun_id >= CTL_MAX_LUNS) { - CFISCSI_WARN("requested lun number %ld is higher " - "than maximum %d", lun_id, CTL_MAX_LUNS - 1); - return (-1); - } - - if (ct->ct_luns[lun_id] < CTL_MAX_LUNS) { - /* - * CTL calls cfiscsi_lun_enable() twice for each LUN - once - * when the LUN is created, and a second time just before - * the port is brought online; don't emit warnings - * for that case. - */ - if (ct->ct_luns[lun_id] == ctl_lun_id) - return (0); - CFISCSI_WARN("lun %ld already allocated", lun_id); - return (-1); - } - -#if 0 - CFISCSI_DEBUG("adding mapping for lun %ld, target %s " - "to ctl lun %ld", lun_id, ct->ct_name, ctl_lun_id); -#endif - - ct->ct_luns[lun_id] = ctl_lun_id; - - return (0); -} - static int cfiscsi_lun_enable(void *arg, struct ctl_id target_id, int lun_id) { - struct cfiscsi_softc *softc; - struct cfiscsi_target *ct; - const char *target = NULL; - const char *lun = NULL; - unsigned long tmp; - - ct = (struct cfiscsi_target *)arg; - softc = ct->ct_softc; - - target = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options, - "cfiscsi_target"); - lun = ctl_get_opt(&control_softc->ctl_luns[lun_id]->be_lun->options, - "cfiscsi_lun"); - if (target == NULL && lun == NULL) - return (0); - - if (target == NULL || lun == NULL) { - CFISCSI_WARN("lun added with cfiscsi_target, but without " - "cfiscsi_lun, or the other way around; ignoring"); - return (0); - } - - if (strcmp(target, ct->ct_name) != 0) - return (0); - - tmp = strtoul(lun, NULL, 10); - cfiscsi_target_set_lun(ct, tmp, lun_id); return (0); } static int cfiscsi_lun_disable(void *arg, struct ctl_id target_id, int lun_id) { - struct cfiscsi_softc *softc; - struct cfiscsi_target *ct; - int i; - - ct = (struct cfiscsi_target *)arg; - softc = ct->ct_softc; - mtx_lock(&softc->lock); - for (i = 0; i < CTL_MAX_LUNS; i++) { - if (ct->ct_luns[i] != lun_id) - continue; - ct->ct_luns[i] = UINT32_MAX; - break; - } - mtx_unlock(&softc->lock); return (0); } diff --git a/sys/cam/ctl/ctl_frontend_iscsi.h b/sys/cam/ctl/ctl_frontend_iscsi.h index 5000f4c..02fd34e 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.h +++ b/sys/cam/ctl/ctl_frontend_iscsi.h @@ -38,7 +38,6 @@ struct cfiscsi_target { TAILQ_ENTRY(cfiscsi_target) ct_next; - uint32_t ct_luns[CTL_MAX_LUNS]; struct cfiscsi_softc *ct_softc; volatile u_int ct_refcount; char ct_name[CTL_ISCSI_NAME_LEN]; diff --git a/sys/cam/ctl/ctl_ioctl.h b/sys/cam/ctl/ctl_ioctl.h index 3093efd..532953f 100644 --- a/sys/cam/ctl/ctl_ioctl.h +++ b/sys/cam/ctl/ctl_ioctl.h @@ -805,6 +805,12 @@ struct ctl_iscsi { /* passed to userland */ }; +struct ctl_lun_map { + uint32_t port; + uint32_t plun; + uint32_t lun; +}; + #define CTL_IO _IOWR(CTL_MINOR, 0x00, union ctl_io) #define CTL_ENABLE_PORT _IOW(CTL_MINOR, 0x04, struct ctl_port_entry) #define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, struct ctl_port_entry) @@ -832,6 +838,7 @@ struct ctl_iscsi { #define CTL_ISCSI _IOWR(CTL_MINOR, 0x25, struct ctl_iscsi) #define CTL_PORT_REQ _IOWR(CTL_MINOR, 0x26, struct ctl_req) #define CTL_PORT_LIST _IOWR(CTL_MINOR, 0x27, struct ctl_lun_list) +#define CTL_LUN_MAP _IOW(CTL_MINOR, 0x28, struct ctl_lun_map) #endif /* _CTL_IOCTL_H_ */ diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index 7bedf10..ffcb063 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -492,6 +492,13 @@ extern const struct ctl_cmd_entry ctl_cmd_table[256]; uint32_t ctl_get_initindex(struct ctl_nexus *nexus); uint32_t ctl_get_resindex(struct ctl_nexus *nexus); uint32_t ctl_port_idx(int port_num); +int ctl_lun_map_init(struct ctl_port *port); +int ctl_lun_map_deinit(struct ctl_port *port); +int ctl_lun_map_set(struct ctl_port *port, uint32_t plun, uint32_t glun); +int ctl_lun_map_unset(struct ctl_port *port, uint32_t plun); +int ctl_lun_map_unsetg(struct ctl_port *port, uint32_t glun); +uint32_t ctl_lun_map_from_port(struct ctl_port *port, uint32_t plun); +uint32_t ctl_lun_map_to_port(struct ctl_port *port, uint32_t glun); int ctl_pool_create(struct ctl_softc *ctl_softc, const char *pool_name, uint32_t total_ctl_io, void **npool); void ctl_pool_free(struct ctl_io_pool *pool); diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c index 63360fe..a254418 100644 --- a/sys/cam/ctl/ctl_tpc_local.c +++ b/sys/cam/ctl/ctl_tpc_local.c @@ -314,48 +314,30 @@ tpcl_resolve(struct ctl_softc *softc, int init_port, struct scsi_ec_cscd_id *cscdid; struct ctl_port *port; struct ctl_lun *lun; - uint64_t lunid = UINT64_MAX, l; - int i; + uint64_t lunid = UINT64_MAX; if (cscd->type_code != EC_CSCD_ID) return (lunid); cscdid = (struct scsi_ec_cscd_id *)cscd; mtx_lock(&softc->ctl_lock); - if (init_port >= 0) { + if (init_port >= 0) port = softc->ctl_ports[ctl_port_idx(init_port)]; - if (port == NULL || port->lun_map == NULL) - init_port = -1; - } - if (init_port < 0) { - STAILQ_FOREACH(lun, &softc->lun_list, links) { - if (lun->lun_devid == NULL) - continue; - if (scsi_devid_match(lun->lun_devid->data, - lun->lun_devid->len, &cscdid->codeset, - cscdid->length + 4) == 0) { - lunid = lun->lun; - if (ss && lun->be_lun) - *ss = lun->be_lun->blocksize; - break; - } - } - } else { - for (i = 0; i < CTL_MAX_LUNS; i++) { - l = port->lun_map(port->targ_lun_arg, i); - if (l >= CTL_MAX_LUNS) - continue; - lun = softc->ctl_luns[l]; - if (lun == NULL || lun->lun_devid == NULL) - continue; - if (scsi_devid_match(lun->lun_devid->data, - lun->lun_devid->len, &cscdid->codeset, - cscdid->length + 4) == 0) { - lunid = lun->lun; - if (ss && lun->be_lun) - *ss = lun->be_lun->blocksize; - break; - } + else + port = NULL; + STAILQ_FOREACH(lun, &softc->lun_list, links) { + if (port != NULL && + ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS) + continue; + if (lun->lun_devid == NULL) + continue; + if (scsi_devid_match(lun->lun_devid->data, + lun->lun_devid->len, &cscdid->codeset, + cscdid->length + 4) == 0) { + lunid = lun->lun; + if (ss && lun->be_lun) + *ss = lun->be_lun->blocksize; + break; } } mtx_unlock(&softc->ctl_lock); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index a94404b..212c270 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -2677,7 +2677,7 @@ extern kmem_cache_t *zio_buf_cache[]; extern kmem_cache_t *zio_data_buf_cache[]; extern kmem_cache_t *range_seg_cache; -static void __noinline +static __noinline void arc_kmem_reap_now(arc_reclaim_strategy_t strat) { size_t i; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c index 5ab3232..b0d4937 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c @@ -353,7 +353,7 @@ txg_rele_to_sync(txg_handle_t *th) * On return, the transaction group has reached a stable state in which it can * then be passed off to the syncing context. */ -static void +static __noinline void txg_quiesce(dsl_pool_t *dp, uint64_t txg) { tx_state_t *tx = &dp->dp_tx; diff --git a/sys/conf/options b/sys/conf/options index a8802af..c23f8f0 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -651,6 +651,7 @@ USB_HOST_ALIGN opt_usb.h USB_REQ_DEBUG opt_usb.h USB_TEMPLATE opt_usb.h USB_VERBOSE opt_usb.h +USB_DMA_SINGLE_ALLOC opt_usb.h USB_EHCI_BIG_ENDIAN_DESC opt_usb.h U3G_DEBUG opt_u3g.h UKBD_DFLT_KEYMAP opt_ukbd.h diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index 79b8a56..755fdc5 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -556,26 +556,27 @@ enum ahci_err_type { bus_write_multi_stream_4((res), (offset), (addr), (count)) -#define AHCI_Q_NOFORCE 1 -#define AHCI_Q_NOPMP 2 -#define AHCI_Q_NONCQ 4 -#define AHCI_Q_1CH 8 -#define AHCI_Q_2CH 0x10 -#define AHCI_Q_4CH 0x20 -#define AHCI_Q_EDGEIS 0x40 -#define AHCI_Q_SATA2 0x80 -#define AHCI_Q_NOBSYRES 0x100 -#define AHCI_Q_NOAA 0x200 -#define AHCI_Q_NOCOUNT 0x400 -#define AHCI_Q_ALTSIG 0x800 -#define AHCI_Q_NOMSI 0x1000 -#define AHCI_Q_ATI_PMP_BUG 0x2000 -#define AHCI_Q_MAXIO_64K 0x4000 -#define AHCI_Q_SATA1_UNIT0 0x8000 /* need better method for this */ -#define AHCI_Q_ABAR0 0x10000 +#define AHCI_Q_NOFORCE 0x00000001 +#define AHCI_Q_NOPMP 0x00000002 +#define AHCI_Q_NONCQ 0x00000004 +#define AHCI_Q_1CH 0x00000008 +#define AHCI_Q_2CH 0x00000010 +#define AHCI_Q_4CH 0x00000020 +#define AHCI_Q_EDGEIS 0x00000040 +#define AHCI_Q_SATA2 0x00000080 +#define AHCI_Q_NOBSYRES 0x00000100 +#define AHCI_Q_NOAA 0x00000200 +#define AHCI_Q_NOCOUNT 0x00000400 +#define AHCI_Q_ALTSIG 0x00000800 +#define AHCI_Q_NOMSI 0x00001000 +#define AHCI_Q_ATI_PMP_BUG 0x00002000 +#define AHCI_Q_MAXIO_64K 0x00004000 +#define AHCI_Q_SATA1_UNIT0 0x00008000 /* need better method for this */ +#define AHCI_Q_ABAR0 0x00010000 +#define AHCI_Q_1MSI 0x00020000 #define AHCI_Q_BIT_STRING \ - "\020" \ + "\021" \ "\001NOFORCE" \ "\002NOPMP" \ "\003NONCQ" \ @@ -592,7 +593,8 @@ enum ahci_err_type { "\016ATI_PMP_BUG" \ "\017MAXIO_64K" \ "\020SATA1_UNIT0" \ - "\021ABAR0" + "\021ABAR0" \ + "\0221MSI" int ahci_attach(device_t dev); int ahci_detach(device_t dev); diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c index 8574e47..acde18d 100644 --- a/sys/dev/ahci/ahci_pci.c +++ b/sys/dev/ahci/ahci_pci.c @@ -55,12 +55,17 @@ static const struct { int quirks; } ahci_ids[] = { {0x43801002, 0x00, "AMD SB600", - AHCI_Q_NOMSI | AHCI_Q_ATI_PMP_BUG | AHCI_Q_MAXIO_64K}, - {0x43901002, 0x00, "AMD SB7x0/SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, - {0x43911002, 0x00, "AMD SB7x0/SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, - {0x43921002, 0x00, "AMD SB7x0/SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, - {0x43931002, 0x00, "AMD SB7x0/SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, - {0x43941002, 0x00, "AMD SB7x0/SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, + AHCI_Q_NOMSI | AHCI_Q_ATI_PMP_BUG | AHCI_Q_MAXIO_64K}, + {0x43901002, 0x00, "AMD SB7x0/SB8x0/SB9x0", + AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI}, + {0x43911002, 0x00, "AMD SB7x0/SB8x0/SB9x0", + AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI}, + {0x43921002, 0x00, "AMD SB7x0/SB8x0/SB9x0", + AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI}, + {0x43931002, 0x00, "AMD SB7x0/SB8x0/SB9x0", + AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI}, + {0x43941002, 0x00, "AMD SB7x0/SB8x0/SB9x0", + AHCI_Q_ATI_PMP_BUG | AHCI_Q_1MSI}, /* Not sure SB8x0/SB9x0 needs this quirk. Be conservative though */ {0x43951002, 0x00, "AMD SB8x0/SB9x0", AHCI_Q_ATI_PMP_BUG}, {0x78001022, 0x00, "AMD Hudson-2", 0}, @@ -137,7 +142,7 @@ static const struct { {0x1f378086, 0x00, "Intel Avoton (RAID)", 0}, {0x1f3e8086, 0x00, "Intel Avoton (RAID)", 0}, {0x1f3f8086, 0x00, "Intel Avoton (RAID)", 0}, - {0x23a38086, 0x00, "Intel Coleto Creek", 0}, + {0x23a38086, 0x00, "Intel Coleto Creek", 0}, {0x28238086, 0x00, "Intel Wellsburg (RAID)", 0}, {0x28278086, 0x00, "Intel Wellsburg (RAID)", 0}, {0x8c028086, 0x00, "Intel Lynx Point", 0}, @@ -410,10 +415,13 @@ ahci_pci_attach(device_t dev) /* Setup interrupts. */ /* Setup MSI register parameters */ - ctlr->msi = 2; /* Process hints. */ if (ctlr->quirks & AHCI_Q_NOMSI) ctlr->msi = 0; + else if (ctlr->quirks & AHCI_Q_1MSI) + ctlr->msi = 1; + else + ctlr->msi = 2; resource_int_value(device_get_name(dev), device_get_unit(dev), "msi", &ctlr->msi); ctlr->numirqs = 1; diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c index 9579fe2..6e38ca9 100644 --- a/sys/dev/gpio/gpiobus.c +++ b/sys/dev/gpio/gpiobus.c @@ -143,6 +143,9 @@ gpiobus_attach_bus(device_t dev) device_delete_child(dev, busdev); return (NULL); } +#ifdef FDT + ofw_gpiobus_register_provider(dev); +#endif bus_generic_attach(dev); return (busdev); @@ -152,6 +155,10 @@ int gpiobus_detach_bus(device_t dev) { +#ifdef FDT + ofw_gpiobus_unregister_provider(dev); +#endif + return (bus_generic_detach(dev)); } diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h index 5ea4040..4f84430 100644 --- a/sys/dev/gpio/gpiobusvar.h +++ b/sys/dev/gpio/gpiobusvar.h @@ -93,6 +93,8 @@ gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, } device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t); +void ofw_gpiobus_register_provider(device_t); +void ofw_gpiobus_unregister_provider(device_t); #endif int gpio_check_flags(uint32_t, uint32_t); device_t gpiobus_attach_bus(device_t); diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c index 225e905..59dcbbd 100644 --- a/sys/dev/gpio/ofw_gpiobus.c +++ b/sys/dev/gpio/ofw_gpiobus.c @@ -217,6 +217,24 @@ ofw_gpiobus_parse_gpios(struct gpiobus_softc *sc, struct gpiobus_ivar *dinfo, return (0); } +void +ofw_gpiobus_register_provider(device_t provider) +{ + phandle_t node; + + node = ofw_bus_get_node(provider); + OF_device_register_xref(OF_xref_from_node(node), provider); +} + +void +ofw_gpiobus_unregister_provider(device_t provider) +{ + phandle_t node; + + node = ofw_bus_get_node(provider); + OF_device_register_xref(OF_xref_from_node(node), NULL); +} + static struct ofw_gpiobus_devinfo * ofw_gpiobus_setup_devinfo(device_t dev, phandle_t node) { diff --git a/sys/dev/iscsi/iscsi_proto.h b/sys/dev/iscsi/iscsi_proto.h index 46572ce..ee19fbc 100644 --- a/sys/dev/iscsi/iscsi_proto.h +++ b/sys/dev/iscsi/iscsi_proto.h @@ -115,7 +115,9 @@ struct iscsi_bhs_scsi_response { uint8_t bhssr_status; uint8_t bhssr_total_ahs_len; uint8_t bhssr_data_segment_len[3]; - uint64_t bhssr_reserved; + uint16_t bhssr_status_qualifier; + uint16_t bhssr_reserved; + uint32_t bhssr_reserved2; uint32_t bhssr_initiator_task_tag; uint32_t bhssr_snack_tag; uint32_t bhssr_statsn; @@ -135,6 +137,10 @@ CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE); #define BHSTMR_FUNCTION_TARGET_WARM_RESET 6 #define BHSTMR_FUNCTION_TARGET_COLD_RESET 7 #define BHSTMR_FUNCTION_TASK_REASSIGN 8 +#define BHSTMR_FUNCTION_QUERY_TASK 9 +#define BHSTMR_FUNCTION_QUERY_TASK_SET 10 +#define BHSTMR_FUNCTION_I_T_NEXUS_RESET 11 +#define BHSTMR_FUNCTION_QUERY_ASYNC_EVENT 12 struct iscsi_bhs_task_management_request { uint8_t bhstmr_opcode; @@ -154,7 +160,14 @@ struct iscsi_bhs_task_management_request { CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE); #define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0 +#define BHSTMR_RESPONSE_TASK_DOES_NOT_EXIST 1 +#define BHSTMR_RESPONSE_LUN_DOES_NOT_EXIST 2 +#define BHSTMR_RESPONSE_TASK_STILL_ALLEGIANT 3 +#define BHSTMR_RESPONSE_TASK_ALL_REASS_NOT_SUPP 4 #define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5 +#define BHSTMR_RESPONSE_FUNCTION_AUTH_FAIL 6 +#define BHSTMR_RESPONSE_FUNCTION_SUCCEEDED 7 +#define BHSTMR_RESPONSE_FUNCTION_REJECTED 255 struct iscsi_bhs_task_management_response { uint8_t bhstmr_opcode; @@ -163,7 +176,8 @@ struct iscsi_bhs_task_management_response { uint8_t bhstmr_reserved; uint8_t bhstmr_total_ahs_len; uint8_t bhstmr_data_segment_len[3]; - uint64_t bhstmr_reserved2; + uint8_t bhstmr_additional_reponse_information[3]; + uint8_t bhstmr_reserved2[5]; uint32_t bhstmr_initiator_task_tag; uint32_t bhstmr_reserved3; uint32_t bhstmr_statsn; diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index 8650444..e9b72a3 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -1866,6 +1866,15 @@ restart: XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE); if (temp->direction == UE_DIR_IN) dword |= XHCI_TRB_3_DIR_IN | XHCI_TRB_3_ISP_BIT; + /* + * Section 3.2.9 in the XHCI + * specification about control + * transfers says that we should use a + * normal-TRB if there are more TRBs + * extending the data-stage + * TRB. Update the "trb_type". + */ + temp->trb_type = XHCI_TRB_TYPE_NORMAL; break; case XHCI_TRB_TYPE_STATUS_STAGE: dword = XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_CYCLE_BIT | @@ -2106,7 +2115,8 @@ xhci_setup_generic_chain(struct usb_xfer *xfer) mult = 1; temp.isoc_delta = 0; temp.isoc_frame = 0; - temp.trb_type = XHCI_TRB_TYPE_DATA_STAGE; + temp.trb_type = xfer->flags_int.control_did_data ? + XHCI_TRB_TYPE_NORMAL : XHCI_TRB_TYPE_DATA_STAGE; } else { x = 0; mult = 1; diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index dc51464..739a003 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -101,6 +101,7 @@ struct usb_xfer_flags_int { * sent */ uint8_t control_act:1; /* set if control transfer is active */ uint8_t control_stall:1; /* set if control transfer should be stalled */ + uint8_t control_did_data:1; /* set if control DATA has been transferred */ uint8_t short_frames_ok:1; /* filtered version */ uint8_t short_xfer_ok:1; /* filtered version */ diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c index 91b2292..c77afd0 100644 --- a/sys/dev/usb/usb_msctest.c +++ b/sys/dev/usb/usb_msctest.c @@ -113,6 +113,8 @@ static uint8_t scsi_request_sense[] = { 0x03, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t scsi_read_capacity[] = { 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_prevent_removal[] = { 0x1e, 0, 0, 0, 1, 0 }; +static uint8_t scsi_allow_removal[] = { 0x1e, 0, 0, 0, 0, 0 }; #ifndef USB_MSCTEST_BULK_SIZE #define USB_MSCTEST_BULK_SIZE 64 /* dummy */ @@ -702,10 +704,28 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) USB_MS_HZ); if (err != 0) { + if (err != ERR_CSW_FAILED) + goto error; + DPRINTF("Test unit ready failed\n"); + } + err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0, + &scsi_prevent_removal, sizeof(scsi_prevent_removal), + USB_MS_HZ); + + if (err == 0) { + err = bbb_command_start(sc, DIR_OUT, 0, NULL, 0, + &scsi_allow_removal, sizeof(scsi_allow_removal), + USB_MS_HZ); + } + + if (err != 0) { if (err != ERR_CSW_FAILED) goto error; + DPRINTF("Device doesn't handle prevent and allow removal\n"); + usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW); } + timeout = 1; retry_sync_cache: @@ -718,11 +738,9 @@ retry_sync_cache: if (err != ERR_CSW_FAILED) goto error; - DPRINTF("Device doesn't handle synchronize cache " - "and prevent allow medium removal\n"); + DPRINTF("Device doesn't handle synchronize cache\n"); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); - usbd_add_dynamic_quirk(udev, UQ_MSC_NO_PREVENT_ALLOW); } else { /* @@ -749,13 +767,10 @@ retry_sync_cache: goto retry_sync_cache; DPRINTF("Device most likely doesn't " - "handle synchronize cache nor" - "prevent allow medium removal\n"); + "handle synchronize cache\n"); usbd_add_dynamic_quirk(udev, UQ_MSC_NO_SYNC_CACHE); - usbd_add_dynamic_quirk(udev, - UQ_MSC_NO_PREVENT_ALLOW); } else { if (err != ERR_CSW_FAILED) goto error; diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index d99a22f..5650790 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -237,7 +237,11 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm, n_obj = 1; } else { /* compute number of objects per page */ +#ifdef USB_DMA_SINGLE_ALLOC + n_obj = 1; +#else n_obj = (USB_PAGE_SIZE / size); +#endif /* * Compute number of DMA chunks, rounded up * to nearest one: @@ -273,15 +277,33 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm, &parm->curr_xfer->xroot->dma_parent_tag; } - if (ppc) { - *ppc = parm->xfer_page_cache_ptr; + if (ppc != NULL) { + if (n_obj != 1) + *ppc = parm->xfer_page_cache_ptr; + else + *ppc = parm->dma_page_cache_ptr; } r = count; /* set remainder count */ z = n_obj * size; /* set allocation size */ pc = parm->xfer_page_cache_ptr; pg = parm->dma_page_ptr; - for (x = 0; x != n_dma_pc; x++) { + if (n_obj == 1) { + /* + * Avoid mapping memory twice if only a single object + * should be allocated per page cache: + */ + for (x = 0; x != n_dma_pc; x++) { + if (usb_pc_alloc_mem(parm->dma_page_cache_ptr, + pg, z, align)) { + return (1); /* failure */ + } + /* Make room for one DMA page cache and "n_dma_pg" pages */ + parm->dma_page_cache_ptr++; + pg += n_dma_pg; + } + } else { + for (x = 0; x != n_dma_pc; x++) { if (r < n_obj) { /* compute last remainder */ @@ -294,7 +316,7 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm, } /* Set beginning of current buffer */ buf = parm->dma_page_cache_ptr->buffer; - /* Make room for one DMA page cache and one page */ + /* Make room for one DMA page cache and "n_dma_pg" pages */ parm->dma_page_cache_ptr++; pg += n_dma_pg; @@ -314,6 +336,7 @@ usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm, } mtx_unlock(pc->tag_parent->mtx); } + } } parm->xfer_page_cache_ptr = pc; @@ -1409,6 +1432,29 @@ usbd_control_transfer_init(struct usb_xfer *xfer) } /*------------------------------------------------------------------------* + * usbd_control_transfer_did_data + * + * This function returns non-zero if a control endpoint has + * transferred the first DATA packet after the SETUP packet. + * Else it returns zero. + *------------------------------------------------------------------------*/ +static uint8_t +usbd_control_transfer_did_data(struct usb_xfer *xfer) +{ + struct usb_device_request req; + + /* SETUP packet is not yet sent */ + if (xfer->flags_int.control_hdr != 0) + return (0); + + /* copy out the USB request header */ + usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req)); + + /* compare remainder to the initial value */ + return (xfer->flags_int.control_rem != UGETW(req.wLength)); +} + +/*------------------------------------------------------------------------* * usbd_setup_ctrl_transfer * * This function handles initialisation of control transfers. Control @@ -1513,6 +1559,11 @@ usbd_setup_ctrl_transfer(struct usb_xfer *xfer) len = (xfer->sumlen - sizeof(struct usb_device_request)); } + /* update did data flag */ + + xfer->flags_int.control_did_data = + usbd_control_transfer_did_data(xfer); + /* check if there is a length mismatch */ if (len > xfer->flags_int.control_rem) { diff --git a/sys/mips/atheros/if_argevar.h b/sys/mips/atheros/if_argevar.h index 50c02c3..048c375 100644 --- a/sys/mips/atheros/if_argevar.h +++ b/sys/mips/atheros/if_argevar.h @@ -74,8 +74,20 @@ #define ARGE_CLEAR_BITS(sc, reg, bits) \ ARGE_WRITE(sc, reg, ARGE_READ(sc, (reg)) & ~(bits)) -#define ARGE_MDIO_WRITE(_sc, _reg, _val) \ - ARGE_WRITE((_sc), (_reg), (_val)) +/* + * The linux driver code for the MDIO bus does a read-after-write + * which seems to be required on MIPS74k platforms for correct + * behaviour. + * + * So, ARGE_WRITE() does the write + barrier, and the following + * ARGE_READ() seems to flush the thing all the way through the device + * FIFO(s) before we continue issuing MDIO bus updates. + */ +#define ARGE_MDIO_WRITE(_sc, _reg, _val) \ + do { \ + ARGE_WRITE((_sc), (_reg), (_val)); \ + ARGE_READ((_sc), (_reg)); \ + } while (0) #define ARGE_MDIO_READ(_sc, _reg) \ ARGE_READ((_sc), (_reg)) #define ARGE_MDIO_BARRIER_READ(_sc) ARGE_BARRIER_READ(_sc) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index ccd5e89..ec2813d 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -789,6 +789,10 @@ smart_frag_failure: IPSTAT_INC(ips_odropped); goto done; } + /* make sure the flowid is the same for the fragmented mbufs */ + M_HASHTYPE_SET(m, M_HASHTYPE_GET(m0)); + m->m_pkthdr.flowid = m0->m_pkthdr.flowid; + /* copy multicast flag, if any */ m->m_flags |= (m0->m_flags & M_MCAST); /* * In the first mbuf, leave room for the link header, then diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index 0190a0c..920c4b5 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -143,7 +143,7 @@ SVCXPRT * svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize, size_t recvsize) { - SVCXPRT *xprt; + SVCXPRT *xprt = NULL; struct sockaddr* sa; int error; |