## Automatically generated incremental diff ## From: linux-2.5.1-pre7 ## To: linux-2.5.1-pre8 ## Robot: $Id: make-incremental-diff,v 1.8 2001/12/04 06:05:04 hpa Exp $ diff -urN linux-2.5.1-pre7/Documentation/usb/error-codes.txt linux/Documentation/usb/error-codes.txt --- linux-2.5.1-pre7/Documentation/usb/error-codes.txt Wed Oct 17 14:34:06 2001 +++ linux/Documentation/usb/error-codes.txt Sat Dec 8 21:05:02 2001 @@ -1,14 +1,9 @@ -Revised: 2000-Dec-05. +Revised: 2001-Dec-06. This is the documentation of (hopefully) all possible error codes (and their interpretation) that can be returned from the host controller drivers and from usbcore. -NOTE: -The USB_ST_* codes are deprecated and are only listed for compatibility; -new software should use only -E* instead! - - ************************************************************************** * Error codes returned by usb_submit_urb * @@ -16,7 +11,6 @@ Non-USB-specific: -USB_ST_NOERROR 0 URB submission went fine -ENOMEM no memory for allocation of internal structures @@ -25,12 +19,10 @@ -ENODEV specified USB-device or bus doesn't exist -USB_ST_REQUEST_ERROR -ENXIO a control or interrupt URB is already queued to this endpoint; or a bulk URB is already queued to this endpoint and USB_QUEUE_BULK wasn't used (UHCI HCDs only) -USB_ST_URB_INVALID_ERROR -EINVAL a) Invalid transfer type specified (or not supported) b) Invalid interrupt interval (0<=n<256) c) more than one interrupt packet requested @@ -42,12 +34,10 @@ -EFBIG too much ISO frames requested (currently uhci>900) -USB_ST_STALL -EPIPE specified pipe-handle is already stalled -EMSGSIZE endpoint message size is zero, do interface/alternate setting -USB_ST_BANDWIDTH_ERROR -ENOSPC The host controller's bandwidth is already consumed and this request would push it past its allowed limit. @@ -60,60 +50,43 @@ * or in iso_frame_desc[n].status (for ISO) * ************************************************************************** -USB_ST_NOERROR 0 Transfer completed successfully -USB_ST_URB_KILLED -ENOENT URB was canceled by usb_unlink_urb -USB_ST_URB_PENDING -EINPROGRESS URB still pending, no results yet (actually no error until now;-) -USB_ST_BITSTUFF -USB_ST_INTERNALERROR -EPROTO a) bitstuff error b) unknown USB error -USB_ST_CRC -EILSEQ CRC mismatch -USB_ST_STALL -EPIPE endpoint stalled -USB_ST_BUFFEROVERRUN -ECOMM During an IN transfer, the host controller received data from an endpoint faster than it could be written to system memory -USB_ST_BUFFERUNDERRUN -ENOSR During an OUT transfer, the host controller could not retrieve data from system memory fast enough to keep up with the USB data rate -USB_ST_DATAOVERRUN -EOVERFLOW The amount of data returned by the endpoint was greater than either the max packet size of the endpoint or the remaining buffer size. "Babble". -USB_ST_DATAUNDERRUN -EREMOTEIO The endpoint returned less than max packet size and that amount did not fill the specified buffer -USB_ST_NORESPONSE -USB_ST_TIMEOUT -ETIMEDOUT transfer timed out, NAK -USB_ST_REMOVED -ENODEV device was removed -USB_ST_SHORT_PACKET -EREMOTEIO short packet detected -USB_ST_PARTIAL_ERROR -EXDEV ISO transfer only partially completed look at individual frame status for details -USB_ST_URB_INVALID_ERROR -EINVAL ISO madness, if this happens: Log off and go home -ECONNRESET the URB is being unlinked asynchronously diff -urN linux-2.5.1-pre7/Documentation/usb/scanner.txt linux/Documentation/usb/scanner.txt --- linux-2.5.1-pre7/Documentation/usb/scanner.txt Sat Oct 20 19:13:11 2001 +++ linux/Documentation/usb/scanner.txt Sat Dec 8 21:05:02 2001 @@ -83,7 +83,7 @@ `mknod /dev/usbscanner1 c 180 49` . . - `mknod /dev/usbscanner15 180 63` + `mknod /dev/usbscanner15 c 180 63` If you foresee using only one scanner it is best to: diff -urN linux-2.5.1-pre7/Makefile linux/Makefile --- linux-2.5.1-pre7/Makefile Sat Dec 8 21:04:22 2001 +++ linux/Makefile Sat Dec 8 21:05:02 2001 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 1 -EXTRAVERSION =-pre7 +EXTRAVERSION =-pre8 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.5.1-pre7/arch/i386/defconfig linux/arch/i386/defconfig --- linux-2.5.1-pre7/arch/i386/defconfig Sat Dec 8 21:04:22 2001 +++ linux/arch/i386/defconfig Sat Dec 8 21:05:02 2001 @@ -496,9 +496,6 @@ # IrDA (infrared) support # # CONFIG_IRDA is not set -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -CONFIG_IRDA_DEBUG=y # # ISDN subsystem diff -urN linux-2.5.1-pre7/drivers/block/DAC960.c linux/drivers/block/DAC960.c --- linux-2.5.1-pre7/drivers/block/DAC960.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/DAC960.c Sat Dec 8 21:05:02 2001 @@ -1947,7 +1947,6 @@ */ RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber); blk_init_queue(RequestQueue, DAC960_RequestFunction); - blk_queue_headactive(RequestQueue, 0); RequestQueue->queuedata = Controller; RequestQueue->max_segments = Controller->DriverScatterGatherLimit; RequestQueue->max_sectors = Controller->MaxBlocksPerCommand; diff -urN linux-2.5.1-pre7/drivers/block/block_ioctl.c linux/drivers/block/block_ioctl.c --- linux-2.5.1-pre7/drivers/block/block_ioctl.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/block_ioctl.c Sat Dec 8 21:05:02 2001 @@ -37,7 +37,7 @@ rq->flags |= REQ_BARRIER; rq->waiting = &wait; - elv_add_request(q, rq); + elv_add_request(q, rq, 1); generic_unplug_device(q); wait_for_completion(&wait); diff -urN linux-2.5.1-pre7/drivers/block/cciss.c linux/drivers/block/cciss.c --- linux-2.5.1-pre7/drivers/block/cciss.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/cciss.c Sat Dec 8 21:05:02 2001 @@ -1867,7 +1867,6 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; blk_init_queue(q, do_cciss_request); - blk_queue_headactive(q, 0); blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); blk_queue_max_segments(q, MAXSGENTRIES); blk_queue_max_sectors(q, 512); diff -urN linux-2.5.1-pre7/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c --- linux-2.5.1-pre7/drivers/block/cpqarray.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/cpqarray.c Sat Dec 8 21:05:02 2001 @@ -468,7 +468,6 @@ q = BLK_DEFAULT_QUEUE(MAJOR_NR + i); q->queuedata = hba[i]; blk_init_queue(q, do_ida_request); - blk_queue_headactive(q, 0); blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); blk_queue_max_segments(q, SG_MAX); blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256); diff -urN linux-2.5.1-pre7/drivers/block/genhd.c linux/drivers/block/genhd.c --- linux-2.5.1-pre7/drivers/block/genhd.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/genhd.c Sat Dec 8 21:05:02 2001 @@ -149,8 +149,7 @@ char buf[64]; int len, n; - len = sprintf(page, "major minor #blocks start_sect nr_sects " - "name\n\n"); + len = sprintf(page, "major minor #blocks name\n\n"); read_lock(&gendisk_lock); for (gp = gendisk_head; gp; gp = gp->next) { for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) { @@ -158,10 +157,8 @@ continue; len += snprintf(page + len, 63, - "%4d %4d %10d %10lu %10lu %s\n", + "%4d %4d %10d %s\n", gp->major, n, gp->sizes[n], - gp->part[n].start_sect, - gp->part[n].nr_sects, disk_name(gp, n, buf)); if (len < offset) offset -= len, len = 0; diff -urN linux-2.5.1-pre7/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-2.5.1-pre7/drivers/block/ll_rw_blk.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/ll_rw_blk.c Sat Dec 8 21:05:02 2001 @@ -562,6 +562,7 @@ static int blk_init_free_list(request_queue_t *q) { + struct request_list *rl; struct request *rq; int i; @@ -573,20 +574,22 @@ /* * Divide requests in half between read and write */ + rl = &q->rq[READ]; for (i = 0; i < queue_nr_requests; i++) { rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL); if (!rq) goto nomem; + /* + * half way through, switch to WRITE list + */ + if (i == queue_nr_requests / 2) + rl = &q->rq[WRITE]; + memset(rq, 0, sizeof(struct request)); rq->rq_status = RQ_INACTIVE; - if (i < queue_nr_requests >> 1) { - list_add(&rq->queuelist, &q->rq[READ].free); - q->rq[READ].count++; - } else { - list_add(&rq->queuelist, &q->rq[WRITE].free); - q->rq[WRITE].count++; - } + list_add(&rq->queuelist, &rl->free); + rl->count++; } init_waitqueue_head(&q->rq[READ].wait); @@ -692,21 +695,22 @@ static struct request *get_request_wait(request_queue_t *q, int rw) { DECLARE_WAITQUEUE(wait, current); + struct request_list *rl = &q->rq[rw]; struct request *rq; spin_lock_prefetch(&q->queue_lock); generic_unplug_device(q); - add_wait_queue(&q->rq[rw].wait, &wait); + add_wait_queue(&rl->wait, &wait); do { set_current_state(TASK_UNINTERRUPTIBLE); - if (q->rq[rw].count < batch_requests) + if (rl->count < batch_requests) schedule(); spin_lock_irq(&q->queue_lock); rq = get_request(q, rw); spin_unlock_irq(&q->queue_lock); } while (rq == NULL); - remove_wait_queue(&q->rq[rw].wait, &wait); + remove_wait_queue(&rl->wait, &wait); current->state = TASK_RUNNING; return rq; } @@ -1234,7 +1238,6 @@ */ BUG_ON(!bio->bi_end_io); - BIO_BUG_ON(bio_offset(bio) > PAGE_SIZE); BIO_BUG_ON(!bio->bi_size); BIO_BUG_ON(!bio->bi_io_vec); @@ -1397,6 +1400,28 @@ extern int stram_device_init (void); #endif +inline void blk_recalc_request(struct request *rq, int nsect) +{ + rq->hard_sector += nsect; + rq->hard_nr_sectors -= nsect; + rq->sector = rq->hard_sector; + rq->nr_sectors = rq->hard_nr_sectors; + + rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; + rq->hard_cur_sectors = rq->current_nr_sectors; + + /* + * if total number of sectors is less than the first segment + * size, something has gone terribly wrong + */ + if (rq->nr_sectors < rq->current_nr_sectors) { + printk("blk: request botched\n"); + rq->nr_sectors = rq->current_nr_sectors; + } + + rq->buffer = bio_data(rq->bio); +} + /** * end_that_request_first - end I/O on one buffer. * @req: the request being processed @@ -1414,53 +1439,55 @@ int end_that_request_first(struct request *req, int uptodate, int nr_sectors) { - struct bio *bio, *nxt; - int nsect, total_nsect = 0; + int nsect, total_nsect; + struct bio *bio; req->errors = 0; if (!uptodate) printk("end_request: I/O error, dev %s, sector %lu\n", kdevname(req->rq_dev), req->sector); - if ((bio = req->bio) != NULL) { -next_chunk: + total_nsect = 0; + while ((bio = req->bio)) { nsect = bio_iovec(bio)->bv_len >> 9; + bio->bi_size -= bio_iovec(bio)->bv_len; + + /* + * not a complete bvec done + */ + if (unlikely(nsect > nr_sectors)) { + int residual = (nsect - nr_sectors) << 9; + + bio_iovec(bio)->bv_offset += residual; + bio_iovec(bio)->bv_len -= residual; + blk_recalc_request(req, nr_sectors); + return 1; + } + nr_sectors -= nsect; total_nsect += nsect; if (++bio->bi_idx >= bio->bi_vcnt) { - nxt = bio->bi_next; - if (!bio_endio(bio, uptodate, total_nsect)) { - total_nsect = 0; - req->bio = nxt; - } else + req->bio = bio->bi_next; + + if (unlikely(bio_endio(bio, uptodate, total_nsect))) BUG(); + + total_nsect = 0; } - if ((bio = req->bio) != NULL) { - req->hard_sector += nsect; - req->hard_nr_sectors -= nsect; - req->sector = req->hard_sector; - req->nr_sectors = req->hard_nr_sectors; - - req->current_nr_sectors = bio_iovec(bio)->bv_len >> 9; - req->hard_cur_sectors = req->current_nr_sectors; - if (req->nr_sectors < req->current_nr_sectors) { - printk("end_request: buffer-list destroyed\n"); - req->nr_sectors = req->current_nr_sectors; - } + if ((bio = req->bio)) { + blk_recalc_request(req, nsect); - req->buffer = bio_data(bio); /* * end more in this run, or just return 'not-done' */ - if (nr_sectors > 0) - goto next_chunk; - - return 1; + if (unlikely(nr_sectors <= 0)) + return 1; } } + return 0; } @@ -1544,3 +1571,4 @@ EXPORT_SYMBOL(blk_rq_map_sg); EXPORT_SYMBOL(blk_nohighio); EXPORT_SYMBOL(blk_dump_rq_flags); +EXPORT_SYMBOL(submit_bio); diff -urN linux-2.5.1-pre7/drivers/block/nbd.c linux/drivers/block/nbd.c --- linux-2.5.1-pre7/drivers/block/nbd.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/nbd.c Sat Dec 8 21:05:02 2001 @@ -516,7 +516,6 @@ blksize_size[MAJOR_NR] = nbd_blksizes; blk_size[MAJOR_NR] = nbd_sizes; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_nbd_request); - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_NBD; i++) { nbd_dev[i].refcnt = 0; nbd_dev[i].file = NULL; diff -urN linux-2.5.1-pre7/drivers/block/xd.c linux/drivers/block/xd.c --- linux-2.5.1-pre7/drivers/block/xd.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/block/xd.c Sat Dec 8 21:05:02 2001 @@ -121,7 +121,6 @@ static struct hd_struct xd_struct[XD_MAXDRIVES << 6]; static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES]; static int xd_blocksizes[XD_MAXDRIVES << 6]; -static int xd_maxsect[XD_MAXDRIVES << 6]; extern struct block_device_operations xd_fops; @@ -246,8 +245,7 @@ } /* xd_maxsectors depends on controller - so set after detection */ - for(i=0; i<(XD_MAXDRIVES << 6); i++) xd_maxsect[i] = xd_maxsectors; - max_sectors[MAJOR_NR] = xd_maxsect; + blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors); for (i = 0; i < xd_drives; i++) { xd_valid[i] = 1; @@ -294,11 +292,11 @@ block = CURRENT->sector; count = CURRENT->nr_sectors; - switch (CURRENT->cmd) { + switch (rq_data_dir(CURRENT)) { case READ: case WRITE: for (retry = 0; (retry < XD_RETRIES) && !code; retry++) - code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count); + code = xd_readwrite(rq_data_dir(CURRENT),CURRENT_DEV,CURRENT->buffer,block,count); break; default: printk("do_xd_request: unknown request\n"); diff -urN linux-2.5.1-pre7/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- linux-2.5.1-pre7/drivers/cdrom/sbpcd.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/cdrom/sbpcd.c Sat Dec 8 21:05:02 2001 @@ -5870,7 +5870,6 @@ (BLK_DEFAULT_QUEUE(MAJOR_NR))->front_merge_fn = dont_bh_merge_fn; (BLK_DEFAULT_QUEUE(MAJOR_NR))->merge_requests_fn = dont_merge_requests_fn; #endif - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); read_ahead[MAJOR_NR] = buffers * (CD_FRAMESIZE / 512); request_region(CDo_command,4,major_name); diff -urN linux-2.5.1-pre7/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c --- linux-2.5.1-pre7/drivers/ide/ide-cd.c Sat Dec 8 21:04:22 2001 +++ linux/drivers/ide/ide-cd.c Sat Dec 8 21:05:02 2001 @@ -1615,7 +1615,7 @@ /* * just wrap this around cdrom_do_packet_command */ -static int cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) +static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { struct packet_command pc; ide_startstop_t startstop; @@ -2145,7 +2145,8 @@ pc.timeout = cgc->timeout; pc.sense = cgc->sense; cgc->stat = cdrom_queue_packet_command(drive, &pc); - cgc->buflen -= pc.buflen; + if (!cgc->stat) + cgc->buflen -= pc.buflen; return cgc->stat; } diff -urN linux-2.5.1-pre7/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h --- linux-2.5.1-pre7/drivers/ide/ide-cd.h Sat Dec 8 21:04:22 2001 +++ linux/drivers/ide/ide-cd.h Sat Dec 8 21:05:02 2001 @@ -435,7 +435,7 @@ byte curlba[3]; byte nslots; - __u16 short slot_tablelen; + __u16 slot_tablelen; }; diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c --- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_b.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/isdn/hisax/st5481_b.c Sat Dec 8 21:05:03 2001 @@ -168,7 +168,7 @@ test_and_clear_bit(buf_nr, &b_out->busy); if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); if (b_out->busy == 0) { st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL); diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c --- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_d.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/isdn/hisax/st5481_d.c Sat Dec 8 21:05:03 2001 @@ -382,7 +382,7 @@ test_and_clear_bit(buf_nr, &d_out->busy); if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); if (d_out->busy == 0) { st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); diff -urN linux-2.5.1-pre7/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c --- linux-2.5.1-pre7/drivers/isdn/hisax/st5481_usb.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/isdn/hisax/st5481_usb.c Sat Dec 8 21:05:03 2001 @@ -130,7 +130,7 @@ struct ctrl_msg *ctrl_msg; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); @@ -184,7 +184,7 @@ int j; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); urb->actual_length = 0; } else { @@ -470,7 +470,7 @@ int len, count, status; if (urb->status < 0) { - if (urb->status != USB_ST_URB_KILLED) { + if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); diff -urN linux-2.5.1-pre7/drivers/message/i2o/i2o_block.c linux/drivers/message/i2o/i2o_block.c --- linux-2.5.1-pre7/drivers/message/i2o/i2o_block.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/message/i2o/i2o_block.c Sat Dec 8 21:05:03 2001 @@ -1423,7 +1423,6 @@ atomic_set(&i2ob_queues[unit]->queue_depth, 0); blk_init_queue(&i2ob_queues[unit]->req_queue, i2ob_request); - blk_queue_headactive(&i2ob_queues[unit]->req_queue, 0); i2ob_queues[unit]->req_queue.queuedata = &i2ob_queues[unit]; return 0; @@ -1822,7 +1821,6 @@ blk_dev[MAJOR_NR].queue = i2ob_get_queue; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), i2ob_request); - blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); for (i = 0; i < MAX_I2OB << 4; i++) { i2ob_dev[i].refcnt = 0; diff -urN linux-2.5.1-pre7/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c --- linux-2.5.1-pre7/drivers/net/irda/irda-usb.c Fri Nov 9 14:22:17 2001 +++ linux/drivers/net/irda/irda-usb.c Sat Dec 8 21:05:03 2001 @@ -256,7 +256,7 @@ /* Grab the speed URB */ purb = &self->speed_urb; - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { WARNING(__FUNCTION__ "(), URB still in use!\n"); return; } @@ -301,7 +301,7 @@ } /* Check for timeout and other USB nasties */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags); @@ -314,7 +314,7 @@ } /* urb is now available */ - purb->status = USB_ST_NOERROR; + purb->status = 0; /* If it was the speed URB, allow the stack to send more packets */ if(purb == &self->speed_urb) { @@ -372,7 +372,7 @@ } } - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { WARNING(__FUNCTION__ "(), URB still in use!\n"); dev_kfree_skb(skb); return 0; @@ -490,7 +490,7 @@ purb->context = NULL; /* Check for timeout and other USB nasties */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ IRDA_DEBUG(0, __FUNCTION__ "(), URB complete status %d, transfer_flags 0x%04X\n", purb->status, purb->transfer_flags); @@ -504,7 +504,7 @@ } /* urb is now available */ - purb->status = USB_ST_NOERROR; + purb->status = 0; /* If the network is closed, stop everything */ if ((!self->netopen) || (!self->present)) { @@ -547,11 +547,11 @@ /* Check speed URB */ purb = &(self->speed_urb); - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { IRDA_DEBUG(0, "%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags); switch (purb->status) { - case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */ + case -EINPROGRESS: usb_unlink_urb(purb); /* Note : above will *NOT* call netif_wake_queue() * in completion handler, we will come back here. @@ -563,7 +563,7 @@ case -ETIMEDOUT: /* -110 */ case -ENOENT: /* -2 (urb unlinked by us) */ default: /* ??? - Play safe */ - purb->status = USB_ST_NOERROR; + purb->status = 0; netif_wake_queue(self->netdev); done = 1; break; @@ -572,7 +572,7 @@ /* Check Tx URB */ purb = &(self->tx_urb); - if (purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { struct sk_buff *skb = purb->context; IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, purb->status, purb->transfer_flags); @@ -590,7 +590,7 @@ #endif /* IU_BUG_KICK_TIMEOUT */ switch (purb->status) { - case USB_ST_URB_PENDING: /* -EINPROGRESS == -115 */ + case -EINPROGRESS: usb_unlink_urb(purb); /* Note : above will *NOT* call netif_wake_queue() * in completion handler, because purb->status will @@ -610,7 +610,7 @@ dev_kfree_skb_any(skb); purb->context = NULL; } - purb->status = USB_ST_NOERROR; + purb->status = 0; netif_wake_queue(self->netdev); done = 1; break; @@ -727,7 +727,7 @@ purb->transfer_flags = USB_QUEUE_BULK; /* Note : unlink *must* be synchronous because of the code in * irda_usb_net_close() -> free the skb - Jean II */ - purb->status = USB_ST_NOERROR; + purb->status = 0; purb->next = NULL; /* Don't auto resubmit URBs */ ret = usb_submit_urb(purb); @@ -768,9 +768,9 @@ } /* Check the status */ - if(purb->status != USB_ST_NOERROR) { + if (purb->status != 0) { switch (purb->status) { - case USB_ST_CRC: /* -EILSEQ */ + case -EILSEQ: self->stats.rx_errors++; self->stats.rx_crc_errors++; break; @@ -1442,9 +1442,9 @@ ret = usb_set_interface(dev, ifnum, 0); IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", ifnum, ret); switch (ret) { - case USB_ST_NOERROR: /* 0 */ + case 0: break; - case USB_ST_STALL: /* -EPIPE = -32 */ + case -EPIPE: /* -EPIPE = -32 */ usb_clear_halt(dev, usb_sndctrlpipe(dev, 0)); IRDA_DEBUG(0, __FUNCTION__ "(), Clearing stall on control interface\n" ); break; diff -urN linux-2.5.1-pre7/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c --- linux-2.5.1-pre7/drivers/s390/block/dasd.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/s390/block/dasd.c Sat Dec 8 21:05:03 2001 @@ -3343,7 +3343,6 @@ device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL); device->request_queue->queuedata = device; blk_init_queue (device->request_queue, do_dasd_request); - blk_queue_headactive (device->request_queue, 0); elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP); for (i = 0; i < (1 << DASD_PARTN_BITS); i++) { diff -urN linux-2.5.1-pre7/drivers/s390/block/xpram.c linux/drivers/s390/block/xpram.c --- linux-2.5.1-pre7/drivers/s390/block/xpram.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/s390/block/xpram.c Sat Dec 8 21:05:03 2001 @@ -1041,7 +1041,6 @@ #elif (XPRAM_VERSION == 24) q = BLK_DEFAULT_QUEUE (major); blk_init_queue (q, xpram_request); - blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0); #endif /* V22/V24 */ read_ahead[major] = xpram_rahead; diff -urN linux-2.5.1-pre7/drivers/s390/char/tapeblock.c linux/drivers/s390/char/tapeblock.c --- linux-2.5.1-pre7/drivers/s390/char/tapeblock.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/s390/char/tapeblock.c Sat Dec 8 21:05:03 2001 @@ -77,7 +77,6 @@ blksize_size[tapeblock_major][ti->blk_minor]=2048; // blocks are 2k by default. hardsect_size[tapeblock_major][ti->blk_minor]=512; blk_init_queue (&ti->request_queue, tape_request_fn); - blk_queue_headactive (&ti->request_queue, 0); #ifdef CONFIG_DEVFS_FS tapeblock_mkdevfstree(ti); #endif diff -urN linux-2.5.1-pre7/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c --- linux-2.5.1-pre7/drivers/sbus/char/jsflash.c Thu Oct 25 13:58:35 2001 +++ linux/drivers/sbus/char/jsflash.c Sat Dec 8 21:05:03 2001 @@ -662,7 +662,6 @@ blk_size[JSFD_MAJOR] = jsfd_sizes; blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST); - /* blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); */ for (i = 0; i < JSF_MAX; i++) { if ((i & JSF_PART_MASK) >= JSF_NPART) continue; jsf = &jsf0; /* actually, &jsfv[i >> JSF_PART_BITS] */ diff -urN linux-2.5.1-pre7/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c --- linux-2.5.1-pre7/drivers/scsi/ide-scsi.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/scsi/ide-scsi.c Sat Dec 8 21:05:03 2001 @@ -429,7 +429,7 @@ pc->current_position=pc->buffer; bcount = IDE_MIN (pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ - if (drive->using_dma && rq->special) + if (drive->using_dma && rq->bio) dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive); SELECT_DRIVE(HWIF(drive), drive); diff -urN linux-2.5.1-pre7/drivers/scsi/imm.c linux/drivers/scsi/imm.c --- linux-2.5.1-pre7/drivers/scsi/imm.c Sun Sep 30 12:26:07 2001 +++ linux/drivers/scsi/imm.c Sat Dec 8 21:05:03 2001 @@ -124,11 +124,6 @@ int i, nhosts, try_again; struct parport *pb; - /* - * unlock to allow the lowlevel parport driver to probe - * the irqs - */ - spin_unlock_irq(&io_request_lock); pb = parport_enumerate(); printk("imm: Version %s\n", IMM_VERSION); @@ -137,7 +132,6 @@ if (!pb) { printk("imm: parport reports no devices.\n"); - spin_lock_irq(&io_request_lock); return 0; } retry_entry: @@ -163,7 +157,6 @@ "pardevice is owning the port for too longtime!\n", i); parport_unregister_device (imm_hosts[i].dev); - spin_lock_irq(&io_request_lock); return 0; } } @@ -219,13 +212,11 @@ } if (nhosts == 0) { if (try_again == 1) { - spin_lock_irq(&io_request_lock); return 0; } try_again = 1; goto retry_entry; } else { - spin_lock_irq (&io_request_lock); return 1; /* return number of hosts detected */ } } @@ -834,7 +825,7 @@ if (cmd->SCp.buffers_residual--) { cmd->SCp.buffer++; cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = cmd->SCp.buffer->address; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; /* * Make sure that we transfer even number of bytes @@ -897,6 +888,7 @@ { imm_struct *tmp = (imm_struct *) data; Scsi_Cmnd *cmd = tmp->cur_cmd; + struct Scsi_Host *host = cmd->host; unsigned long flags; if (!cmd) { @@ -948,10 +940,10 @@ if (cmd->SCp.phase > 0) imm_pb_release(cmd->host->unique_id); - spin_lock_irqsave(&io_request_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); tmp->cur_cmd = 0; cmd->scsi_done(cmd); - spin_unlock_irqrestore(&io_request_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return; } @@ -1008,7 +1000,7 @@ /* if many buffers are available, start filling the first */ cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = cmd->SCp.buffer->address; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; } else { /* else fill the only available buffer */ cmd->SCp.buffer = NULL; diff -urN linux-2.5.1-pre7/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- linux-2.5.1-pre7/drivers/scsi/scsi.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/scsi/scsi.c Sat Dec 8 21:05:03 2001 @@ -183,7 +183,6 @@ request_queue_t *q = &SDpnt->request_queue; blk_init_queue(q, scsi_request_fn); - blk_queue_headactive(q, 0); q->queuedata = (void *) SDpnt; #ifdef DMA_CHUNK_SIZE blk_queue_max_segments(q, 64); @@ -231,7 +230,8 @@ req = &SCpnt->request; req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - complete(req->waiting); + if (req->waiting) + complete(req->waiting); } /* diff -urN linux-2.5.1-pre7/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c --- linux-2.5.1-pre7/drivers/scsi/scsi_lib.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/scsi/scsi_lib.c Sat Dec 8 21:05:03 2001 @@ -72,7 +72,13 @@ ASSERT_LOCK(&q->queue_lock, 0); - rq->flags = REQ_SPECIAL | REQ_NOMERGE | REQ_BARRIER; + /* + * tell I/O scheduler that this isn't a regular read/write (ie it + * must not attempt merges on this) and that it acts as a soft + * barrier + */ + rq->flags = REQ_SPECIAL | REQ_BARRIER; + rq->special = data; rq->q = NULL; rq->bio = rq->biotail = NULL; @@ -86,12 +92,7 @@ * device, or a host that is unable to accept a particular command. */ spin_lock_irqsave(&q->queue_lock, flags); - - if (at_head) - list_add(&rq->queuelist, &q->queue_head); - else - list_add_tail(&rq->queuelist, &q->queue_head); - + __elv_add_request(q, rq, !at_head, 0); q->request_fn(q); spin_unlock_irqrestore(&q->queue_lock, flags); } @@ -261,10 +262,7 @@ * the bad sector. */ SCpnt->request.special = (void *) SCpnt; -#if 0 - SCpnt->request.flags |= REQ_SPECIAL; -#endif - list_add(&SCpnt->request.queuelist, &q->queue_head); + __elv_add_request(q, &SCpnt->request, 0, 0); } /* @@ -360,23 +358,15 @@ int frequeue) { request_queue_t *q = &SCpnt->device->request_queue; - struct request *req; + struct request *req = &SCpnt->request; ASSERT_LOCK(&q->queue_lock, 0); - req = &SCpnt->request; - while (end_that_request_first(req, 1, sectors)) { - if (!req->bio) { - printk("scsi_end_request: missing bio\n"); - break; - } - } - /* * If there are blocks left over at the end, set up the command * to queue the remainder of them. */ - if (req->bio) { + if (end_that_request_first(req, 1, sectors)) { if (!requeue) return SCpnt; @@ -834,13 +824,6 @@ */ if (SHpnt->in_recovery || blk_queue_plugged(q)) return; - - /* - * if we are at the max queue depth, don't attempt to queue - * more - */ - if (SHpnt->host_busy == SDpnt->queue_depth) - break; /* * If the device cannot accept another request, then quit. diff -urN linux-2.5.1-pre7/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- linux-2.5.1-pre7/drivers/scsi/sd.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/scsi/sd.c Sat Dec 8 21:05:03 2001 @@ -286,6 +286,12 @@ char nbuff[6]; #endif + /* + * don't support specials for nwo + */ + if (!(SCpnt->request.flags & REQ_CMD)) + return 0; + devm = SD_PARTITION(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev); diff -urN linux-2.5.1-pre7/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c --- linux-2.5.1-pre7/drivers/usb/CDCEther.c Fri Oct 5 12:06:08 2001 +++ linux/drivers/usb/CDCEther.c Sat Dec 8 21:05:03 2001 @@ -82,9 +82,9 @@ ether_dev->flags |= CDC_ETHER_RX_BUSY; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_NORESPONSE: + case -ETIMEDOUT: dbg( "no repsonse in BULK IN" ); ether_dev->flags &= ~CDC_ETHER_RX_BUSY; break; @@ -179,9 +179,9 @@ // return; // // switch ( urb->status ) { -// case USB_ST_NOERROR: +// case 0: // break; -// case USB_ST_URB_KILLED: +// case -ENOENT: // return; // default: // info("intr status %d", urb->status); @@ -337,13 +337,9 @@ ether_dev_t *ether_dev = (ether_dev_t *)net->priv; int res; - // We are finally getting used! - MOD_INC_USE_COUNT; - // Turn on the USB and let the packets flow!!! if ( (res = enable_net_traffic( ether_dev )) ) { err( __FUNCTION__ "can't enable_net_traffic() - %d", res ); - MOD_DEC_USE_COUNT; return -EIO; } @@ -391,9 +387,6 @@ usb_unlink_urb( ðer_dev->tx_urb ); usb_unlink_urb( ðer_dev->intr_urb ); - // We are not being used now. - MOD_DEC_USE_COUNT; - // That's it. I'm done. return 0; } @@ -480,6 +473,7 @@ i++, mclist = mclist->next) { memcpy(&mclist->dmi_addr, &buff[i * 6], 6); } +#if 0 usb_control_msg(ether_dev->usb, usb_sndctrlpipe(ether_dev->usb, 0), SET_ETHERNET_MULTICAST_FILTER, /* request */ @@ -489,11 +483,13 @@ buff, (6* net->mc_count), /* size */ HZ); /* timeout */ +#endif kfree(buff); } - + +#if 0 CDC_SetEthernetPacketFilter(ether_dev); - +#endif // Tell the kernel to start giving frames to us again. netif_wake_queue(net); } @@ -1210,6 +1206,7 @@ // Now that we have an ethernet device, let's set it up // (And I don't mean "set [it] up the bomb".) net->priv = ether_dev; + SET_MODULE_OWNER(net); net->open = CDCEther_open; net->stop = CDCEther_close; net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT; diff -urN linux-2.5.1-pre7/drivers/usb/Config.in linux/drivers/usb/Config.in --- linux-2.5.1-pre7/drivers/usb/Config.in Fri Nov 2 17:18:58 2001 +++ linux/drivers/usb/Config.in Sat Dec 8 21:05:03 2001 @@ -9,7 +9,7 @@ bool ' USB verbose debug messages' CONFIG_USB_DEBUG comment 'Miscellaneous USB options' - bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS + bool ' USB device filesystem' CONFIG_USB_DEVICEFS if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' Enforce USB bandwidth allocation (EXPERIMENTAL)' CONFIG_USB_BANDWIDTH else diff -urN linux-2.5.1-pre7/drivers/usb/audio.c linux/drivers/usb/audio.c --- linux-2.5.1-pre7/drivers/usb/audio.c Fri Oct 5 12:04:50 2001 +++ linux/drivers/usb/audio.c Sat Dec 8 21:05:03 2001 @@ -899,7 +899,7 @@ struct usbin *u = &as->usbin; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbin_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -917,7 +917,7 @@ if (!usbin_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -964,7 +964,7 @@ struct usbin *u = &as->usbin; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbin_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -982,7 +982,7 @@ if (!usbin_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbin_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1257,7 +1257,7 @@ struct usbout *u = &as->usbout; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbout_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -1275,7 +1275,7 @@ if (!usbout_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -1329,7 +1329,7 @@ struct usbout *u = &as->usbout; unsigned long flags; unsigned int mask; - int suret = USB_ST_NOERROR; + int suret = 0; #if 0 printk(KERN_DEBUG "usbout_sync_completed: status %d errcnt %d flags 0x%x\n", urb->status, urb->error_count, u->flags); @@ -1347,7 +1347,7 @@ if (!usbout_sync_retire_desc(u, urb) && u->flags & FLG_RUNNING && !usbout_sync_prepare_desc(u, urb) && - (suret = usb_submit_urb(urb)) == USB_ST_NOERROR) { + (suret = usb_submit_urb(urb)) == 0) { u->flags |= mask; } else { u->flags &= ~(mask | FLG_RUNNING); @@ -3362,28 +3362,48 @@ struct usb_device *dev = state->s->usbdev; unsigned char data[1]; #endif + unsigned char nr_logical_channels, i; usb_audio_recurseunit(state, ftr[4]); + + if (ftr[5] == 0 ) { + printk(KERN_ERR "usbaudio: wrong controls size in feature unit %u\n",ftr[3]); + return; + } + if (state->nrchannels == 0) { printk(KERN_ERR "usbaudio: feature unit %u source has no channels\n", ftr[3]); return; } if (state->nrchannels > 2) printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]); - if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) { - printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n"); - mchftr = ftr[6]; - chftr = 0; - } else { - if (ftr[0] < 7+ftr[5]*(1+state->nrchannels)) { - printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", ftr[3]); - return; + + nr_logical_channels=(ftr[0]-7)/ftr[5]-1; + + if (nr_logical_channels != state->nrchannels) { + printk(KERN_WARNING "usbaudio: warning: found %d of %d logical channels.\n", state->nrchannels,nr_logical_channels); + + if (state->nrchannels == 1 && nr_logical_channels==0) { + printk(KERN_INFO "usbaudio: assuming the channel found is the master channel (got a Philips camera?). Should be fine.\n"); + } else if (state->nrchannels == 1 && nr_logical_channels==2) { + printk(KERN_INFO "usbaudio: assuming that a stereo channel connected directly to a mixer is missing in search (got Labtec headset?). Should be fine.\n"); + state->nrchannels=nr_logical_channels; + } else { + printk(KERN_WARNING "usbaudio: no idea what's going on..., contact linux-usb-devel@lists.sourceforge.net\n"); } - mchftr = ftr[6]; + } + + /* There is always a master channel */ + mchftr = ftr[6]; + /* Binary AND over logical channels if they exist */ + if (nr_logical_channels) { chftr = ftr[6+ftr[5]]; - if (state->nrchannels > 1) - chftr &= ftr[6+2*ftr[5]]; + for (i = 2; i <= nr_logical_channels; i++) + chftr &= ftr[6+i*ftr[5]]; + } else { + chftr = 0; } + /* volume control */ if (chftr & 2) { ch = getmixchannel(state, getvolchannel(state)); diff -urN linux-2.5.1-pre7/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c --- linux-2.5.1-pre7/drivers/usb/bluetooth.c Tue Nov 13 09:19:41 2001 +++ linux/drivers/usb/bluetooth.c Sat Dec 8 21:05:03 2001 @@ -1,11 +1,15 @@ /* - * bluetooth.c Version 0.12 + * bluetooth.c Version 0.13 * * Copyright (c) 2000, 2001 Greg Kroah-Hartman * Copyright (c) 2000 Mark Douglas Corner * * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B * + * (2001/11/30) Version 0.13 gkh + * - added locking patch from Masoodur Rahman + * - removed active variable, as open_count will do. + * * (2001/07/09) Version 0.12 gkh * - removed in_interrupt() call, as it doesn't make sense to do * that anymore. @@ -118,7 +122,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.12" +#define DRIVER_VERSION "v0.13" #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner" #define DRIVER_DESC "USB Bluetooth tty driver" @@ -170,8 +174,8 @@ struct tty_struct * tty; /* the coresponding tty for this port */ unsigned char minor; /* the starting minor number for this device */ - char active; /* someone has this device open */ int throttle; /* throttled by tty layer */ + int open_count; __u8 control_out_bInterfaceNum; struct urb * control_urb_pool[NUM_CONTROL_URBS]; @@ -200,6 +204,7 @@ unsigned char int_buffer[EVENT_BUFFER_SIZE]; unsigned int bulk_packet_pos; unsigned char bulk_buffer[ACL_BUFFER_SIZE]; /* 64k preallocated, fix? */ + struct semaphore lock; }; @@ -361,43 +366,46 @@ return -ENODEV; } - if (bluetooth->active) { - dbg (__FUNCTION__ " - device already open"); - return -EINVAL; - } - - /* set up our structure making the tty driver remember our object, and us it */ - tty->driver_data = bluetooth; - bluetooth->tty = tty; - - /* force low_latency on so that our tty_push actually forces the data through, - * otherwise it is scheduled, and with high data rates (like with OHCI) data - * can get lost. */ - bluetooth->tty->low_latency = 1; + down (&bluetooth->lock); + + ++bluetooth->open_count; + if (bluetooth->open_count == 1) { + /* set up our structure making the tty driver remember our object, and us it */ + tty->driver_data = bluetooth; + bluetooth->tty = tty; + + /* force low_latency on so that our tty_push actually forces the data through, + * otherwise it is scheduled, and with high data rates (like with OHCI) data + * can get lost. */ + bluetooth->tty->low_latency = 1; - bluetooth->active = 1; - - /* Reset the packet position counters */ - bluetooth->int_packet_pos = 0; - bluetooth->bulk_packet_pos = 0; + /* Reset the packet position counters */ + bluetooth->int_packet_pos = 0; + bluetooth->bulk_packet_pos = 0; #ifndef BTBUGGYHARDWARE - /* Start reading from the device */ - FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, - usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), - bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, - bluetooth_read_bulk_callback, bluetooth); - result = usb_submit_urb(bluetooth->read_urb); - if (result) - dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); + /* Start reading from the device */ + FILL_BULK_URB (bluetooth->read_urb, bluetooth->dev, + usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress), + bluetooth->bulk_in_buffer, + bluetooth->bulk_in_buffer_size, + bluetooth_read_bulk_callback, bluetooth); + result = usb_submit_urb(bluetooth->read_urb); + if (result) + dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result); #endif - FILL_INT_URB(bluetooth->interrupt_in_urb, bluetooth->dev, - usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), - bluetooth->interrupt_in_buffer, bluetooth->interrupt_in_buffer_size, - bluetooth_int_callback, bluetooth, bluetooth->interrupt_in_interval); - result = usb_submit_urb(bluetooth->interrupt_in_urb); - if (result) - dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); + FILL_INT_URB (bluetooth->interrupt_in_urb, bluetooth->dev, + usb_rcvintpipe(bluetooth->dev, bluetooth->interrupt_in_endpointAddress), + bluetooth->interrupt_in_buffer, + bluetooth->interrupt_in_buffer_size, + bluetooth_int_callback, bluetooth, + bluetooth->interrupt_in_interval); + result = usb_submit_urb(bluetooth->interrupt_in_urb); + if (result) + dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result); + } + + up(&bluetooth->lock); return 0; } @@ -414,18 +422,24 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not opened"); return; } - /* shutdown any bulk reads and writes that might be going on */ - for (i = 0; i < NUM_BULK_URBS; ++i) - usb_unlink_urb (bluetooth->write_urb_pool[i]); - usb_unlink_urb (bluetooth->read_urb); - usb_unlink_urb (bluetooth->interrupt_in_urb); - - bluetooth->active = 0; + down (&bluetooth->lock); + + --bluetooth->open_count; + if (bluetooth->open_count <= 0) { + bluetooth->open_count = 0; + + /* shutdown any bulk reads and writes that might be going on */ + for (i = 0; i < NUM_BULK_URBS; ++i) + usb_unlink_urb (bluetooth->write_urb_pool[i]); + usb_unlink_urb (bluetooth->read_urb); + usb_unlink_urb (bluetooth->interrupt_in_urb); + } + up(&bluetooth->lock); } @@ -447,7 +461,7 @@ dbg(__FUNCTION__ " - %d byte(s)", count); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not opened"); return -EINVAL; } @@ -572,7 +586,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -EINVAL; } @@ -598,7 +612,7 @@ return -ENODEV; } - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -EINVAL; } @@ -624,7 +638,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -645,7 +659,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -664,7 +678,7 @@ dbg(__FUNCTION__ " - cmd 0x%.4x", cmd); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return -ENODEV; } @@ -684,7 +698,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -706,7 +720,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -731,7 +745,7 @@ dbg(__FUNCTION__); - if (!bluetooth->active) { + if (!bluetooth->open_count) { dbg (__FUNCTION__ " - device not open"); return; } @@ -961,7 +975,7 @@ } exit: - if (!bluetooth || !bluetooth->active) + if (!bluetooth || !bluetooth->open_count) return; FILL_BULK_URB(bluetooth->read_urb, bluetooth->dev, @@ -1102,6 +1116,7 @@ bluetooth->minor = minor; bluetooth->tqueue.routine = bluetooth_softint; bluetooth->tqueue.data = bluetooth; + init_MUTEX(&bluetooth->lock); /* record the interface number for the control out */ bluetooth->control_out_bInterfaceNum = control_out_endpoint; @@ -1217,10 +1232,10 @@ int i; if (bluetooth) { - if ((bluetooth->active) && (bluetooth->tty)) + if ((bluetooth->open_count) && (bluetooth->tty)) tty_hangup(bluetooth->tty); - bluetooth->active = 0; + bluetooth->open_count = 0; if (bluetooth->read_urb) { usb_unlink_urb (bluetooth->read_urb); diff -urN linux-2.5.1-pre7/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c --- linux-2.5.1-pre7/drivers/usb/dc2xx.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/dc2xx.c Sat Dec 8 21:05:03 2001 @@ -199,7 +199,7 @@ retval = count; break; } - if (retval != USB_ST_TIMEOUT) + if (retval != -ETIMEDOUT) break; interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT); @@ -267,7 +267,7 @@ } else if (!result) break; - if (result == USB_ST_TIMEOUT) { /* NAK - delay a bit */ + if (result == -ETIMEDOUT) { /* NAK - delay a bit */ if (!maxretry--) { if (!bytes_written) bytes_written = -ETIME; diff -urN linux-2.5.1-pre7/drivers/usb/devices.c linux/drivers/usb/devices.c --- linux-2.5.1-pre7/drivers/usb/devices.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/devices.c Sat Dec 8 21:05:03 2001 @@ -139,9 +139,12 @@ {USB_CLASS_PHYSICAL, "PID"}, {USB_CLASS_PRINTER, "print"}, {USB_CLASS_MASS_STORAGE, "stor."}, - {USB_CLASS_DATA, "data"}, + {USB_CLASS_CDC_DATA, "data"}, {USB_CLASS_APP_SPEC, "app."}, {USB_CLASS_VENDOR_SPEC, "vend."}, + {USB_CLASS_STILL_IMAGE, "still"}, + {USB_CLASS_CSCID, "scard"}, + {USB_CLASS_CONTENT_SEC, "c-sec"}, {-1, "unk."} /* leave as last */ }; diff -urN linux-2.5.1-pre7/drivers/usb/devio.c linux/drivers/usb/devio.c --- linux-2.5.1-pre7/drivers/usb/devio.c Fri Nov 2 17:18:58 2001 +++ linux/drivers/usb/devio.c Sat Dec 8 21:05:03 2001 @@ -276,7 +276,7 @@ list_del(&as->asynclist); INIT_LIST_HEAD(&as->asynclist); spin_unlock_irqrestore(&ps->lock, flags); - /* usb_unlink_urb calls the completion handler with status == USB_ST_URB_KILLED */ + /* usb_unlink_urb calls the completion handler with status == -ENOENT */ usb_unlink_urb(&as->urb); spin_lock_irqsave(&ps->lock, flags); } @@ -299,11 +299,12 @@ { struct dev_state *ps = (struct dev_state *)context; - ps->ifclaimed = 0; + if (ps) + ps->ifclaimed = 0; } struct usb_driver usbdevfs_driver = { - name: "usbdevfs", + name: "usbfs", probe: driver_probe, disconnect: driver_disconnect, }; diff -urN linux-2.5.1-pre7/drivers/usb/hid-core.c linux/drivers/usb/hid-core.c --- linux-2.5.1-pre7/drivers/usb/hid-core.c Sun Sep 16 11:07:43 2001 +++ linux/drivers/usb/hid-core.c Sat Dec 8 21:05:03 2001 @@ -897,7 +897,7 @@ u8 data[len]; int read; - if ((read = usb_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) { + if ((read = hid_get_report(hid->dev, hid->ifnum, report->type + 1, report->id, data, len)) != len) { dbg("reading report type %d id %d failed len %d read %d", report->type + 1, report->id, len, read); return; } @@ -1064,7 +1064,7 @@ list = report_enum->report_list.next; while (list != &report_enum->report_list) { report = (struct hid_report *) list; - usb_set_idle(hid->dev, hid->ifnum, 0, report->id); + hid_set_idle(hid->dev, hid->ifnum, 0, report->id); hid_read_report(hid, report); list = list->next; } @@ -1089,6 +1089,16 @@ { 0, 0 } }; +static int get_class_descriptor(struct usb_device *dev, int ifnum, + unsigned char type, void *buf, int size) +{ + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, + (type << 8), ifnum, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); +} + + static struct hid_device *usb_hid_configure(struct usb_device *dev, int ifnum) { struct usb_interface_descriptor *interface = dev->actconfig->interface[ifnum].altsetting + 0; @@ -1102,14 +1112,14 @@ if ((hid_blacklist[n].idVendor == dev->descriptor.idVendor) && (hid_blacklist[n].idProduct == dev->descriptor.idProduct)) return NULL; - if (usb_get_extra_descriptor(interface, USB_DT_HID, &hdesc) && ((!interface->bNumEndpoints) || - usb_get_extra_descriptor(&interface->endpoint[0], USB_DT_HID, &hdesc))) { + if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->bNumEndpoints) || + usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { dbg("class descriptor not present\n"); return NULL; } for (n = 0; n < hdesc->bNumDescriptors; n++) - if (hdesc->desc[n].bDescriptorType == USB_DT_REPORT) + if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { @@ -1120,7 +1130,7 @@ { __u8 rdesc[rsize]; - if ((n = usb_get_class_descriptor(dev, interface->bInterfaceNumber, USB_DT_REPORT, 0, rdesc, rsize)) < 0) { + if ((n = get_class_descriptor(dev, interface->bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { dbg("reading report descriptor failed"); return NULL; } @@ -1170,7 +1180,7 @@ for (n = 0; n < HID_CONTROL_FIFO_SIZE; n++) { hid->out[n].dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - hid->out[n].dr.request = USB_REQ_SET_REPORT; + hid->out[n].dr.request = HID_REQ_SET_REPORT; hid->out[n].dr.index = cpu_to_le16(hid->ifnum); } @@ -1198,7 +1208,7 @@ #if 0 if (interface->bInterfaceSubClass == 1) - usb_set_protocol(dev, hid->ifnum, 1); + hid_set_protocol(dev, hid->ifnum, 1); #endif return hid; @@ -1236,7 +1246,7 @@ c = "Device"; for (i = 0; i < hid->maxapplication; i++) - if (IS_INPUT_APPLICATION(hid->application[i])) { + if ((hid->application[i] & 0xffff) < ARRAY_SIZE(hid_types)) { c = hid_types[hid->application[i] & 0xffff]; break; } diff -urN linux-2.5.1-pre7/drivers/usb/hid.h linux/drivers/usb/hid.h --- linux-2.5.1-pre7/drivers/usb/hid.h Tue Nov 13 17:45:27 2001 +++ linux/drivers/usb/hid.h Sat Dec 8 21:05:03 2001 @@ -30,6 +30,88 @@ * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ +/* + * HID class requests + */ +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_SET_PROTOCOL 0x0B + +/* + * HID class descriptor types + */ +#define HID_DT_HID (USB_TYPE_CLASS | 0x01) +#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) +#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) + +/* + * Utilities for class control messaging + */ +static inline int +hid_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (duration << 8) | report_id, ifnum, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); +} + +static inline int +hid_get_protocol(struct usb_device *dev, int ifnum) +{ + unsigned char type; + int ret; + + if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_PROTOCOL, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + 0, ifnum, &type, 1, + HZ * USB_CTRL_GET_TIMEOUT)) < 0) + return ret; + + return type; +} + +static inline int +hid_set_protocol(struct usb_device *dev, int ifnum, int protocol) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + protocol, ifnum, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); +} + +static inline int +hid_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + HID_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, ifnum, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); +} + +static inline int +hid_set_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size) +{ + return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + HID_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, ifnum, buf, size, HZ); + // FIXME USB_CTRL_SET_TIMEOUT +} + + +/* + * "Boot Protocol" keyboard/mouse drivers use don't use all of HID; + * they're a lot smaller but can't support all the device features. + */ +#ifndef _HID_BOOT_PROTOCOL + #include #include #include @@ -359,9 +441,7 @@ #else #define hid_dump_input(a,b) do { } while (0) #define hid_dump_device(c) do { } while (0) -#endif - -#endif +#endif /* DEBUG */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || ( a == 0x000c0001)) @@ -372,3 +452,8 @@ void hid_write_report(struct hid_device *, struct hid_report *); void hid_read_report(struct hid_device *, struct hid_report *); void hid_init_reports(struct hid_device *hid); + +#endif /* !_HID_BOOT_PROTOCOL */ + +#endif /* !__HID_H */ + diff -urN linux-2.5.1-pre7/drivers/usb/inode.c linux/drivers/usb/inode.c --- linux-2.5.1-pre7/drivers/usb/inode.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/inode.c Sat Dec 8 21:05:03 2001 @@ -654,7 +654,13 @@ return NULL; } +/* + * The usbdevfs name is now depreciated (as of 2.5.1). + * It will be removed when the 2.7.x development cycle is started. + * You have been warned :) + */ static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbdevfs_read_super, FS_SINGLE); +static DECLARE_FSTYPE(usb_fs_type, "usbfs", usbdevfs_read_super, FS_SINGLE); /* --------------------------------------------------------------------- */ @@ -747,7 +753,12 @@ } if ((ret = usb_register(&usbdevfs_driver))) return ret; + if ((ret = register_filesystem(&usb_fs_type))) { + usb_deregister(&usbdevfs_driver); + return ret; + } if ((ret = register_filesystem(&usbdevice_fs_type))) { + unregister_filesystem(&usb_fs_type); usb_deregister(&usbdevfs_driver); return ret; } @@ -761,6 +772,7 @@ void __exit usbdevfs_cleanup(void) { usb_deregister(&usbdevfs_driver); + unregister_filesystem(&usb_fs_type); unregister_filesystem(&usbdevice_fs_type); #ifdef CONFIG_PROC_FS if (usbdir) @@ -768,7 +780,3 @@ #endif } -#if 0 -module_init(usbdevfs_init); -module_exit(usbdevfs_cleanup); -#endif diff -urN linux-2.5.1-pre7/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c --- linux-2.5.1-pre7/drivers/usb/kaweth.c Tue Nov 13 09:19:41 2001 +++ linux/drivers/usb/kaweth.c Sat Dec 8 21:05:03 2001 @@ -944,6 +944,13 @@ } +// FIXME this completion stuff is a modified clone of +// an OLD version of some stuff in usb.c ... +struct usb_api_data { + wait_queue_head_t wqh; + int done; +}; + /*-------------------------------------------------------------------* * completion handler for compatibility wrappers (sync control/bulk) * *-------------------------------------------------------------------*/ diff -urN linux-2.5.1-pre7/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c --- linux-2.5.1-pre7/drivers/usb/mdc800.c Tue Oct 9 15:15:02 2001 +++ linux/drivers/usb/mdc800.c Sat Dec 8 21:05:03 2001 @@ -30,8 +30,14 @@ * * The driver supports only one camera. * - * (08/04/2001) gb + * Fix: mdc800 used sleep_on and slept with io_lock held. + * Converted sleep_on to waitqueues with schedule_timeout and made io_lock + * a semaphore from a spinlock. + * by Oliver Neukum <520047054719-0001@t-online.de> + * (02/12/2001) + * * Identify version on module load. + * (08/04/2001) gb * * version 0.7.5 * Fixed potential SMP races with Spinlocks. @@ -136,6 +142,7 @@ purb_t irq_urb; wait_queue_head_t irq_wait; + int irq_woken; char* irq_urb_buffer; int camera_busy; // is camera busy ? @@ -145,11 +152,13 @@ purb_t write_urb; char* write_urb_buffer; wait_queue_head_t write_wait; + int written; purb_t download_urb; char* download_urb_buffer; wait_queue_head_t download_wait; + int downloaded; int download_left; // Bytes left to download ? @@ -159,7 +168,7 @@ int out_count; // Bytes in the buffer int open; // Camera device open ? - spinlock_t io_lock; // IO -lock + struct semaphore io_lock; // IO -lock char in [8]; // Command Input Buffer int in_count; @@ -284,6 +293,7 @@ if (wake_up) { mdc800->camera_request_ready=0; + mdc800->irq_woken=1; wake_up_interruptible (&mdc800->irq_wait); } } @@ -300,9 +310,19 @@ */ static int mdc800_usb_waitForIRQ (int mode, int msec) { + DECLARE_WAITQUEUE(wait, current); + mdc800->camera_request_ready=1+mode; - interruptible_sleep_on_timeout (&mdc800->irq_wait, msec*HZ/1000); + add_wait_queue(&mdc800->irq_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->irq_woken) + { + schedule_timeout (msec*HZ/1000); + } + remove_wait_queue(&mdc800->irq_wait, &wait); + set_current_state(TASK_RUNNING); + mdc800->irq_woken = 0; if (mdc800->camera_request_ready>0) { @@ -337,6 +357,7 @@ { mdc800->state=READY; } + mdc800->written = 1; wake_up_interruptible (&mdc800->write_wait); } @@ -364,6 +385,7 @@ { err ("request bytes fails (status:%i)", urb->status); } + mdc800->downloaded = 1; wake_up_interruptible (&mdc800->download_wait); } @@ -445,7 +467,7 @@ info ("Found Mustek MDC800 on USB."); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); mdc800->dev=dev; mdc800->open=0; @@ -484,7 +506,7 @@ mdc800->state=READY; - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return mdc800; } @@ -558,7 +580,7 @@ int retval=0; int errn=0; - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { @@ -594,7 +616,7 @@ dbg ("Mustek MDC800 device opened."); error_out: - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return errn; } @@ -607,10 +629,9 @@ int retval=0; dbg ("Mustek MDC800 device closed."); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->open && (mdc800->state != NOT_CONNECTED)) { - spin_unlock(&mdc800->io_lock); usb_unlink_urb (mdc800->irq_urb); usb_unlink_urb (mdc800->write_urb); usb_unlink_urb (mdc800->download_urb); @@ -618,11 +639,10 @@ } else { - spin_unlock (&mdc800->io_lock); retval=-EIO; } - + up(&mdc800->io_lock); return retval; } @@ -634,22 +654,23 @@ { int left=len, sts=len; /* single transfer size */ char* ptr=buf; + DECLARE_WAITQUEUE(wait, current); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (mdc800->state == WORKING) { warn ("Illegal State \"working\" reached during read ?!"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -657,7 +678,7 @@ { if (signal_pending (current)) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } @@ -676,21 +697,29 @@ if (usb_submit_urb (mdc800->download_urb)) { err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } - interruptible_sleep_on_timeout (&mdc800->download_wait, TO_DOWNLOAD_GET_READY*HZ/1000); + add_wait_queue(&mdc800->download_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->downloaded) + { + schedule_timeout (TO_DOWNLOAD_GET_READY*HZ/1000); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&mdc800->download_wait, &wait); + mdc800->downloaded = 0; if (mdc800->download_urb->status != 0) { err ("request download-bytes fails (status=%i)",mdc800->download_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } } else { /* No more bytes -> that's an error*/ - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -704,7 +733,7 @@ } } - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return len-left; } @@ -718,16 +747,17 @@ static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos) { int i=0; + DECLARE_WAITQUEUE(wait, current); - spin_lock (&mdc800->io_lock); + down (&mdc800->io_lock); if (mdc800->state != READY) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } if (!mdc800->open ) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EBUSY; } @@ -735,7 +765,7 @@ { if (signal_pending (current)) { - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EINTR; } @@ -757,7 +787,7 @@ else { err ("Command is to long !\n"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -769,7 +799,7 @@ if (mdc800_usb_waitForIRQ (0,TO_GET_READY)) { err ("Camera didn't get ready.\n"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -781,14 +811,22 @@ if (usb_submit_urb (mdc800->write_urb)) { err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } - interruptible_sleep_on_timeout (&mdc800->write_wait, TO_WRITE_GET_READY*HZ/1000); + add_wait_queue(&mdc800->write_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (!mdc800->written) + { + schedule_timeout (TO_WRITE_GET_READY*HZ/1000); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&mdc800->write_wait, &wait); + mdc800->written = 0; if (mdc800->state == WORKING) { usb_unlink_urb (mdc800->write_urb); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -800,7 +838,7 @@ { err ("call 0x07 before 0x05,0x3e"); mdc800->state=READY; - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } mdc800->pic_len=-1; @@ -819,7 +857,7 @@ if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ)) { err ("requesting answer from irq fails"); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } @@ -847,7 +885,7 @@ if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND)) { err ("Command Timeout."); - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return -EIO; } } @@ -857,7 +895,7 @@ } i++; } - spin_unlock (&mdc800->io_lock); + up (&mdc800->io_lock); return i; } @@ -916,11 +954,15 @@ mdc800->dev=0; mdc800->open=0; mdc800->state=NOT_CONNECTED; - spin_lock_init (&mdc800->io_lock); + init_MUTEX (&mdc800->io_lock); init_waitqueue_head (&mdc800->irq_wait); init_waitqueue_head (&mdc800->write_wait); init_waitqueue_head (&mdc800->download_wait); + + mdc800->irq_woken = 0; + mdc800->downloaded = 0; + mdc800->written = 0; try (mdc800->irq_urb_buffer=kmalloc (8, GFP_KERNEL)); try (mdc800->write_urb_buffer=kmalloc (8, GFP_KERNEL)); diff -urN linux-2.5.1-pre7/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c --- linux-2.5.1-pre7/drivers/usb/pegasus.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/pegasus.c Sat Dec 8 21:05:03 2001 @@ -53,7 +53,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.4.21 (2001/08/27)" +#define DRIVER_VERSION "v0.4.22 (2001/12/07)" #define DRIVER_AUTHOR "Petko Manolov " #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" @@ -102,7 +102,7 @@ return; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: if ( pegasus->flags & ETH_REGS_CHANGE ) { pegasus->flags &= ~ETH_REGS_CHANGE; pegasus->flags |= ETH_REGS_CHANGED; @@ -110,9 +110,9 @@ return; } break; - case USB_ST_URB_PENDING: + case -EINPROGRESS: return; - case USB_ST_URB_KILLED: + case -ENOENT: break; default: warn( __FUNCTION__ " status %d", urb->status); @@ -526,9 +526,9 @@ pegasus->flags |= PEGASUS_RX_BUSY; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_NORESPONSE: + case -ETIMEDOUT: dbg( "reset MAC" ); pegasus->flags &= ~PEGASUS_RX_BUSY; break; @@ -607,9 +607,9 @@ return; switch ( urb->status ) { - case USB_ST_NOERROR: + case 0: break; - case USB_ST_URB_KILLED: + case -ENOENT: return; default: info("intr status %d", urb->status); @@ -713,10 +713,8 @@ pegasus_t *pegasus = (pegasus_t *)net->priv; int res; - MOD_INC_USE_COUNT; if ( (res = enable_net_traffic(net, pegasus->usb)) ) { err("can't enable_net_traffic() - %d", res); - MOD_DEC_USE_COUNT; return -EIO; } FILL_BULK_URB( &pegasus->rx_urb, pegasus->usb, @@ -755,7 +753,6 @@ #ifdef PEGASUS_USE_INTR usb_unlink_urb( &pegasus->intr_urb ); #endif - MOD_DEC_USE_COUNT; return 0; } @@ -867,6 +864,7 @@ pegasus->usb = dev; pegasus->net = net; + SET_MODULE_OWNER(net); net->priv = pegasus; net->open = pegasus_open; net->stop = pegasus_close; diff -urN linux-2.5.1-pre7/drivers/usb/pegasus.h linux/drivers/usb/pegasus.h --- linux-2.5.1-pre7/drivers/usb/pegasus.h Wed Oct 17 14:34:06 2001 +++ linux/drivers/usb/pegasus.h Sat Dec 8 21:05:03 2001 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@dce.bg) + * Copyright (c) 1999,2000 Petko Manolov - Petkan (pmanolov@lnxw.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -138,6 +138,7 @@ #define VENDOR_DLINK 0x2001 #define VENDOR_ELSA 0x05cc #define VENDOR_IODATA 0x04bb +#define VENDOR_KINGSTON 0x0951 #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 @@ -210,6 +211,8 @@ DEFAULT_GPIO_RESET ) PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, DEFAULT_GPIO_RESET ) +PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a, + DEFAULT_GPIO_RESET) PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b, diff -urN linux-2.5.1-pre7/drivers/usb/rio500.c linux/drivers/usb/rio500.c --- linux-2.5.1-pre7/drivers/usb/rio500.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/rio500.c Sat Dec 8 21:05:03 2001 @@ -324,7 +324,7 @@ dbg("write stats: result:%d thistime:%lu partial:%u", result, thistime, partial); - if (result == USB_ST_TIMEOUT) { /* NAK - so hold for a while */ + if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ if (!maxretry--) { errn = -ETIME; goto error; @@ -403,7 +403,7 @@ if (partial) { count = this_read = partial; - } else if (result == USB_ST_TIMEOUT || result == 15) { /* FIXME: 15 ??? */ + } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ if (!maxretry--) { up(&(rio->lock)); err("read_rio: maxretry timeout"); @@ -412,7 +412,7 @@ interruptible_sleep_on_timeout(&rio->wait_q, NAK_TIMEOUT); continue; - } else if (result != USB_ST_DATAUNDERRUN) { + } else if (result != -EREMOTEIO) { up(&(rio->lock)); err("Read Whoops - result:%u partial:%u this_read:%u", result, partial, this_read); diff -urN linux-2.5.1-pre7/drivers/usb/scanner.c linux/drivers/usb/scanner.c --- linux-2.5.1-pre7/drivers/usb/scanner.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/scanner.c Sat Dec 8 21:05:03 2001 @@ -278,6 +278,28 @@ * - Users are now notified to consult the Documentation/usb/scanner.txt * for common error messages rather than the maintainer. * + * 0.4.7 11/28/2001 + * - Fixed typo in Documentation/scanner.txt. Thanks to + * Karel for pointing it out. + * - Added ID's for a Memorex 6136u. Thanks to =C1lvaro Gaspar de + * Valenzuela" . + * - Added ID's for Agfa e25. Thanks to Heinrich + * Rust . Also reported to work with + * Linux and SANE (?). + * - Added Canon FB620U, D646U, and 1220U ID's. Thanks to Paul + * Rensing . For more info + * on Linux support for these models, contact + * salvestrini@users.sourceforge.net. + * - Added Plustek OpticPro UT12, OpticPro U24, KYE/Genius + * ColorPage-HR6 V2 ID's in addition to many "Unknown" models + * under those vendors. Thanks to + * Jaeger, Gerhard" . These scanner are + * apparently based upon the LM983x IC's. + * - Applied Frank's patch that addressed some locking and module + * referencing counts. Thanks to both + * Frank Zago and + * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. + * * TODO * - Performance * - Select/poll methods @@ -324,17 +346,16 @@ struct scn_usb_data *scn; unsigned char *data; scn = urb->context; - down(&(scn->sem)); + data = &scn->button; data += 0; /* Keep gcc from complaining about unused var */ if (urb->status) { - up(&(scn->sem)); return; } dbg("irq_scanner(%d): data:%x", scn->scn_minor, *data); - up(&(scn->sem)); + return; } @@ -358,6 +379,7 @@ if (!p_scn_table[scn_minor]) { up(&scn_mutex); + MOD_DEC_USE_COUNT; err("open_scanner(%d): Unable to access minor data", scn_minor); return -ENODEV; } @@ -606,7 +628,7 @@ } ret = result; break; - } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) { + } else if ((result < 0) && (result != -EREMOTEIO)) { warn("read_scanner(%d): funky result:%d. Consult Documentation/usb/scanner.txt.", scn_minor, (int)result); ret = -EIO; break; @@ -939,6 +961,7 @@ /* Check to make sure that the last slot isn't already taken */ if (p_scn_table[scn_minor]) { err("probe_scanner: No more minor devices remaining."); + up(&scn_mutex); return NULL; } @@ -946,6 +969,7 @@ if (!(scn = kmalloc (sizeof (struct scn_usb_data), GFP_KERNEL))) { err("probe_scanner: Out of memory."); + up(&scn_mutex); return NULL; } memset (scn, 0, sizeof(struct scn_usb_data)); @@ -1028,9 +1052,11 @@ if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); + p_scn_table[scn_minor] = scn; + up(&scn_mutex); - return p_scn_table[scn_minor] = scn; + return scn; } static void diff -urN linux-2.5.1-pre7/drivers/usb/scanner.h linux/drivers/usb/scanner.h --- linux-2.5.1-pre7/drivers/usb/scanner.h Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/scanner.h Sat Dec 8 21:05:03 2001 @@ -86,12 +86,23 @@ { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */ + { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ + /* Canon */ + { USB_DEVICE(0x04a9, 0x2202) }, /* FB620U */ + { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ + { USB_DEVICE(0x04a9, 0x2207) }, /* 1220U */ /* Colorado -- See Primax/Colorado below */ /* Epson -- See Seiko/Epson below */ /* Genius */ { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ + { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ + { USB_DEVICE(0x0458, 0x2008) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2009) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2013) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2015) }, /* Unknown */ + { USB_DEVICE(0x0458, 0x2016) }, /* Unknown */ /* Hewlett Packard */ { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ @@ -108,6 +119,8 @@ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ /* Lifetec */ { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ + /* Memorex */ + { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */ // { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */ // { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */ @@ -128,6 +141,19 @@ { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x055f, 0x0008) }, /* 1200 CU Plus */ { USB_DEVICE(0x0ff5, 0x0010) }, /* BearPaw 1200F */ + /* Plustek */ + { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12 */ + { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro UT24 */ + { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0010) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0015) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ diff -urN linux-2.5.1-pre7/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c --- linux-2.5.1-pre7/drivers/usb/serial/belkin_sa.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/belkin_sa.c Sat Dec 8 21:05:03 2001 @@ -211,9 +211,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /*Start reading from the device*/ /* TODO: Look at possibility of submitting mulitple URBs to device to * enhance buffering. Win trace shows 16 initial read URBs. @@ -262,7 +260,7 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; + port->open_count = 0; } up (&port->sem); diff -urN linux-2.5.1-pre7/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c --- linux-2.5.1-pre7/drivers/usb/serial/cyberjack.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/cyberjack.c Sat Dec 8 21:05:03 2001 @@ -156,8 +156,7 @@ ++port->open_count; - if (!port->active) { - port->active = 1; + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces * the data through, otherwise it is scheduled, and with high * data rates (like with OHCI) data can get lost. @@ -201,8 +200,6 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - - port->active = 0; port->open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c --- linux-2.5.1-pre7/drivers/usb/serial/digi_acceleport.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/digi_acceleport.c Sat Dec 8 21:05:03 2001 @@ -14,6 +14,10 @@ * Peter Berger (pberger@brimson.com) * Al Borchers (borchers@steinerpoint.com) * +* (12/03/2001) gkh +* switched to using port->open_count instead of private version. +* Removed port->active +* * (04/08/2001) gb * Identify version on module load. * @@ -429,7 +433,6 @@ int dp_write_urb_in_use; unsigned int dp_modem_signals; wait_queue_head_t dp_modem_change_wait; - int dp_open_count; /* inc on open, dec on close */ int dp_transmit_idle; wait_queue_head_t dp_transmit_idle_wait; int dp_throttled; @@ -1380,7 +1383,7 @@ /* try to send any buffered data on this port, if it is open */ spin_lock( &priv->dp_port_lock ); priv->dp_write_urb_in_use = 0; - if( priv->dp_open_count && port->write_urb->status != -EINPROGRESS + if( port->open_count && port->write_urb->status != -EINPROGRESS && priv->dp_out_buf_len > 0 ) { *((unsigned char *)(port->write_urb->transfer_buffer)) @@ -1474,7 +1477,7 @@ unsigned long flags = 0; -dbg( "digi_open: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count ); +dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); /* be sure the device is started up */ if( digi_startup_device( port->serial ) != 0 ) @@ -1489,7 +1492,7 @@ } /* inc module use count before sleeping to wait for closes */ - ++priv->dp_open_count; + ++port->open_count; MOD_INC_USE_COUNT; /* wait for a close in progress to finish */ @@ -1498,7 +1501,7 @@ &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, &priv->dp_port_lock, flags ); if( signal_pending(current) ) { - --priv->dp_open_count; + --port->open_count; MOD_DEC_USE_COUNT; return( -EINTR ); } @@ -1507,13 +1510,11 @@ /* if port is already open, just return */ /* be sure exactly one open proceeds */ - if( port->active ) { + if( port->open_count != 1) { spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return( 0 ); } - /* first open, mark port as active */ - port->active = 1; spin_unlock_irqrestore( &priv->dp_port_lock, flags ); /* read modem signals automatically whenever they change */ @@ -1554,17 +1555,17 @@ unsigned long flags = 0; -dbg( "digi_close: TOP: port=%d, active=%d, open_count=%d", priv->dp_port_num, port->active, priv->dp_open_count ); +dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); /* do cleanup only after final close on this port */ spin_lock_irqsave( &priv->dp_port_lock, flags ); - if( priv->dp_open_count > 1 ) { - --priv->dp_open_count; + if( port->open_count > 1 ) { + --port->open_count; MOD_DEC_USE_COUNT; spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return; - } else if( priv->dp_open_count <= 0 ) { + } else if( port->open_count <= 0 ) { spin_unlock_irqrestore( &priv->dp_port_lock, flags ); return; } @@ -1638,10 +1639,9 @@ tty->closing = 0; spin_lock_irqsave( &priv->dp_port_lock, flags ); - port->active = 0; priv->dp_write_urb_in_use = 0; priv->dp_in_close = 0; - --priv->dp_open_count; + --port->open_count; MOD_DEC_USE_COUNT; wake_up_interruptible( &priv->dp_close_wait ); spin_unlock_irqrestore( &priv->dp_port_lock, flags ); @@ -1710,8 +1710,6 @@ /* number of regular ports + 1 for the out-of-band port */ for( i=0; itype->num_ports+1; i++ ) { - serial->port[i].active = 0; - /* allocate port private structure */ priv = serial->port[i].private = (digi_port_t *)kmalloc( sizeof(digi_port_t), @@ -1730,7 +1728,6 @@ priv->dp_write_urb_in_use = 0; priv->dp_modem_signals = 0; init_waitqueue_head( &priv->dp_modem_change_wait ); - priv->dp_open_count = 0; priv->dp_transmit_idle = 0; init_waitqueue_head( &priv->dp_transmit_idle_wait ); priv->dp_throttled = 0; @@ -1789,9 +1786,9 @@ for( i=0; itype->num_ports; i++ ) { priv = serial->port[i].private; spin_lock_irqsave( &priv->dp_port_lock, flags ); - while( priv->dp_open_count > 0 ) { + while( serial->port[i].open_count > 0 ) { MOD_DEC_USE_COUNT; - --priv->dp_open_count; + --serial->port[i].open_count; } spin_unlock_irqrestore( &priv->dp_port_lock, flags ); } @@ -1883,7 +1880,7 @@ /* do not process callbacks on closed ports */ /* but do continue the read chain */ - if( priv->dp_open_count == 0 ) + if( port->open_count == 0 ) return( 0 ); /* short/multiple packet check */ @@ -2017,7 +2014,7 @@ if( val & DIGI_READ_INPUT_SIGNALS_CTS ) { priv->dp_modem_signals |= TIOCM_CTS; /* port must be open to use tty struct */ - if( priv->dp_open_count + if( port->open_count && port->tty->termios->c_cflag & CRTSCTS ) { port->tty->hw_stopped = 0; digi_wakeup_write( port ); @@ -2025,7 +2022,7 @@ } else { priv->dp_modem_signals &= ~TIOCM_CTS; /* port must be open to use tty struct */ - if( priv->dp_open_count + if( port->open_count && port->tty->termios->c_cflag & CRTSCTS ) { port->tty->hw_stopped = 1; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c --- linux-2.5.1-pre7/drivers/usb/serial/empeg.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/empeg.c Sat Dec 8 21:05:03 2001 @@ -161,12 +161,11 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { + if (port->open_count == 1) { /* Force default termio settings */ empeg_set_termios (port, NULL) ; - port->active = 1; bytes_in = 0; bytes_out = 0; @@ -218,7 +217,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c --- linux-2.5.1-pre7/drivers/usb/serial/ftdi_sio.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/ftdi_sio.c Sat Dec 8 21:05:03 2001 @@ -321,9 +321,7 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active){ - port->active = 1; - + if (port->open_count == 1){ /* This will push the characters through immediately rather than queue a task to deliver them */ port->tty->low_latency = 1; @@ -404,7 +402,6 @@ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } else { /* Send a HUP if necessary */ diff -urN linux-2.5.1-pre7/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c --- linux-2.5.1-pre7/drivers/usb/serial/io_edgeport.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/io_edgeport.c Sat Dec 8 21:05:03 2001 @@ -987,9 +987,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces the data through, otherwise it is scheduled, and with high data rates (like with OHCI) data can get lost. */ @@ -1000,7 +998,6 @@ serial = port->serial; edge_serial = (struct edgeport_serial *)serial->private; if (edge_serial == NULL) { - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1064,7 +1061,6 @@ if (response < 0) { err(__FUNCTION__" - error sending open port command"); edge_port->openPending = FALSE; - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1080,7 +1076,6 @@ /* open timed out */ dbg(__FUNCTION__" - open timedout"); edge_port->openPending = FALSE; - port->active = 0; port->open_count = 0; MOD_DEC_USE_COUNT; return -ENODEV; @@ -1285,7 +1280,6 @@ if (edge_port->txfifo.fifo) { kfree(edge_port->txfifo.fifo); } - port->active = 0; port->open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c --- linux-2.5.1-pre7/drivers/usb/serial/ir-usb.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/ir-usb.c Sat Dec 8 21:05:03 2001 @@ -206,9 +206,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { if (buffer_size) { /* override the default buffer sizes */ buffer = kmalloc (buffer_size, GFP_KERNEL); @@ -268,7 +266,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c --- linux-2.5.1-pre7/drivers/usb/serial/keyspan.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/keyspan.c Sat Dec 8 21:05:03 2001 @@ -468,7 +468,7 @@ p_priv = (struct keyspan_port_private *)(port->private); dbg (__FUNCTION__ " urb %d\n", urb == p_priv->out_urbs[1]); - if (port->active) { + if (port->open_count) { queue_task(&port->tqueue, &tq_immediate); mark_bh(IMMEDIATE_BH); } @@ -880,9 +880,8 @@ MOD_INC_USE_COUNT; down (&port->sem); + already_active = port->open_count; ++port->open_count; - already_active = port->active; - port->active = 1; up (&port->sem); if (already_active) @@ -948,18 +947,15 @@ down (&port->sem); if (--port->open_count <= 0) { - if (port->active) { - if (serial->dev) { - /* Stop reading/writing urbs */ - stop_urb(p_priv->inack_urb); - stop_urb(p_priv->outcont_urb); - for (i = 0; i < 2; i++) { - stop_urb(p_priv->in_urbs[i]); - stop_urb(p_priv->out_urbs[i]); - } + if (serial->dev) { + /* Stop reading/writing urbs */ + stop_urb(p_priv->inack_urb); + stop_urb(p_priv->outcont_urb); + for (i = 0; i < 2; i++) { + stop_urb(p_priv->in_urbs[i]); + stop_urb(p_priv->out_urbs[i]); } } - port->active = 0; port->open_count = 0; port->tty = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c --- linux-2.5.1-pre7/drivers/usb/serial/keyspan_pda.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/keyspan_pda.c Sat Dec 8 21:05:03 2001 @@ -675,9 +675,7 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* find out how much room is in the Tx ring */ rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 6, /* write_room */ @@ -723,7 +721,6 @@ return rc; error: --port->open_count; - port->active = 0; MOD_DEC_USE_COUNT; up (&port->sem); return rc; @@ -748,7 +745,6 @@ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; port->open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c --- linux-2.5.1-pre7/drivers/usb/serial/mct_u232.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/mct_u232.c Sat Dec 8 21:05:03 2001 @@ -27,6 +27,9 @@ * 10-Nov-2001 Wolfgang Grandegger * - Fixed an endianess problem with the baudrate selection for PowerPC. * + * 06-Dec-2001 Martin Hamilton + * Added support for the Belkin F5U109 DB9 adaptor + * * 30-May-2001 Greg Kroah-Hartman * switched from using spinlock to a semaphore, which fixes lots of problems. * @@ -133,6 +136,7 @@ { USB_DEVICE(MCT_U232_VID, MCT_U232_PID) }, { USB_DEVICE(MCT_U232_VID, MCT_U232_SITECOM_PID) }, { USB_DEVICE(MCT_U232_VID, MCT_U232_DU_H3SP_PID) }, + { USB_DEVICE(MCT_U232_BELKIN_F5U109_VID, MCT_U232_BELKIN_F5U109_PID) }, { } /* Terminating entry */ }; @@ -175,7 +179,8 @@ #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) { - if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID) { + if (serial->dev->descriptor.idProduct == MCT_U232_SITECOM_PID + || serial->dev->descriptor.idProduct == MCT_U232_BELKIN_F5U109_PID) { switch (value) { case 300: return 0x01; case 600: return 0x02; /* this one not tested */ @@ -340,9 +345,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* Compensate for a hardware bug: although the Sitecom U232-P25 * device reports a maximum output packet size of 32 bytes, * it seems to be able to accept only 16 bytes (and that's what @@ -416,7 +419,7 @@ usb_unlink_urb (port->read_urb); usb_unlink_urb (port->interrupt_in_urb); } - port->active = 0; + port->open_count = 0; } up (&port->sem); diff -urN linux-2.5.1-pre7/drivers/usb/serial/mct_u232.h linux/drivers/usb/serial/mct_u232.h --- linux-2.5.1-pre7/drivers/usb/serial/mct_u232.h Thu Feb 8 16:30:40 2001 +++ linux/drivers/usb/serial/mct_u232.h Sat Dec 8 21:05:03 2001 @@ -30,9 +30,12 @@ #define MCT_U232_SITECOM_PID 0x0230 /* Sitecom Product Id */ /* DU-H3SP USB BAY hub */ - #define MCT_U232_DU_H3SP_PID 0x0200 /* D-Link DU-H3SP USB BAY */ +/* Belkin badge the MCT U232-P9 as the F5U109 */ +#define MCT_U232_BELKIN_F5U109_VID 0x050d /* Vendor Id */ +#define MCT_U232_BELKIN_F5U109_PID 0x0109 /* Product Id */ + /* * Vendor Request Interface */ @@ -363,6 +366,25 @@ * bmAttributes = 03 (Interrupt) * wMaxPacketSize = 0002 * bInterval = 02 + * + * + * Hardware details (added by Martin Hamilton, 2001/12/06) + * ----------------------------------------------------------------- + * + * This info was gleaned from opening a Belkin F5U109 DB9 USB serial + * adaptor, which turns out to simply be a re-badged U232-P9. We + * know this because there is a sticky label on the circuit board + * which says "U232-P9" ;-) + * + * The circuit board inside the adaptor contains a Philips PDIUSBD12 + * USB endpoint chip and a Phillips P87C52UBAA microcontroller with + * embedded UART. Exhaustive documentation for these is available at: + * + * http://www.semiconductors.philips.com/pip/p87c52ubaa + * http://www.semiconductors.philips.com/pip/pdiusbd12 + * + * Thanks to Julian Highfield for the pointer to the Philips database. + * */ #endif /* __LINUX_USB_SERIAL_MCT_U232_H */ diff -urN linux-2.5.1-pre7/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c --- linux-2.5.1-pre7/drivers/usb/serial/omninet.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/omninet.c Sat Dec 8 21:05:03 2001 @@ -161,14 +161,11 @@ MOD_INC_USE_COUNT; ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); if( !od ) { err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data)); - --port->open_count; - port->active = 0; + port->open_count = 0; up (&port->sem); MOD_DEC_USE_COUNT; return -ENOMEM; @@ -219,7 +216,6 @@ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; od = (struct omninet_data *)port->private; if (od) diff -urN linux-2.5.1-pre7/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c --- linux-2.5.1-pre7/drivers/usb/serial/pl2303.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/pl2303.c Sat Dec 8 21:05:03 2001 @@ -371,9 +371,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { #define FISH(a,b,c,d) \ result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \ b, a, c, d, buf, 1, 100); \ @@ -478,8 +476,6 @@ "(interrupt_in_urb) failed with reason: %d", result); } - - port->active = 0; port->open_count = 0; } @@ -648,7 +644,7 @@ if (urb->status) { dbg (__FUNCTION__ " - urb->status = %d", urb->status); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port is closed, exiting."); return; } @@ -680,7 +676,7 @@ } /* Schedule the next read _if_ we are still open */ - if (port->active) { + if (port->open_count) { urb->dev = serial->dev; result = usb_submit_urb(urb); if (result) diff -urN linux-2.5.1-pre7/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h --- linux-2.5.1-pre7/drivers/usb/serial/usb-serial.h Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/usb-serial.h Sat Dec 8 21:05:03 2001 @@ -11,6 +11,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (12/03/2001) gkh + * removed active from the port structure. + * added documentation to the usb_serial_device_type structure + * * (10/10/2001) gkh * added vendor and product to serial structure. Needed to determine device * owner when the device is disconnected. @@ -65,7 +69,6 @@ struct usb_serial *serial; /* pointer back to the owner of this port */ struct tty_struct * tty; /* the coresponding tty for this port */ unsigned char number; - char active; /* someone has this device open */ unsigned char * interrupt_in_buffer; struct urb * interrupt_in_urb; @@ -111,21 +114,40 @@ #define NUM_DONT_CARE (-1) -/* This structure defines the individual serial converter. */ +/** + * usb_serial_device_type - a structure that defines a usb serial device + * @name: pointer to a string that describes this device. This string used + * in the syslog messages when a device is inserted or removed. + * @id_table: pointer to a list of usb_device_id structures that define all + * of the devices this structure can support. + * @num_interrupt_in: the number of interrupt in endpoints this device will + * have. + * @num_bulk_in: the number of bulk in endpoints this device will have. + * @num_bulk_out: the number of bulk out endpoints this device will have. + * @num_ports: the number of different ports this device will have. + * @startup: pointer to the driver's startup function. This will be called + * when the driver is inserted into the system. Return 0 to continue + * on with the initialization sequence. Anything else will abort it. + * @shutdown: pointer to the driver's shutdown function. This will be + * called when the device is removed from the system. + * + * This structure is defines a USB Serial device. It provides all of + * the information that the USB serial core code needs. If the function + * pointers are defined, then the USB serial core code will call them when + * the corresponding tty port functions are called. If they are not + * called, the generic serial function will be used instead. + */ struct usb_serial_device_type { char *name; const struct usb_device_id *id_table; char num_interrupt_in; char num_bulk_in; char num_bulk_out; - char num_ports; /* number of serial ports this device has */ + char num_ports; struct list_head driver_list; - /* function call to make before accepting driver */ - /* return 0 to continue initialization, anything else to abort */ int (*startup) (struct usb_serial *serial); - void (*shutdown) (struct usb_serial *serial); /* serial function calls */ diff -urN linux-2.5.1-pre7/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c --- linux-2.5.1-pre7/drivers/usb/serial/usbserial.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/usbserial.c Sat Dec 8 21:05:03 2001 @@ -545,7 +545,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); return; } @@ -570,7 +570,7 @@ dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not opened"); return -EINVAL; } @@ -595,7 +595,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } @@ -618,7 +618,7 @@ return -ENODEV; } - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } @@ -643,7 +643,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -668,7 +668,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -693,7 +693,7 @@ dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return -ENODEV; } @@ -718,7 +718,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -743,7 +743,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - if (!port->active) { + if (!port->open_count) { dbg (__FUNCTION__ " - port not open"); return; } @@ -787,9 +787,7 @@ ++port->open_count; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* force low_latency on so that our tty_push actually forces the data through, otherwise it is scheduled, and with high data rates (like with OHCI) data can get lost. */ @@ -798,13 +796,14 @@ /* if we have a bulk interrupt, start reading from it */ if (serial->num_bulk_in) { /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -835,8 +834,6 @@ if (serial->num_bulk_in) usb_unlink_urb (port->read_urb); } - - port->active = 0; port->open_count = 0; } @@ -879,13 +876,13 @@ usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); /* set up our urb */ - FILL_BULK_URB(port->write_urb, serial->dev, - usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), - port->write_urb->transfer_buffer, count, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - generic_write_bulk_callback), - port); + usb_fill_bulk_urb (port->write_urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + port->write_urb->transfer_buffer, count, + ((serial->type->write_bulk_callback) ? + serial->type->write_bulk_callback : + generic_write_bulk_callback), port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb); @@ -973,13 +970,14 @@ } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -1203,13 +1201,14 @@ err("Couldn't allocate bulk_in_buffer"); goto probe_error; } - FILL_BULK_URB(port->read_urb, dev, - usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), - port->bulk_in_buffer, buffer_size, - ((serial->type->read_bulk_callback) ? - serial->type->read_bulk_callback : - generic_read_bulk_callback), - port); + usb_fill_bulk_urb (port->read_urb, dev, + usb_rcvbulkpipe (dev, + endpoint->bEndpointAddress), + port->bulk_in_buffer, buffer_size, + ((serial->type->read_bulk_callback) ? + serial->type->read_bulk_callback : + generic_read_bulk_callback), + port); } for (i = 0; i < num_bulk_out; ++i) { @@ -1228,13 +1227,14 @@ err("Couldn't allocate bulk_out_buffer"); goto probe_error; } - FILL_BULK_URB(port->write_urb, dev, - usb_sndbulkpipe(dev, endpoint->bEndpointAddress), - port->bulk_out_buffer, buffer_size, - ((serial->type->write_bulk_callback) ? - serial->type->write_bulk_callback : - generic_write_bulk_callback), - port); + usb_fill_bulk_urb (port->write_urb, dev, + usb_sndbulkpipe (dev, + endpoint->bEndpointAddress), + port->bulk_out_buffer, buffer_size, + ((serial->type->write_bulk_callback) ? + serial->type->write_bulk_callback : + generic_write_bulk_callback), + port); } for (i = 0; i < num_interrupt_in; ++i) { @@ -1252,12 +1252,12 @@ err("Couldn't allocate interrupt_in_buffer"); goto probe_error; } - FILL_INT_URB(port->interrupt_in_urb, dev, - usb_rcvintpipe(dev, endpoint->bEndpointAddress), - port->interrupt_in_buffer, buffer_size, - serial->type->read_int_callback, - port, - endpoint->bInterval); + usb_fill_int_urb (port->interrupt_in_urb, dev, + usb_rcvintpipe (dev, + endpoint->bEndpointAddress), + port->interrupt_in_buffer, buffer_size, + serial->type->read_int_callback, port, + endpoint->bInterval); } /* initialize some parts of the port structures */ @@ -1335,7 +1335,7 @@ serial_shutdown (serial); for (i = 0; i < serial->num_ports; ++i) - serial->port[i].active = 0; + serial->port[i].open_count = 0; for (i = 0; i < serial->num_bulk_in; ++i) { port = &serial->port[i]; diff -urN linux-2.5.1-pre7/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c --- linux-2.5.1-pre7/drivers/usb/serial/visor.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/visor.c Sat Dec 8 21:05:03 2001 @@ -127,7 +127,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.6" +#define DRIVER_VERSION "v1.7" #define DRIVER_AUTHOR "Greg Kroah-Hartman " #define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver" @@ -251,8 +251,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; + if (port->open_count == 1) { bytes_in = 0; bytes_out = 0; @@ -262,10 +261,12 @@ port->tty->low_latency = 1; /* Start reading from the device */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); @@ -314,7 +315,6 @@ /* shutdown our bulk read */ usb_unlink_urb (port->read_urb); } - port->active = 0; port->open_count = 0; } up (&port->sem); @@ -375,8 +375,11 @@ usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer); /* build up our urb */ - FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), - urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port); + usb_fill_bulk_urb (urb, serial->dev, + usb_sndbulkpipe (serial->dev, + port->bulk_out_endpointAddress), + urb->transfer_buffer, transfer_size, + visor_write_bulk_callback, port); urb->transfer_flags |= USB_QUEUE_BULK; /* send it down the pipe */ @@ -506,10 +509,12 @@ } /* Continue trying to always read */ - FILL_BULK_URB(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); + usb_fill_bulk_urb (port->read_urb, serial->dev, + usb_rcvbulkpipe (serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); result = usb_submit_urb(port->read_urb); if (result) err(__FUNCTION__ " - failed resubmitting read urb, error %d", result); @@ -647,11 +652,8 @@ dbg (__FUNCTION__); /* stop reads and writes on all ports */ - for (i=0; i < serial->num_ports; ++i) { - while (serial->port[i].open_count > 0) { - visor_close (&serial->port[i], NULL); - } - } + for (i=0; i < serial->num_ports; ++i) + serial->port[i].open_count = 0; } diff -urN linux-2.5.1-pre7/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c --- linux-2.5.1-pre7/drivers/usb/serial/whiteheat.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/serial/whiteheat.c Sat Dec 8 21:05:03 2001 @@ -309,9 +309,7 @@ ++port->open_count; MOD_INC_USE_COUNT; - if (!port->active) { - port->active = 1; - + if (port->open_count == 1) { /* set up some stuff for our command port */ command_port = &port->serial->port[COMMAND_PORT]; if (command_port->private == NULL) { @@ -391,7 +389,7 @@ /* shutdown our bulk reads and writes */ usb_unlink_urb (port->write_urb); usb_unlink_urb (port->read_urb); - port->active = 0; + port->open_count = 0; } MOD_DEC_USE_COUNT; up (&port->sem); diff -urN linux-2.5.1-pre7/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c --- linux-2.5.1-pre7/drivers/usb/usb-ohci.c Fri Nov 9 13:41:42 2001 +++ linux/drivers/usb/usb-ohci.c Sat Dec 8 21:05:04 2001 @@ -485,7 +485,7 @@ /* implicitly requeued */ urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; if (urb_priv->state != URB_DEL) td_submit_urb (urb); break; @@ -502,7 +502,7 @@ urb->complete (urb); spin_lock_irqsave (&usb_ed_lock, flags); urb->actual_length = 0; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; urb->start_frame = urb_priv->ed->last_iso + 1; if (urb_priv->state != URB_DEL) { for (i = 0; i < urb->number_of_packets; i++) { @@ -673,7 +673,7 @@ urb->actual_length = 0; urb->hcpriv = urb_priv; - urb->status = USB_ST_URB_PENDING; + urb->status = -EINPROGRESS; /* link the ed into a chain if is not already */ if (ed->state != ED_OPER) @@ -737,7 +737,7 @@ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) return rh_unlink_urb (urb); - if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) { + if (urb->hcpriv && (urb->status == -EINPROGRESS)) { if (!ohci->disabled) { urb_priv_t * urb_priv; @@ -777,11 +777,11 @@ /* wait until all TDs are deleted */ set_current_state(TASK_UNINTERRUPTIBLE); - while (timeout && (urb->status == USB_ST_URB_PENDING)) + while (timeout && (urb->status == -EINPROGRESS)) timeout = schedule_timeout (timeout); set_current_state(TASK_RUNNING); remove_wait_queue (&unlink_wakeup, &wait); - if (urb->status == USB_ST_URB_PENDING) { + if (urb->status == -EINPROGRESS) { err ("unlink URB timeout"); return -ETIMEDOUT; } diff -urN linux-2.5.1-pre7/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h --- linux-2.5.1-pre7/drivers/usb/usb-ohci.h Wed Oct 24 08:26:12 2001 +++ linux/drivers/usb/usb-ohci.h Sat Dec 8 21:05:04 2001 @@ -11,22 +11,22 @@ static int cc_to_error[16] = { /* mapping of the OHCI CC status to error codes */ - /* No Error */ USB_ST_NOERROR, - /* CRC Error */ USB_ST_CRC, - /* Bit Stuff */ USB_ST_BITSTUFF, - /* Data Togg */ USB_ST_CRC, - /* Stall */ USB_ST_STALL, - /* DevNotResp */ USB_ST_NORESPONSE, - /* PIDCheck */ USB_ST_BITSTUFF, - /* UnExpPID */ USB_ST_BITSTUFF, - /* DataOver */ USB_ST_DATAOVERRUN, - /* DataUnder */ USB_ST_DATAUNDERRUN, - /* reservd */ USB_ST_NORESPONSE, - /* reservd */ USB_ST_NORESPONSE, - /* BufferOver */ USB_ST_BUFFEROVERRUN, - /* BuffUnder */ USB_ST_BUFFERUNDERRUN, - /* Not Access */ USB_ST_NORESPONSE, - /* Not Access */ USB_ST_NORESPONSE + /* No Error */ 0, + /* CRC Error */ -EILSEQ, + /* Bit Stuff */ -EPROTO, + /* Data Togg */ -EILSEQ, + /* Stall */ -EPIPE, + /* DevNotResp */ -ETIMEDOUT, + /* PIDCheck */ -EPROTO, + /* UnExpPID */ -EPROTO, + /* DataOver */ -EOVERFLOW, + /* DataUnder */ -EREMOTEIO, + /* reservd */ -ETIMEDOUT, + /* reservd */ -ETIMEDOUT, + /* BufferOver */ -ECOMM, + /* BuffUnder */ -ENOSR, + /* Not Access */ -ETIMEDOUT, + /* Not Access */ -ETIMEDOUT }; #include diff -urN linux-2.5.1-pre7/drivers/usb/usb.c linux/drivers/usb/usb.c --- linux-2.5.1-pre7/drivers/usb/usb.c Sat Dec 8 21:04:23 2001 +++ linux/drivers/usb/usb.c Sat Dec 8 21:05:04 2001 @@ -106,8 +106,8 @@ * Goes through all unclaimed USB interfaces, and offers them to all * registered USB drivers through the 'probe' function. * This will automatically be called after usb_register is called. - * It is called by some of the USB subsystems after one of their subdrivers - * are registered. + * It is called by some of the subsystems layered over USB + * after one of their subdrivers are registered. */ void usb_scan_devices(void) { @@ -292,7 +292,7 @@ * bustime is from calc_bus_time(), but converted to microseconds. * * returns if successful, - * or USB_ST_BANDWIDTH_ERROR if bandwidth request fails. + * or -ENOSPC if bandwidth request fails. * * FIXME: * This initial implementation does not use Endpoint.bInterval @@ -333,7 +333,7 @@ if (!usb_bandwidth_option) /* don't enforce it */ return (bustime); - return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : USB_ST_BANDWIDTH_ERROR; + return (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ? bustime : -ENOSPC; } void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) @@ -1121,7 +1121,10 @@ * any transfer flags. * * Successful submissions return 0; otherwise this routine returns a - * negative error number. + * negative error number. If the submission is successful, the complete + * fuction of the urb will be called when the USB host driver is + * finished with the urb (either a successful transmission, or some + * error case.) * * Unreserved Bandwidth Transfers: * @@ -1198,12 +1201,14 @@ return -ENODEV; } /*-------------------------------------------------------------------* - * COMPLETION HANDLERS * + * SYNCHRONOUS CALLS * *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * completion handler for compatibility wrappers (sync control/bulk) * - *-------------------------------------------------------------------*/ +struct usb_api_data { + wait_queue_head_t wqh; + int done; +}; + static void usb_api_blocking_completion(urb_t *urb) { struct usb_api_data *awd = (struct usb_api_data *)urb->context; @@ -1213,10 +1218,6 @@ wake_up(&awd->wqh); } -/*-------------------------------------------------------------------* - * SYNCHRONOUS CALLS * - *-------------------------------------------------------------------*/ - // Starts urb and waits for completion or timeout static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length) { @@ -1723,7 +1724,8 @@ return size; } -// usbcore-internal: enumeration/hub only!! +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally on disconnect/destroy path void usb_destroy_configuration(struct usb_device *dev) { int c, i, j, k; @@ -1955,18 +1957,14 @@ * These are the actual routines to send * and receive control messages. */ -#ifdef CONFIG_USB_LONG_TIMEOUT -#define GET_TIMEOUT 4 -#else -#define GET_TIMEOUT 3 -#endif -#define SET_TIMEOUT 3 -// hub driver only!!! for enumeration +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally, for usb_new_device() int usb_set_address(struct usb_device *dev) { return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, - 0, dev->devnum, 0, NULL, 0, HZ * GET_TIMEOUT); + // FIXME USB_CTRL_SET_TIMEOUT + 0, dev->devnum, 0, NULL, 0, HZ * USB_CTRL_GET_TIMEOUT); } /** @@ -1984,7 +1982,7 @@ * Configuration descriptors (USB_DT_CONFIG) are part of the device * structure, at least for the current configuration. * In addition to a number of USB-standard descriptors, some - * devices also use vendor-specific descriptors. + * devices also use class-specific or vendor-specific descriptors. * * This call is synchronous, and may not be used in an interrupt context. * @@ -1999,24 +1997,17 @@ memset(buf,0,size); // Make sure we parse really received data while (i--) { + /* retries if the returned length was 0; flakey device */ if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, HZ * GET_TIMEOUT)) > 0 || - result == -EPIPE) - break; /* retry if the returned length was 0; flaky device */ + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (type << 8) + index, 0, buf, size, + HZ * USB_CTRL_GET_TIMEOUT)) > 0 + || result == -EPIPE) + break; } return result; } -// FIXME Doesn't use USB_DT_CLASS ... but hid-core.c expects it this way -int usb_get_class_descriptor(struct usb_device *dev, int ifnum, - unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); -} - /** * usb_get_string - gets a string descriptor * @dev: the device whose string descriptor is being retrieved @@ -2042,7 +2033,8 @@ { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (USB_DT_STRING << 8) + index, langid, buf, size, HZ * GET_TIMEOUT); + (USB_DT_STRING << 8) + index, langid, buf, size, + HZ * USB_CTRL_GET_TIMEOUT); } /** @@ -2100,40 +2092,13 @@ int usb_get_status(struct usb_device *dev, int type, int target, void *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ * GET_TIMEOUT); + USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, + HZ * USB_CTRL_GET_TIMEOUT); } -// FIXME hid-specific !! DOES NOT BELONG HERE -int usb_get_protocol(struct usb_device *dev, int ifnum) -{ - unsigned char type; - int ret; - - if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - 0, ifnum, &type, 1, HZ * GET_TIMEOUT)) < 0) - return ret; - return type; -} - -// FIXME hid-specific !! DOES NOT BELONG HERE -int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - protocol, ifnum, NULL, 0, HZ * SET_TIMEOUT); -} - -// FIXME hid-specific !! DOES NOT BELONG HERE -int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (duration << 8) | report_id, ifnum, NULL, 0, HZ * SET_TIMEOUT); -} - -// hub-only!! +// hub-only!! ... and only exported for reset/reinit path. +// otherwise used internally, for config/altsetting reconfig. void usb_set_maxpacket(struct usb_device *dev) { int i, b; @@ -2197,7 +2162,8 @@ */ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, HZ * SET_TIMEOUT); + USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, + HZ * USB_CTRL_SET_TIMEOUT); /* don't clear if failed */ if (result < 0) @@ -2211,7 +2177,8 @@ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp, - buffer, sizeof(status), HZ * SET_TIMEOUT); + // FIXME USB_CTRL_GET_TIMEOUT, yes? why not usb_get_status() ? + buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT); memcpy(&status, buffer, sizeof(status)); kfree(buffer); @@ -2327,7 +2294,8 @@ } if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ * SET_TIMEOUT)) < 0) + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, + NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0) return ret; dev->actconfig = cp; @@ -2338,23 +2306,8 @@ return 0; } -// FIXME hid-specific !! DOES NOT BELONG HERE -int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, ifnum, buf, size, HZ * GET_TIMEOUT); -} - -// FIXME hid-specific !! DOES NOT BELONG HERE -int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size) -{ - return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, ifnum, buf, size, HZ); -} - -// hub driver only !! +// hub-only!! ... and only in reset path, or usb_new_device() +// (used by real hubs and virtual root hubs) int usb_get_configuration(struct usb_device *dev) { int result; @@ -2761,33 +2714,28 @@ EXPORT_SYMBOL(usb_claim_bandwidth); EXPORT_SYMBOL(usb_release_bandwidth); -EXPORT_SYMBOL(usb_set_address); -EXPORT_SYMBOL(usb_get_descriptor); -EXPORT_SYMBOL(usb_get_class_descriptor); EXPORT_SYMBOL(__usb_get_extra_descriptor); -EXPORT_SYMBOL(usb_get_device_descriptor); -EXPORT_SYMBOL(usb_get_string); -EXPORT_SYMBOL(usb_string); -EXPORT_SYMBOL(usb_get_protocol); -EXPORT_SYMBOL(usb_set_protocol); -EXPORT_SYMBOL(usb_get_report); -EXPORT_SYMBOL(usb_set_report); -EXPORT_SYMBOL(usb_set_idle); -EXPORT_SYMBOL(usb_clear_halt); -EXPORT_SYMBOL(usb_set_interface); -EXPORT_SYMBOL(usb_get_configuration); -EXPORT_SYMBOL(usb_set_configuration); -EXPORT_SYMBOL(usb_get_status); EXPORT_SYMBOL(usb_get_current_frame_number); +// asynchronous request completion model EXPORT_SYMBOL(usb_alloc_urb); EXPORT_SYMBOL(usb_free_urb); EXPORT_SYMBOL(usb_submit_urb); EXPORT_SYMBOL(usb_unlink_urb); +// synchronous request completion model EXPORT_SYMBOL(usb_control_msg); EXPORT_SYMBOL(usb_bulk_msg); +// synchronous control message convenience routines +EXPORT_SYMBOL(usb_get_descriptor); +EXPORT_SYMBOL(usb_get_device_descriptor); +EXPORT_SYMBOL(usb_get_status); +EXPORT_SYMBOL(usb_get_string); +EXPORT_SYMBOL(usb_string); +EXPORT_SYMBOL(usb_clear_halt); +EXPORT_SYMBOL(usb_set_configuration); +EXPORT_SYMBOL(usb_set_interface); EXPORT_SYMBOL(usb_devfs_handle); MODULE_LICENSE("GPL"); diff -urN linux-2.5.1-pre7/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c --- linux-2.5.1-pre7/drivers/usb/usbkbd.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/usbkbd.c Sat Dec 8 21:05:04 2001 @@ -35,6 +35,9 @@ #include #include +#define _HID_BOOT_PROTOCOL +#include "hid.h" + /* * Version Information */ @@ -192,8 +195,8 @@ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - usb_set_protocol(dev, interface->bInterfaceNumber, 0); - usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); + hid_set_protocol(dev, interface->bInterfaceNumber, 0); + hid_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; memset(kbd, 0, sizeof(struct usb_kbd)); @@ -216,7 +219,7 @@ usb_kbd_irq, kbd, endpoint->bInterval); kbd->dr.requesttype = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - kbd->dr.request = USB_REQ_SET_REPORT; + kbd->dr.request = HID_REQ_SET_REPORT; kbd->dr.value = 0x200; kbd->dr.index = interface->bInterfaceNumber; kbd->dr.length = 1; diff -urN linux-2.5.1-pre7/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c --- linux-2.5.1-pre7/drivers/usb/usbmouse.c Fri Sep 14 14:04:07 2001 +++ linux/drivers/usb/usbmouse.c Sat Dec 8 21:05:04 2001 @@ -35,6 +35,9 @@ #include #include +#define _HID_BOOT_PROTOCOL +#include "hid.h" + /* * Version Information */ @@ -118,7 +121,7 @@ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); - usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); + hid_set_idle(dev, interface->bInterfaceNumber, 0, 0); if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) return NULL; memset(mouse, 0, sizeof(struct usb_mouse)); diff -urN linux-2.5.1-pre7/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c --- linux-2.5.1-pre7/drivers/usb/usbnet.c Wed Nov 21 09:51:08 2001 +++ linux/drivers/usb/usbnet.c Sat Dec 8 21:05:04 2001 @@ -1535,7 +1535,7 @@ struct skb_data *entry = (struct skb_data *) skb->cb; struct usbnet *dev = entry->dev; - if (urb->status == USB_ST_STALL) { + if (urb->status == -EPIPE) { if (dev->ctrl_task.sync == 0) { dev->ctrl_task.routine = tx_clear_halt; dev->ctrl_task.data = dev; @@ -1868,6 +1868,11 @@ #ifdef CONFIG_USB_AN2720 { USB_DEVICE (0x0547, 0x2720), // AnchorChips defaults + driver_info: (unsigned long) &an2720_info, +}, + +{ + USB_DEVICE (0x0547, 0x2727), // Xircom PGUNET driver_info: (unsigned long) &an2720_info, }, #endif diff -urN linux-2.5.1-pre7/drivers/usb/uss720.c linux/drivers/usb/uss720.c --- linux-2.5.1-pre7/drivers/usb/uss720.c Sat Oct 20 19:13:11 2001 +++ linux/drivers/usb/uss720.c Sat Dec 8 21:05:04 2001 @@ -193,7 +193,7 @@ struct parport *pp = (struct parport *)dev_id; struct parport_uss720_private *priv = pp->private_data; - if (usbstatus != USB_ST_NOERROR || len < 4 || !buffer) + if (usbstatus != 0 || len < 4 || !buffer) return 1; memcpy(priv->reg, buffer, 4); /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */ diff -urN linux-2.5.1-pre7/fs/bio.c linux/fs/bio.c --- linux-2.5.1-pre7/fs/bio.c Sat Dec 8 21:04:23 2001 +++ linux/fs/bio.c Sat Dec 8 21:05:04 2001 @@ -47,7 +47,6 @@ struct biovec_pool { int bp_size; kmem_cache_t *bp_cachep; - wait_queue_head_t bp_wait; }; static struct biovec_pool bvec_list[BIOVEC_NR_POOLS]; @@ -161,32 +160,22 @@ if ((bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask))) goto out_gotit; - /* - * we need slab reservations for this to be completely - * deadlock free... - */ - if (BIO_CAN_WAIT(gfp_mask)) { - DECLARE_WAITQUEUE(wait, current); + if (!BIO_CAN_WAIT(gfp_mask)) + return NULL; - add_wait_queue_exclusive(&bp->bp_wait, &wait); - for (;;) { - set_current_state(TASK_UNINTERRUPTIBLE); - bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask); - if (bvl) - goto out_gotit; + do { + bvl = kmem_cache_alloc(bp->bp_cachep, gfp_mask); + if (bvl) + break; - run_task_queue(&tq_disk); - schedule(); - } - remove_wait_queue(&bp->bp_wait, &wait); + run_task_queue(&tq_disk); __set_current_state(TASK_RUNNING); - } + current->policy |= SCHED_YIELD; + schedule(); + } while (1); - if (bvl) { out_gotit: - memset(bvl, 0, bp->bp_size); - } - + memset(bvl, 0, bp->bp_size); return bvl; } @@ -202,10 +191,8 @@ /* * cloned bio doesn't own the veclist */ - if (!(bio->bi_flags & (1 << BIO_CLONED))) { + if (!(bio->bi_flags & (1 << BIO_CLONED))) kmem_cache_free(bp->bp_cachep, bio->bi_io_vec); - wake_up_nr(&bp->bp_wait, 1); - } bio_pool_put(bio); } @@ -326,31 +313,46 @@ } /** - * bio_clone - duplicate a bio - * @bio: bio to clone - * @gfp_mask: allocation priority + * __bio_clone - clone a bio + * @bio: destination bio + * @bio_src: bio to clone * - * Duplicate a &bio. Caller will own the returned bio, but not + * Clone a &bio. Caller will own the returned bio, but not * the actual data it points to. Reference count of returned * bio will be one. */ -struct bio *bio_clone(struct bio *bio, int gfp_mask) +inline void __bio_clone(struct bio *bio, struct bio *bio_src) { - struct bio *b = bio_alloc(gfp_mask, 0); + bio->bi_io_vec = bio_src->bi_io_vec; - if (b) { - b->bi_io_vec = bio->bi_io_vec; + bio->bi_sector = bio_src->bi_sector; + bio->bi_dev = bio_src->bi_dev; + bio->bi_flags |= 1 << BIO_CLONED; + bio->bi_rw = bio_src->bi_rw; - b->bi_sector = bio->bi_sector; - b->bi_dev = bio->bi_dev; - b->bi_flags |= 1 << BIO_CLONED; - b->bi_rw = bio->bi_rw; + /* + * notes -- maybe just leave bi_idx alone. bi_max has no used + * on a cloned bio + */ + bio->bi_vcnt = bio_src->bi_vcnt; + bio->bi_idx = bio_src->bi_idx; + bio->bi_size = bio_src->bi_size; + bio->bi_max = bio_src->bi_max; +} - b->bi_vcnt = bio->bi_vcnt; - b->bi_idx = bio->bi_idx; - b->bi_size = bio->bi_size; - b->bi_max = bio->bi_max; - } +/** + * bio_clone - clone a bio + * @bio: bio to clone + * @gfp_mask: allocation priority + * + * Like __bio_clone, only also allocates the returned bio + */ +struct bio *bio_clone(struct bio *bio, int gfp_mask) +{ + struct bio *b = bio_alloc(gfp_mask, 0); + + if (b) + __bio_clone(b, bio); return b; } @@ -667,7 +669,6 @@ panic("biovec: can't init slab pools\n"); bp->bp_size = size; - init_waitqueue_head(&bp->bp_wait); } } @@ -696,4 +697,5 @@ EXPORT_SYMBOL(bio_endio); EXPORT_SYMBOL(bio_init); EXPORT_SYMBOL(bio_copy); +EXPORT_SYMBOL(__bio_clone); EXPORT_SYMBOL(bio_clone); diff -urN linux-2.5.1-pre7/include/asm-alpha/page.h linux/include/asm-alpha/page.h --- linux-2.5.1-pre7/include/asm-alpha/page.h Sat Dec 8 21:04:23 2001 +++ linux/include/asm-alpha/page.h Sat Dec 8 21:05:04 2001 @@ -67,18 +67,6 @@ #define PAGE_BUG(page) BUG() -#define BUG_ON(condition) \ - do { \ - if (unlikely((long)(condition)))\ - BUG(); \ - } while (0) - -#define BUG_ON(condition) \ - do { \ - if (unlikely((int)(condition))) \ - BUG(); \ - } while (0) - /* Pure 2^n version of get_order */ extern __inline__ int get_order(unsigned long size) { diff -urN linux-2.5.1-pre7/include/asm-i386/page.h linux/include/asm-i386/page.h --- linux-2.5.1-pre7/include/asm-i386/page.h Sat Dec 8 21:04:23 2001 +++ linux/include/asm-i386/page.h Thu Nov 22 11:46:18 2001 @@ -101,12 +101,6 @@ BUG(); \ } while (0) -#define BUG_ON(condition) \ - do { \ - if (unlikely((int)(condition))) \ - BUG(); \ - } while (0) - /* Pure 2^n version of get_order */ static __inline__ int get_order(unsigned long size) { diff -urN linux-2.5.1-pre7/include/linux/bio.h linux/include/linux/bio.h --- linux-2.5.1-pre7/include/linux/bio.h Sat Dec 8 21:04:23 2001 +++ linux/include/linux/bio.h Sat Dec 8 21:05:04 2001 @@ -168,6 +168,7 @@ extern int bio_endio(struct bio *, int, int); +extern inline void __bio_clone(struct bio *, struct bio *); extern struct bio *bio_clone(struct bio *, int); extern struct bio *bio_copy(struct bio *, int, int); diff -urN linux-2.5.1-pre7/include/linux/blk.h linux/include/linux/blk.h --- linux-2.5.1-pre7/include/linux/blk.h Sat Dec 8 21:04:23 2001 +++ linux/include/linux/blk.h Sat Dec 8 21:05:04 2001 @@ -77,12 +77,21 @@ return rq; } -extern inline void elv_add_request(request_queue_t *q, struct request *rq) -{ - blk_plug_device(q); - q->elevator.elevator_add_req_fn(q, rq, q->queue_head.prev); -} +#define __elv_add_request_core(q, rq, where, plug) \ + do { \ + if ((plug)) \ + blk_plug_device((q)); \ + (q)->elevator.elevator_add_req_fn((q), (rq), (where)); \ + } while (0) +#define __elv_add_request(q, rq, back, p) \ + if ((back)) \ + __elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \ + else \ + __elv_add_request_core((q), (rq), &(q)->queue_head, 0); \ + +#define elv_add_request(q, rq, back) __elv_add_request((q), (rq), (back), 1) + #if defined(MAJOR_NR) || defined(IDE_DRIVER) #undef DEVICE_ON diff -urN linux-2.5.1-pre7/include/linux/kernel.h linux/include/linux/kernel.h --- linux-2.5.1-pre7/include/linux/kernel.h Thu Nov 22 11:46:18 2001 +++ linux/include/linux/kernel.h Sat Dec 8 21:05:04 2001 @@ -11,6 +11,7 @@ #include #include #include +#include /* Optimization barrier */ /* The "volatile" is due to gcc bugs */ @@ -176,4 +177,5 @@ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) #endif diff -urN linux-2.5.1-pre7/include/linux/usb.h linux/include/linux/usb.h --- linux-2.5.1-pre7/include/linux/usb.h Sat Dec 8 21:04:23 2001 +++ linux/include/linux/usb.h Sat Dec 8 21:05:04 2001 @@ -11,10 +11,13 @@ #define USB_CLASS_COMM 2 #define USB_CLASS_HID 3 #define USB_CLASS_PHYSICAL 5 +#define USB_CLASS_STILL_IMAGE 6 #define USB_CLASS_PRINTER 7 #define USB_CLASS_MASS_STORAGE 8 #define USB_CLASS_HUB 9 -#define USB_CLASS_DATA 10 +#define USB_CLASS_CDC_DATA 0x0a +#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ +#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ #define USB_CLASS_APP_SPEC 0xfe #define USB_CLASS_VENDOR_SPEC 0xff @@ -43,31 +46,6 @@ #define USB_DIR_IN 0x80 /* - * Descriptor types - */ -#define USB_DT_DEVICE 0x01 -#define USB_DT_CONFIG 0x02 -#define USB_DT_STRING 0x03 -#define USB_DT_INTERFACE 0x04 -#define USB_DT_ENDPOINT 0x05 - -#define USB_DT_HID (USB_TYPE_CLASS | 0x01) -#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) -#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) -#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) - -/* - * Descriptor sizes per descriptor type - */ -#define USB_DT_DEVICE_SIZE 18 -#define USB_DT_CONFIG_SIZE 9 -#define USB_DT_INTERFACE_SIZE 9 -#define USB_DT_ENDPOINT_SIZE 7 -#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ -#define USB_DT_HUB_NONVAR_SIZE 7 -#define USB_DT_HID_SIZE 9 - -/* * Endpoints */ #define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ @@ -115,16 +93,6 @@ #define USB_REQ_SET_INTERFACE 0x0B #define USB_REQ_SYNCH_FRAME 0x0C -/* - * HID requests - */ -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_GET_IDLE 0x02 -#define USB_REQ_GET_PROTOCOL 0x03 -#define USB_REQ_SET_REPORT 0x09 -#define USB_REQ_SET_IDLE 0x0A -#define USB_REQ_SET_PROTOCOL 0x0B - #ifdef __KERNEL__ @@ -158,32 +126,6 @@ } devrequest __attribute__ ((packed)); /* - * USB-status codes: - * USB_ST* maps to -E* and should go away in the future - */ - -#define USB_ST_NOERROR 0 -#define USB_ST_CRC (-EILSEQ) -#define USB_ST_BITSTUFF (-EPROTO) -#define USB_ST_NORESPONSE (-ETIMEDOUT) /* device not responding/handshaking */ -#define USB_ST_DATAOVERRUN (-EOVERFLOW) -#define USB_ST_DATAUNDERRUN (-EREMOTEIO) -#define USB_ST_BUFFEROVERRUN (-ECOMM) -#define USB_ST_BUFFERUNDERRUN (-ENOSR) -#define USB_ST_INTERNALERROR (-EPROTO) /* unknown error */ -#define USB_ST_SHORT_PACKET (-EREMOTEIO) -#define USB_ST_PARTIAL_ERROR (-EXDEV) /* ISO transfer only partially completed */ -#define USB_ST_URB_KILLED (-ENOENT) /* URB canceled by user */ -#define USB_ST_URB_PENDING (-EINPROGRESS) -#define USB_ST_REMOVED (-ENODEV) /* device not existing or removed */ -#define USB_ST_TIMEOUT (-ETIMEDOUT) /* communication timed out, also in urb->status**/ -#define USB_ST_NOTSUPPORTED (-ENOSYS) -#define USB_ST_BANDWIDTH_ERROR (-ENOSPC) /* too much bandwidth used */ -#define USB_ST_URB_INVALID_ERROR (-EINVAL) /* invalid value/transfer type */ -#define USB_ST_URB_REQUEST_ERROR (-ENXIO) /* invalid endpoint */ -#define USB_ST_STALL (-EPIPE) /* pipe stalled, also in urb->status*/ - -/* * USB device number allocation bitmap. There's one bitmap * per USB tree. */ @@ -197,18 +139,46 @@ unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))]; }; +struct usb_device; + +/*-------------------------------------------------------------------------*/ + /* - * This is a USB device descriptor. - * - * USB device information + * Standard USB Descriptor support. + * Devices may also have class-specific or vendor-specific descriptors. */ -/* Everything but the endpoint maximums are aribtrary */ +/* + * Descriptor types ... USB 2.0 spec table 9.5 + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE_QUALIFIER 0x06 +#define USB_DT_OTHER_SPEED_CONFIG 0x07 +#define USB_DT_INTERFACE_POWER 0x08 + +// FIXME should be internal to hub driver +#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) +#define USB_DT_HUB_NONVAR_SIZE 7 + +/* + * Descriptor sizes per descriptor type + */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ + +/* most of these maximums are arbitrary */ #define USB_MAXCONFIG 8 #define USB_ALTSETTINGALLOC 4 #define USB_MAXALTSETTING 128 /* Hard limit */ #define USB_MAXINTERFACES 32 -#define USB_MAXENDPOINTS 32 +#define USB_MAXENDPOINTS 32 /* Hard limit */ /* All standard descriptors have these 2 fields in common */ struct usb_descriptor_header { @@ -216,7 +186,7 @@ __u8 bDescriptorType; } __attribute__ ((packed)); -/* Device descriptor */ +/* USB_DT_DEVICE: Device descriptor */ struct usb_device_descriptor { __u8 bLength; __u8 bDescriptorType; @@ -234,7 +204,7 @@ __u8 bNumConfigurations; } __attribute__ ((packed)); -/* Endpoint descriptor */ +/* USB_DT_ENDPOINT: Endpoint descriptor */ struct usb_endpoint_descriptor { __u8 bLength __attribute__ ((packed)); __u8 bDescriptorType __attribute__ ((packed)); @@ -245,11 +215,12 @@ __u8 bRefresh __attribute__ ((packed)); __u8 bSynchAddress __attribute__ ((packed)); + /* the rest is internal to the Linux implementation */ unsigned char *extra; /* Extra descriptors */ int extralen; }; -/* Interface descriptor */ +/* USB_DT_INTERFACE: Interface descriptor */ struct usb_interface_descriptor { __u8 bLength __attribute__ ((packed)); __u8 bDescriptorType __attribute__ ((packed)); @@ -261,6 +232,7 @@ __u8 bInterfaceProtocol __attribute__ ((packed)); __u8 iInterface __attribute__ ((packed)); + /* the rest is internal to the Linux implementation */ struct usb_endpoint_descriptor *endpoint; unsigned char *extra; /* Extra descriptors */ @@ -278,7 +250,13 @@ void *private_data; }; -/* Configuration descriptor information.. */ +/* USB_DT_CONFIG: Configuration descriptor information. + * + * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the + * descriptor type is different. Highspeed-capable devices can look + * different depending on what speed they're currently running. Only + * devices with a USB_DT_DEVICE_QUALIFIER have an OTHER_SPEED_CONFIG. + */ struct usb_config_descriptor { __u8 bLength __attribute__ ((packed)); __u8 bDescriptorType __attribute__ ((packed)); @@ -289,20 +267,46 @@ __u8 bmAttributes __attribute__ ((packed)); __u8 MaxPower __attribute__ ((packed)); + /* the rest is internal to the Linux implementation */ struct usb_interface *interface; unsigned char *extra; /* Extra descriptors */ int extralen; }; -/* String descriptor */ +/* USB_DT_STRING: String descriptor */ struct usb_string_descriptor { __u8 bLength; __u8 bDescriptorType; - __u16 wData[1]; + __u16 wData[1]; /* UTF-16LE encoded */ } __attribute__ ((packed)); -struct usb_device; +/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ +struct usb_qualifier_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u16 bcdUSB; + __u8 bDeviceClass; + __u8 bDeviceSubClass; + __u8 bDeviceProtocol; + __u8 bMaxPacketSize0; + __u8 bNumConfigurations; + __u8 bRESERVED; +} __attribute__ ((packed)); + +/* helpers for driver access to descriptors */ +extern struct usb_interface * + usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); +extern struct usb_endpoint_descriptor * + usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum); + +int __usb_get_extra_descriptor(char *buffer, unsigned size, + unsigned char type, void **ptr); +#define usb_get_extra_descriptor(ifpoint,type,ptr)\ + __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,\ + type,(void**)ptr) + +/*-------------------------------------------------------------------------*/ /* * Device table entry for "new style" table-driven USB drivers. @@ -316,34 +320,6 @@ * Terminate the driver's table with an all-zeroes entry. * Use the flag values to control which fields are compared. */ -#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 -#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 -#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 -#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 -#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 -#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 -#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 -#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 -#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 -#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 - -#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) -#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) -#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) -#define USB_DEVICE_ID_MATCH_DEV_INFO \ - (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL) -#define USB_DEVICE_ID_MATCH_INT_INFO \ - (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL) - -/* Some useful macros */ -#define USB_DEVICE(vend,prod) \ - match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod) -#define USB_DEVICE_VER(vend,prod,lo,hi) \ - match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi) -#define USB_DEVICE_INFO(cl,sc,pr) \ - match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr) -#define USB_INTERFACE_INFO(cl,sc,pr) \ - match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr) /** * struct usb_device_id - identifies USB devices for probing and hotplugging @@ -377,7 +353,7 @@ * device flags. * * In most cases, drivers will create a table of device IDs by using - * the USB_DEVICE() macros designed for that purpose. + * USB_DEVICE(), or similar macros designed for that purpose. * They will then export it to userspace using MODULE_DEVICE_TABLE(), * and provide it to the USB core through their usb_driver structure. * @@ -413,6 +389,75 @@ unsigned long driver_info; }; +/* Some useful macros to use to create struct usb_device_id */ +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 + +#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) +#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) +#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) +#define USB_DEVICE_ID_MATCH_DEV_INFO \ + (USB_DEVICE_ID_MATCH_DEV_CLASS | USB_DEVICE_ID_MATCH_DEV_SUBCLASS | USB_DEVICE_ID_MATCH_DEV_PROTOCOL) +#define USB_DEVICE_ID_MATCH_INT_INFO \ + (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL) + +/** + * USB_DEVICE - macro used to describe a specific usb device + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * + * This macro is used to create a struct usb_device_id that matches a + * specific device. + */ +#define USB_DEVICE(vend,prod) \ + match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor: (vend), idProduct: (prod) +/** + * USB_DEVICE_VER - macro used to describe a specific usb device with a version range + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @lo: the bcdDevice_lo value + * @hi: the bcdDevice_hi value + * + * This macro is used to create a struct usb_device_id that matches a + * specific device, with a version range. + */ +#define USB_DEVICE_VER(vend,prod,lo,hi) \ + match_flags: USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, idVendor: (vend), idProduct: (prod), bcdDevice_lo: (lo), bcdDevice_hi: (hi) + +/** + * USB_DEVICE_INFO - macro used to describe a class of usb devices + * @cl: bDeviceClass value + * @sc: bDeviceSubClass value + * @pr: bDeviceProtocol value + * + * This macro is used to create a struct usb_device_id that matches a + * specific class of devices. + */ +#define USB_DEVICE_INFO(cl,sc,pr) \ + match_flags: USB_DEVICE_ID_MATCH_DEV_INFO, bDeviceClass: (cl), bDeviceSubClass: (sc), bDeviceProtocol: (pr) + +/** + * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces + * @cl: bInterfaceClass value + * @sc: bInterfaceSubClass value + * @pr: bInterfaceProtocol value + * + * This macro is used to create a struct usb_device_id that matches a + * specific class of interfaces. + */ +#define USB_INTERFACE_INFO(cl,sc,pr) \ + match_flags: USB_DEVICE_ID_MATCH_INT_INFO, bInterfaceClass: (cl), bInterfaceSubClass: (sc), bInterfaceProtocol: (pr) + +/* -------------------------------------------------------------------------- */ + /** * struct usb_driver - identifies USB driver to usbcore * @name: The driver name should be unique among USB drivers @@ -439,6 +484,8 @@ * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. * @id_table: USB drivers use ID table to support hotplugging. + * Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to + * say that probe() should be called for any unclaimed interfce. * * USB drivers should provide a name, probe() and disconnect() methods, * and an id_table. Other driver fields are optional. @@ -482,13 +529,22 @@ /* suspend before the bus suspends; * disconnect or resume when the bus resumes */ - // void (*suspend)(struct usb_device *dev); - // void (*resume)(struct usb_device *dev); + /* void (*suspend)(struct usb_device *dev); */ + /* void (*resume)(struct usb_device *dev); */ }; - -/*----------------------------------------------------------------------------* - * New USB Structures * - *----------------------------------------------------------------------------*/ + +/* + * use these in module_init()/module_exit() + * and don't forget MODULE_DEVICE_TABLE(usb, ...) + */ +extern int usb_register(struct usb_driver *); +extern void usb_deregister(struct usb_driver *); + +/* -------------------------------------------------------------------------- */ + +/* + * URB support, for asynchronous request completions + */ /* * urb->transfer_flags: @@ -500,18 +556,21 @@ #define USB_ASYNC_UNLINK 0x0008 #define USB_QUEUE_BULK 0x0010 #define USB_NO_FSBR 0x0020 -#define USB_ZERO_PACKET 0x0040 // Finish bulk OUTs always with zero length packet -#define USB_TIMEOUT_KILLED 0x1000 // only set by HCD! +#define USB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ +#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ + /* ... less overhead for QUEUE_BULK */ +#define USB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */ typedef struct { unsigned int offset; - unsigned int length; // expected length + unsigned int length; /* expected length */ unsigned int actual_length; unsigned int status; } iso_packet_descriptor_t, *piso_packet_descriptor_t; struct urb; + typedef void (*usb_complete_t)(struct urb *); /** @@ -601,6 +660,8 @@ * to poll for transfers. After the URB has been submitted, the interval * and start_frame fields reflect how the transfer was actually scheduled. * The polling interval may be more frequent than requested. + * For example, some controllers have a maximum interval of 32 microseconds, + * while others support intervals of up to 1024 microseconds. * * Isochronous URBs normally use the USB_ISO_ASAP transfer flag, telling * the host controller to schedule the transfer as soon as bandwidth @@ -634,7 +695,7 @@ * When completion callback is invoked for non-isochronous URBs, the * actual_length field tells how many bytes were transferred. * - * For interrupt and isochronous URBs, the URB provided to the calllback + * For interrupt and isochronous URBs, the URB provided to the callback * function is still "owned" by the USB core subsystem unless the status * indicates that the URB has been unlinked. Completion handlers should * not modify such URBs until they have been unlinked. @@ -681,8 +742,9 @@ * @COMPLETE: pointer to the usb_complete_t function * @CONTEXT: what to set the urb context to. * - * Initializes a control urb with the proper information needed to submit it to - * a device. + * Initializes a control urb with the proper information needed to submit + * it to a device. This macro is depreciated, the usb_fill_control_urb() + * function should be used instead. */ #define FILL_CONTROL_URB(URB,DEV,PIPE,SETUP_PACKET,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ do {\ @@ -706,8 +768,9 @@ * @COMPLETE: pointer to the usb_complete_t function * @CONTEXT: what to set the urb context to. * - * Initializes a bulk urb with the proper information needed to submit it to - * a device. + * Initializes a bulk urb with the proper information needed to submit it + * to a device. This macro is depreciated, the usb_fill_bulk_urb() + * function should be used instead. */ #define FILL_BULK_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT) \ do {\ @@ -731,8 +794,9 @@ * @CONTEXT: what to set the urb context to. * @INTERVAL: what to set the urb interval to. * - * Initializes a interrupt urb with the proper information needed to submit it to - * a device. + * Initializes a interrupt urb with the proper information needed to submit + * it to a device. This macro is depreciated, the usb_fill_int_urb() + * function should be used instead. */ #define FILL_INT_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) \ do {\ @@ -747,51 +811,150 @@ (URB)->start_frame=-1;\ } while (0) -#define FILL_CONTROL_URB_TO(a,aa,b,c,d,e,f,g,h) \ - do {\ - spin_lock_init(&(a)->lock);\ - (a)->dev=aa;\ - (a)->pipe=b;\ - (a)->setup_packet=c;\ - (a)->transfer_buffer=d;\ - (a)->transfer_buffer_length=e;\ - (a)->complete=f;\ - (a)->context=g;\ - (a)->timeout=h;\ - } while (0) +/** + * usb_fill_control_urb - initializes a control urb + * @urb: pointer to the urb to initialize. + * @dev: pointer to the struct usb_device for this urb. + * @pipe: the endpoint pipe + * @setup_packet: pointer to the setup_packet buffer + * @transfer_buffer: pointer to the transfer buffer + * @buffer_length: length of the transfer buffer + * @complete: pointer to the usb_complete_t function + * @context: what to set the urb context to. + * + * Initializes a control urb with the proper information needed to submit + * it to a device. + */ +static inline void usb_fill_control_urb (struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + unsigned char *setup_packet, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete, + void *context) +{ + spin_lock_init(&urb->lock); + urb->dev = dev; + urb->pipe = pipe; + urb->setup_packet = setup_packet; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = buffer_length; + urb->complete = complete; + urb->context = context; +} -#define FILL_BULK_URB_TO(a,aa,b,c,d,e,f,g) \ - do {\ - spin_lock_init(&(a)->lock);\ - (a)->dev=aa;\ - (a)->pipe=b;\ - (a)->transfer_buffer=c;\ - (a)->transfer_buffer_length=d;\ - (a)->complete=e;\ - (a)->context=f;\ - (a)->timeout=g;\ - } while (0) +/** + * usb_fill_bulk_urb - macro to help initialize a bulk urb + * @urb: pointer to the urb to initialize. + * @dev: pointer to the struct usb_device for this urb. + * @pipe: the endpoint pipe + * @transfer_buffer: pointer to the transfer buffer + * @buffer_length: length of the transfer buffer + * @complete: pointer to the usb_complete_t function + * @context: what to set the urb context to. + * + * Initializes a bulk urb with the proper information needed to submit it + * to a device. + */ +static inline void usb_fill_bulk_urb (struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete, + void *context) + +{ + spin_lock_init(&urb->lock); + urb->dev = dev; + urb->pipe = pipe; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = buffer_length; + urb->complete = complete; + urb->context = context; +} -purb_t usb_alloc_urb(int iso_packets); -void usb_free_urb (purb_t purb); -int usb_submit_urb(purb_t purb); -int usb_unlink_urb(purb_t purb); -int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len, int timeout); -int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); +/** + * usb_fill_int_urb - macro to help initialize a interrupt urb + * @urb: pointer to the urb to initialize. + * @dev: pointer to the struct usb_device for this urb. + * @pipe: the endpoint pipe + * @transfer_buffer: pointer to the transfer buffer + * @buffer_length: length of the transfer buffer + * @complete: pointer to the usb_complete_t function + * @context: what to set the urb context to. + * @interval: what to set the urb interval to. + * + * Initializes a interrupt urb with the proper information needed to submit + * it to a device. + */ +static inline void usb_fill_int_urb (struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete, + void *context, + int interval) +{ + spin_lock_init(&urb->lock); + urb->dev = dev; + urb->pipe = pipe; + urb->transfer_buffer = transfer_buffer; + urb->transfer_buffer_length = buffer_length; + urb->complete = complete; + urb->context = context; + urb->interval = interval; + urb->start_frame = -1; +} + +extern struct urb *usb_alloc_urb(int iso_packets); +extern void usb_free_urb(struct urb *purb); +extern int usb_submit_urb(struct urb *purb); +extern int usb_unlink_urb(struct urb *purb); /*-------------------------------------------------------------------* * SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ -struct usb_api_data -{ - wait_queue_head_t wqh; - int done; - /* void* stuff; */ /* Possible extension later. */ -}; +extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, + __u8 request, __u8 requesttype, __u16 value, __u16 index, + void *data, __u16 size, int timeout); +extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, + int timeout); + +/* wrappers around usb_control_msg() for the most common standard requests */ +extern int usb_clear_halt(struct usb_device *dev, int pipe); +extern int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, + unsigned char descindex, void *buf, int size); +extern int usb_get_device_descriptor(struct usb_device *dev); +extern int usb_get_status(struct usb_device *dev, + int type, int target, void *data); +extern int usb_get_string(struct usb_device *dev, + unsigned short langid, unsigned char index, void *buf, int size); +extern int usb_string(struct usb_device *dev, int index, + char *buf, size_t size); +extern int usb_set_configuration(struct usb_device *dev, int configuration); +extern int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); + +/* + * timeouts, in seconds, used for sending/receiving control messages + * they typically complete within a few frames (msec) after they're issued + */ +#ifdef CONFIG_USB_LONG_TIMEOUT +#define USB_CTRL_GET_TIMEOUT 4 +#else +#define USB_CTRL_GET_TIMEOUT 3 +#endif + +#define USB_CTRL_SET_TIMEOUT 3 /* -------------------------------------------------------------------------- */ +/* Host Controller Driver (HCD) support */ + struct usb_operations { int (*allocate)(struct usb_device *); int (*deallocate)(struct usb_device *); @@ -832,6 +995,60 @@ atomic_t refcnt; }; +extern struct usb_bus *usb_alloc_bus(struct usb_operations *); +extern void usb_free_bus(struct usb_bus *); +extern void usb_register_bus(struct usb_bus *); +extern void usb_deregister_bus(struct usb_bus *); + +extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); +extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, + int bustime, int isoc); +extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, + int isoc); +extern int usb_root_hub_string(int id, int serial, + char *type, __u8 *data, int len); + +/* + * Some USB 1.1 bandwidth allocation constants. + */ +#define BW_HOST_DELAY 1000L /* nanoseconds */ +#define BW_HUB_LS_SETUP 333L /* nanoseconds */ + /* 4 full-speed bit times (est.) */ + +#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */ +#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) +#define FRAME_TIME_USECS 1000L +#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) + +#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */ + /* Trying not to use worst-case bit-stuffing + of (7/6 * 8 * bytecount) = 9.33 * bytecount */ + /* bytecount = data payload byte count */ + +#define NS_TO_US(ns) ((ns + 500L) / 1000L) + /* convert & round nanoseconds to microseconds */ + + +/* -------------------------------------------------------------------------- */ + +/* Enumeration is only for the hub driver, or HCD virtual root hubs */ +extern struct usb_device *usb_alloc_dev(struct usb_device *parent, + struct usb_bus *); +extern void usb_free_dev(struct usb_device *); +extern int usb_new_device(struct usb_device *dev); +extern void usb_connect(struct usb_device *dev); +extern void usb_disconnect(struct usb_device **); + +#ifndef _LINUX_HUB_H +/* exported to hub driver ONLY to support usb_reset_device () */ +extern int usb_get_configuration(struct usb_device *dev); +extern void usb_set_maxpacket(struct usb_device *dev); +extern void usb_destroy_configuration(struct usb_device *dev); +extern int usb_set_address(struct usb_device *dev); +#endif /* _LINUX_HUB_H */ + +/* -------------------------------------------------------------------------- */ + /* This is arbitrary. * From USB 2.0 spec Table 11-13, offset 7, a hub can * have up to 255 ports. The most yet reported is 10. @@ -889,44 +1106,30 @@ struct usb_device *children[USB_MAXCHILDREN]; }; -extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum); -extern struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum); - -extern int usb_register(struct usb_driver *); -extern void usb_deregister(struct usb_driver *); +/* for when layers above USB add new non-USB drivers */ extern void usb_scan_devices(void); -/* used these for multi-interface device registration */ -extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv); -extern int usb_interface_claimed(struct usb_interface *iface); -extern void usb_driver_release_interface(struct usb_driver *driver, struct usb_interface *iface); -const struct usb_device_id *usb_match_id(struct usb_device *dev, - struct usb_interface *interface, - const struct usb_device_id *id); +/* mostly for devices emulating SCSI over USB */ +extern int usb_reset_device(struct usb_device *dev); -extern struct usb_bus *usb_alloc_bus(struct usb_operations *); -extern void usb_free_bus(struct usb_bus *); -extern void usb_register_bus(struct usb_bus *); -extern void usb_deregister_bus(struct usb_bus *); +/* for drivers using iso endpoints */ +extern int usb_get_current_frame_number (struct usb_device *usb_dev); -extern struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *); -extern void usb_free_dev(struct usb_device *); +/* drivers must track when they bind to a device's interfaces */ extern void usb_inc_dev_use(struct usb_device *); #define usb_dec_dev_use usb_free_dev -extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); -extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc); -extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb, int isoc); - -extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout); - -extern int usb_root_hub_string(int id, int serial, char *type, __u8 *data, int len); -extern void usb_connect(struct usb_device *dev); -extern void usb_disconnect(struct usb_device **); - -extern void usb_destroy_configuration(struct usb_device *dev); +/* used these for multi-interface device registration */ +extern void usb_driver_claim_interface(struct usb_driver *driver, + struct usb_interface *iface, void* priv); +extern int usb_interface_claimed(struct usb_interface *iface); +extern void usb_driver_release_interface(struct usb_driver *driver, + struct usb_interface *iface); +const struct usb_device_id *usb_match_id(struct usb_device *dev, + struct usb_interface *interface, + const struct usb_device_id *id); -int usb_get_current_frame_number (struct usb_device *usb_dev); +/* -------------------------------------------------------------------------- */ /* * Calling this entity a "pipe" is glorifying it. A USB pipe @@ -934,7 +1137,7 @@ * of the following information: * - device number (7 bits) * - endpoint number (4 bits) - * - current Data0/1 state (1 bit) + * - current Data0/1 state (1 bit) [Historical; now gone] * - direction (1 bit) * - speed (1 bit) * - max packet size (2 bits: 8, 16, 32 or 64) [Historical; now gone.] @@ -951,7 +1154,7 @@ * - direction: bit 7 (0 = Host-to-Device [Out], 1 = Device-to-Host [In]) * - device: bits 8-14 * - endpoint: bits 15-18 - * - Data0/1: bit 19 + * - Data0/1: bit 19 [Historical; now gone. ] * - speed: bit 26 (0 = Full, 1 = Low Speed) * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk) * @@ -964,6 +1167,8 @@ * like full speed devices. */ +// FIXME 2.5 get rid of usb_pipeslow(), just use dev->speed + #define PIPE_ISOCHRONOUS 0 #define PIPE_INTERRUPT 1 #define PIPE_CONTROL 2 @@ -979,7 +1184,6 @@ #define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f) #define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff) #define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf) -#define usb_pipedata(pipe) (((pipe) >> 19) & 1) #define usb_pipeslow(pipe) (((pipe) >> 26) & 1) #define usb_pipetype(pipe) (((pipe) >> 30) & 3) #define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) @@ -1023,58 +1227,10 @@ #define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev)) #define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | __default_pipe(dev) | USB_DIR_IN) -/* - * Send and receive control messages.. - */ -int usb_new_device(struct usb_device *dev); -int usb_reset_device(struct usb_device *dev); -int usb_set_address(struct usb_device *dev); -int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, - unsigned char descindex, void *buf, int size); -int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char desctype, - unsigned char descindex, void *buf, int size); -int usb_get_device_descriptor(struct usb_device *dev); -int __usb_get_extra_descriptor(char *buffer, unsigned size, unsigned char type, void **ptr); -int usb_get_status(struct usb_device *dev, int type, int target, void *data); -int usb_get_configuration(struct usb_device *dev); -int usb_get_protocol(struct usb_device *dev, int ifnum); -int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); -int usb_set_interface(struct usb_device *dev, int ifnum, int alternate); -int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); -int usb_set_configuration(struct usb_device *dev, int configuration); -int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, - unsigned char id, void *buf, int size); -int usb_set_report(struct usb_device *dev, int ifnum, unsigned char type, - unsigned char id, void *buf, int size); -int usb_string(struct usb_device *dev, int index, char *buf, size_t size); -int usb_clear_halt(struct usb_device *dev, int pipe); -void usb_set_maxpacket(struct usb_device *dev); - -#define usb_get_extra_descriptor(ifpoint,type,ptr)\ - __usb_get_extra_descriptor((ifpoint)->extra,(ifpoint)->extralen,type,(void**)ptr) - -/* - * Some USB bandwidth allocation constants. - */ -#define BW_HOST_DELAY 1000L /* nanoseconds */ -#define BW_HUB_LS_SETUP 333L /* nanoseconds */ - /* 4 full-speed bit times (est.) */ - -#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */ -#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) -#define FRAME_TIME_USECS 1000L -#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) - -#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */ - /* Trying not to use worst-case bit-stuffing - of (7/6 * 8 * bytecount) = 9.33 * bytecount */ - /* bytecount = data payload byte count */ - -#define NS_TO_US(ns) ((ns + 500L) / 1000L) - /* convert & round nanoseconds to microseconds */ +/* -------------------------------------------------------------------------- */ /* - * Debugging helpers.. + * Debugging and troubleshooting/diagnostic helpers. */ void usb_show_device_descriptor(struct usb_device_descriptor *); void usb_show_config_descriptor(struct usb_config_descriptor *); @@ -1088,13 +1244,17 @@ #else #define dbg(format, arg...) do {} while (0) #endif + #define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ## arg) #define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ## arg) +/* -------------------------------------------------------------------------- */ + /* * bus and driver list + * exported only for usbdevfs (not visible outside usbcore) */ extern struct list_head usb_driver_list; diff -urN linux-2.5.1-pre7/init/do_mounts.c linux/init/do_mounts.c --- linux-2.5.1-pre7/init/do_mounts.c Sat Dec 8 21:04:23 2001 +++ linux/init/do_mounts.c Sat Dec 8 21:05:04 2001 @@ -351,7 +351,8 @@ mount("devfs", ".", "devfs", 0, NULL); retry: for (p = fs_names; *p; p += strlen(p)+1) { - err = mount(name,"/root",p,root_mountflags,root_mount_data); + int err; + err = sys_mount(name,"/root",p,root_mountflags,root_mount_data); switch (err) { case 0: goto done; diff -urN linux-2.5.1-pre7/ipc/shm.c linux/ipc/shm.c --- linux-2.5.1-pre7/ipc/shm.c Wed Oct 17 14:16:39 2001 +++ linux/ipc/shm.c Sat Dec 8 21:05:04 2001 @@ -569,6 +569,7 @@ { struct shmid_kernel *shp; unsigned long addr; + unsigned long size; struct file * file; int err; unsigned long flags; @@ -588,8 +589,12 @@ return -EINVAL; } flags = MAP_SHARED | MAP_FIXED; - } else + } else { + if ((shmflg & SHM_REMAP)) + return -EINVAL; + flags = MAP_SHARED; + } if (shmflg & SHM_RDONLY) { prot = PROT_READ; @@ -603,7 +608,7 @@ /* * We cannot rely on the fs check since SYSV IPC does have an - * aditional creator id... + * additional creator id... */ shp = shm_lock(shmid); if(shp == NULL) @@ -618,11 +623,27 @@ return -EACCES; } file = shp->shm_file; + size = file->f_dentry->d_inode->i_size; shp->shm_nattch++; shm_unlock(shmid); down_write(¤t->mm->mmap_sem); - user_addr = (void *) do_mmap (file, addr, file->f_dentry->d_inode->i_size, prot, flags, 0); + if (addr && !(shmflg & SHM_REMAP)) { + user_addr = ERR_PTR(-EINVAL); + if (find_vma_intersection(current->mm, addr, addr + size)) + goto invalid; + /* + * If shm segment goes below stack, make sure there is some + * space left for the stack to grow (at least 4 pages). + */ + if (addr < current->mm->start_stack && + addr > current->mm->start_stack - size - PAGE_SIZE * 5) + goto invalid; + } + + user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0); + +invalid: up_write(¤t->mm->mmap_sem); down (&shm_ids.sem); diff -urN linux-2.5.1-pre7/mm/highmem.c linux/mm/highmem.c --- linux-2.5.1-pre7/mm/highmem.c Sat Dec 8 21:04:23 2001 +++ linux/mm/highmem.c Sat Dec 8 21:05:04 2001 @@ -387,9 +387,9 @@ char *vto, *vfrom; vto = page_address(to->bv_page) + to->bv_offset; - vfrom = kmap(from->bv_page); - memcpy(vto, vfrom + from->bv_offset, to->bv_len); - kunmap(to->bv_page); + vfrom = kmap(from->bv_page) + from->bv_offset; + memcpy(vto, vfrom, to->bv_len); + kunmap(from->bv_page); } }