Commit db81280f authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/linux-2.5

into mulgrave.(none):/home/jejb/BK/scsi-for-linus-2.5
parents 2583ec21 5fe41502
bk-kernel-howto.txt: Description of kernel workflow under BitKeeper
bk-make-sum: Create summary of changesets in one repository and not
another, typically in preparation to be sent to an upstream maintainer.
Typical usage:
cd my-updated-repo
bk-make-sum ~/repo/original-repo
mv /tmp/linus.txt ../original-repo.txt
bksend: Create readable text output containing summary of changes, GNU
patch of the changes, and BK metadata of changes (as needed for proper
importing into BitKeeper by an upstream maintainer). This output is
suitable for emailing BitKeeper changes. The recipient of this output
may pipe it directly to 'bk receive'.
bz64wrap: helper script. Uncompressed input is piped to this script,
which compresses its input, and then outputs the uu-/base64-encoded
version of the compressed input.
csets-to-patches: Produces a delta of two BK repositories, in the form
of individual files, each containing a single cset as a GNU patch.
Output is several files, each with the filename "/tmp/rev-$REV.patch"
Typical usage:
cd my-updated-repo
bk changes -L ~/repo/original-repo 2>&1 | \
perl csets-to-patches
cset-to-linus: Produces a delta of two BK repositories, in the form of
changeset descriptions, with 'diffstat' output created for each
individual changset.
Typical usage:
cd my-updated-repo
bk changes -L ~/repo/original-repo 2>&1 | \
perl cset-to-linus > summary.txt
unbz64wrap: Reverse an encoded, compressed data stream created by
bz64wrap into an uncompressed, typically text/plain output.
...@@ -32,7 +32,7 @@ land at the right destination... but I'm getting ahead of myself. ...@@ -32,7 +32,7 @@ land at the right destination... but I'm getting ahead of myself.
Let's start with this progression: Let's start with this progression:
Each BitKeeper source tree on disk is a repository unto itself. Each BitKeeper source tree on disk is a repository unto itself.
Each repository has a parent. Each repository has a parent (except the root/original, of course).
Each repository contains a set of a changesets ("csets"). Each repository contains a set of a changesets ("csets").
Each cset is one or more changed files, bundled together. Each cset is one or more changed files, bundled together.
......
...@@ -565,7 +565,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) ...@@ -565,7 +565,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
return; return;
} }
list_del(&rq->queuelist); list_del_init(&rq->queuelist);
rq->flags &= ~REQ_QUEUED; rq->flags &= ~REQ_QUEUED;
rq->tag = -1; rq->tag = -1;
...@@ -649,7 +649,7 @@ void blk_queue_invalidate_tags(request_queue_t *q) ...@@ -649,7 +649,7 @@ void blk_queue_invalidate_tags(request_queue_t *q)
if (rq->tag == -1) { if (rq->tag == -1) {
printk("bad tag found on list\n"); printk("bad tag found on list\n");
list_del(&rq->queuelist); list_del_init(&rq->queuelist);
rq->flags &= ~REQ_QUEUED; rq->flags &= ~REQ_QUEUED;
} else } else
blk_queue_end_tag(q, rq); blk_queue_end_tag(q, rq);
...@@ -1132,7 +1132,7 @@ static int __blk_cleanup_queue(struct request_list *list) ...@@ -1132,7 +1132,7 @@ static int __blk_cleanup_queue(struct request_list *list)
while (!list_empty(head)) { while (!list_empty(head)) {
rq = list_entry(head->next, struct request, queuelist); rq = list_entry(head->next, struct request, queuelist);
list_del(&rq->queuelist); list_del_init(&rq->queuelist);
kmem_cache_free(request_cachep, rq); kmem_cache_free(request_cachep, rq);
i++; i++;
} }
...@@ -1292,13 +1292,20 @@ static struct request *get_request(request_queue_t *q, int rw) ...@@ -1292,13 +1292,20 @@ static struct request *get_request(request_queue_t *q, int rw)
if (!list_empty(&rl->free)) { if (!list_empty(&rl->free)) {
rq = blkdev_free_rq(&rl->free); rq = blkdev_free_rq(&rl->free);
list_del(&rq->queuelist); list_del_init(&rq->queuelist);
rq->ref_count = 1;
rl->count--; rl->count--;
if (rl->count < queue_congestion_on_threshold()) if (rl->count < queue_congestion_on_threshold())
set_queue_congested(q, rw); set_queue_congested(q, rw);
rq->flags = 0; rq->flags = 0;
rq->rq_status = RQ_ACTIVE; rq->rq_status = RQ_ACTIVE;
rq->errors = 0;
rq->special = NULL; rq->special = NULL;
rq->buffer = NULL;
rq->data = NULL;
rq->sense = NULL;
rq->waiting = NULL;
rq->bio = rq->biotail = NULL;
rq->q = q; rq->q = q;
rq->rl = rl; rq->rl = rl;
} }
...@@ -1497,13 +1504,14 @@ static inline void add_request(request_queue_t * q, struct request * req, ...@@ -1497,13 +1504,14 @@ static inline void add_request(request_queue_t * q, struct request * req,
__elv_add_request_pos(q, req, insert_here); __elv_add_request_pos(q, req, insert_here);
} }
/* void __blk_put_request(request_queue_t *q, struct request *req)
* Must be called with queue lock held and interrupts disabled
*/
void blk_put_request(struct request *req)
{ {
struct request_list *rl = req->rl; struct request_list *rl = req->rl;
request_queue_t *q = req->q;
if (unlikely(--req->ref_count))
return;
if (unlikely(!q))
return;
req->rq_status = RQ_INACTIVE; req->rq_status = RQ_INACTIVE;
req->q = NULL; req->q = NULL;
...@@ -1516,6 +1524,8 @@ void blk_put_request(struct request *req) ...@@ -1516,6 +1524,8 @@ void blk_put_request(struct request *req)
if (rl) { if (rl) {
int rw = 0; int rw = 0;
BUG_ON(!list_empty(&req->queuelist));
list_add(&req->queuelist, &rl->free); list_add(&req->queuelist, &rl->free);
if (rl == &q->rq[WRITE]) if (rl == &q->rq[WRITE])
...@@ -1533,6 +1543,23 @@ void blk_put_request(struct request *req) ...@@ -1533,6 +1543,23 @@ void blk_put_request(struct request *req)
} }
} }
void blk_put_request(struct request *req)
{
request_queue_t *q = req->q;
/*
* if req->q isn't set, this request didnt originate from the
* block layer, so it's safe to just disregard it
*/
if (q) {
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
__blk_put_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
}
}
/** /**
* blk_congestion_wait - wait for a queue to become uncongested * blk_congestion_wait - wait for a queue to become uncongested
* @rw: READ or WRITE * @rw: READ or WRITE
...@@ -1591,7 +1618,7 @@ static void attempt_merge(request_queue_t *q, struct request *req, ...@@ -1591,7 +1618,7 @@ static void attempt_merge(request_queue_t *q, struct request *req,
elv_merge_requests(q, req, next); elv_merge_requests(q, req, next);
blkdev_dequeue_request(next); blkdev_dequeue_request(next);
blk_put_request(next); __blk_put_request(q, next);
} }
} }
...@@ -1784,7 +1811,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1784,7 +1811,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
add_request(q, req, insert_here); add_request(q, req, insert_here);
out: out:
if (freereq) if (freereq)
blk_put_request(freereq); __blk_put_request(q, freereq);
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
return 0; return 0;
...@@ -1914,7 +1941,6 @@ int submit_bio(int rw, struct bio *bio) ...@@ -1914,7 +1941,6 @@ int submit_bio(int rw, struct bio *bio)
{ {
int count = bio_sectors(bio); int count = bio_sectors(bio);
BUG_ON(!bio->bi_end_io);
BIO_BUG_ON(!bio->bi_size); BIO_BUG_ON(!bio->bi_size);
BIO_BUG_ON(!bio->bi_io_vec); BIO_BUG_ON(!bio->bi_io_vec);
bio->bi_rw = rw; bio->bi_rw = rw;
...@@ -1931,6 +1957,9 @@ inline void blk_recalc_rq_segments(struct request *rq) ...@@ -1931,6 +1957,9 @@ inline void blk_recalc_rq_segments(struct request *rq)
struct bio *bio; struct bio *bio;
int nr_phys_segs, nr_hw_segs; int nr_phys_segs, nr_hw_segs;
if (!rq->bio)
return;
rq->buffer = bio_data(rq->bio); rq->buffer = bio_data(rq->bio);
nr_phys_segs = nr_hw_segs = 0; nr_phys_segs = nr_hw_segs = 0;
...@@ -1948,7 +1977,7 @@ inline void blk_recalc_rq_segments(struct request *rq) ...@@ -1948,7 +1977,7 @@ inline void blk_recalc_rq_segments(struct request *rq)
inline void blk_recalc_rq_sectors(struct request *rq, int nsect) inline void blk_recalc_rq_sectors(struct request *rq, int nsect)
{ {
if (rq->bio) { if (blk_fs_request(rq)) {
rq->hard_sector += nsect; rq->hard_sector += nsect;
rq->nr_sectors = rq->hard_nr_sectors -= nsect; rq->nr_sectors = rq->hard_nr_sectors -= nsect;
rq->sector = rq->hard_sector; rq->sector = rq->hard_sector;
...@@ -1967,27 +1996,19 @@ inline void blk_recalc_rq_sectors(struct request *rq, int nsect) ...@@ -1967,27 +1996,19 @@ inline void blk_recalc_rq_sectors(struct request *rq, int nsect)
} }
} }
/** static int __end_that_request_first(struct request *req, int uptodate,
* end_that_request_first - end I/O on one buffer. int nr_bytes)
* @req: the request being processed
* @uptodate: 0 for I/O error
* @nr_sectors: number of sectors to end I/O on
*
* Description:
* Ends I/O on a number of sectors attached to @req, and sets it up
* for the next range of segments (if any) in the cluster.
*
* Return:
* 0 - we are done with this request, call end_that_request_last()
* 1 - still buffers pending for this request
**/
int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
{ {
int total_nsect = 0, error = 0; int total_bytes, bio_nbytes, error = 0, next_idx = 0;
struct bio *bio; struct bio *bio;
req->errors = 0; /*
* for a REQ_BLOCK_PC request, we want to carry any eventual
* sense key with us all the way through
*/
if (!blk_pc_request(req))
req->errors = 0;
if (!uptodate) { if (!uptodate) {
error = -EIO; error = -EIO;
if (!(req->flags & REQ_QUIET)) if (!(req->flags & REQ_QUIET))
...@@ -1996,56 +2017,56 @@ int end_that_request_first(struct request *req, int uptodate, int nr_sectors) ...@@ -1996,56 +2017,56 @@ int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
(unsigned long long)req->sector); (unsigned long long)req->sector);
} }
total_bytes = bio_nbytes = 0;
while ((bio = req->bio)) { while ((bio = req->bio)) {
int new_bio = 0, nsect; int nbytes;
if (unlikely(bio->bi_idx >= bio->bi_vcnt)) { if (nr_bytes >= bio->bi_size) {
printk("%s: bio idx %d >= vcnt %d\n", __FUNCTION__, req->bio = bio->bi_next;
nbytes = bio->bi_size;
bio_endio(bio, nbytes, error);
next_idx = 0;
bio_nbytes = 0;
} else {
int idx = bio->bi_idx + next_idx;
if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
blk_dump_rq_flags(req, "__end_that");
printk("%s: bio idx %d >= vcnt %d\n",
__FUNCTION__,
bio->bi_idx, bio->bi_vcnt); bio->bi_idx, bio->bi_vcnt);
break; break;
} }
BIO_BUG_ON(bio_iovec(bio)->bv_len > bio->bi_size); nbytes = bio_iovec_idx(bio, idx)->bv_len;
BIO_BUG_ON(nbytes > bio->bi_size);
/* /*
* not a complete bvec done * not a complete bvec done
*/ */
nsect = bio_iovec(bio)->bv_len >> 9; if (unlikely(nbytes > nr_bytes)) {
if (unlikely(nsect > nr_sectors)) { bio_iovec(bio)->bv_offset += nr_bytes;
int partial = nr_sectors << 9; bio_iovec(bio)->bv_len -= nr_bytes;
bio_nbytes += nr_bytes;
bio_iovec(bio)->bv_offset += partial; total_bytes += nr_bytes;
bio_iovec(bio)->bv_len -= partial; break;
bio_endio(bio, partial, error); }
total_nsect += nr_sectors;
break;
}
/* /*
* we are ending the last part of the bio, advance req pointer * advance to the next vector
*/ */
if ((nsect << 9) >= bio->bi_size) { next_idx++;
req->bio = bio->bi_next; bio_nbytes += nbytes;
new_bio = 1;
} }
bio_endio(bio, nsect << 9, error); total_bytes += nbytes;
nr_bytes -= nbytes;
total_nsect += nsect;
nr_sectors -= nsect;
/*
* if we didn't advance the req->bio pointer, advance bi_idx
* to indicate we are now on the next bio_vec
*/
if (!new_bio)
bio->bi_idx++;
if ((bio = req->bio)) { if ((bio = req->bio)) {
/* /*
* end more in this run, or just return 'not-done' * end more in this run, or just return 'not-done'
*/ */
if (unlikely(nr_sectors <= 0)) if (unlikely(nr_bytes <= 0))
break; break;
} }
} }
...@@ -2059,17 +2080,64 @@ int end_that_request_first(struct request *req, int uptodate, int nr_sectors) ...@@ -2059,17 +2080,64 @@ int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
/* /*
* if the request wasn't completed, update state * if the request wasn't completed, update state
*/ */
blk_recalc_rq_sectors(req, total_nsect); if (bio_nbytes) {
bio_endio(bio, bio_nbytes, error);
req->bio->bi_idx += next_idx;
}
blk_recalc_rq_sectors(req, total_bytes >> 9);
blk_recalc_rq_segments(req); blk_recalc_rq_segments(req);
return 1; return 1;
} }
/**
* end_that_request_first - end I/O on a request
* @req: the request being processed
* @uptodate: 0 for I/O error
* @nr_sectors: number of sectors to end I/O on
*
* Description:
* Ends I/O on a number of sectors attached to @req, and sets it up
* for the next range of segments (if any) in the cluster.
*
* Return:
* 0 - we are done with this request, call end_that_request_last()
* 1 - still buffers pending for this request
**/
int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
{
return __end_that_request_first(req, uptodate, nr_sectors << 9);
}
/**
* end_that_request_chunk - end I/O on a request
* @req: the request being processed
* @uptodate: 0 for I/O error
* @nr_bytes: number of bytes to complete
*
* Description:
* Ends I/O on a number of bytes attached to @req, and sets it up
* for the next range of segments (if any). Like end_that_request_first(),
* but deals with bytes instead of sectors.
*
* Return:
* 0 - we are done with this request, call end_that_request_last()
* 1 - still buffers pending for this request
**/
int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes)
{
return __end_that_request_first(req, uptodate, nr_bytes);
}
/*
* queue lock must be held
*/
void end_that_request_last(struct request *req) void end_that_request_last(struct request *req)
{ {
if (req->waiting) if (req->waiting)
complete(req->waiting); complete(req->waiting);
blk_put_request(req); __blk_put_request(req->q, req);
} }
int __init blk_dev_init(void) int __init blk_dev_init(void)
...@@ -2115,6 +2183,7 @@ int __init blk_dev_init(void) ...@@ -2115,6 +2183,7 @@ int __init blk_dev_init(void)
}; };
EXPORT_SYMBOL(end_that_request_first); EXPORT_SYMBOL(end_that_request_first);
EXPORT_SYMBOL(end_that_request_chunk);
EXPORT_SYMBOL(end_that_request_last); EXPORT_SYMBOL(end_that_request_last);
EXPORT_SYMBOL(blk_init_queue); EXPORT_SYMBOL(blk_init_queue);
EXPORT_SYMBOL(bdev_get_queue); EXPORT_SYMBOL(bdev_get_queue);
......
...@@ -548,12 +548,7 @@ static void process_page(unsigned long data) ...@@ -548,12 +548,7 @@ static void process_page(unsigned long data)
return_bio = bio->bi_next; return_bio = bio->bi_next;
bio->bi_next = NULL; bio->bi_next = NULL;
/* should use bio_endio(), however already cleared bio_endio(bio, bio->bi_size, 0);
* BIO_UPTODATE. so set bio->bi_size = 0 manually to indicate
* completely done
*/
bio->bi_size = 0;
bio->bi_end_io(bio, bytes, 0);
} }
} }
...@@ -1041,7 +1036,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i ...@@ -1041,7 +1036,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i
spin_lock_init(&card->lock); spin_lock_init(&card->lock);
dev->driver_data = card; pci_set_drvdata(dev, card);
if (pci_write_cmd != 0x0F) /* If not Memory Write & Invalidate */ if (pci_write_cmd != 0x0F) /* If not Memory Write & Invalidate */
pci_write_cmd = 0x07; /* then Memory Write command */ pci_write_cmd = 0x07; /* then Memory Write command */
...@@ -1100,7 +1095,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i ...@@ -1100,7 +1095,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i
*/ */
static void mm_pci_remove(struct pci_dev *dev) static void mm_pci_remove(struct pci_dev *dev)
{ {
struct cardinfo *card = dev->driver_data; struct cardinfo *card = pci_get_drvdata(dev);
tasklet_kill(&card->tasklet); tasklet_kill(&card->tasklet);
iounmap(card->csr_remap); iounmap(card->csr_remap);
......
...@@ -1610,56 +1610,6 @@ static void idedisk_add_settings(ide_drive_t *drive) ...@@ -1610,56 +1610,6 @@ static void idedisk_add_settings(ide_drive_t *drive)
#endif #endif
} }
static int idedisk_suspend(struct device *dev, u32 state, u32 level)
{
ide_drive_t *drive = dev->driver_data;
printk("Suspending device %p\n", dev->driver_data);
/* I hope that every freeze operation from the upper levels have
* already been done...
*/
if (level != SUSPEND_SAVE_STATE)
return 0;
BUG_ON(in_interrupt());
printk("Waiting for commands to finish\n");
/* wait until all commands are finished */
/* FIXME: waiting for spinlocks should be done instead. */
if (!(HWGROUP(drive)))
printk("No hwgroup?\n");
while (HWGROUP(drive)->handler)
yield();
/* set the drive to standby */
printk(KERN_INFO "suspending: %s ", drive->name);
if (drive->driver) {
if (drive->driver->standby)
drive->driver->standby(drive);
}
drive->blocked = 1;
while (HWGROUP(drive)->handler)
yield();
return 0;
}
static int idedisk_resume(struct device *dev, u32 level)
{
ide_drive_t *drive = dev->driver_data;
if (level != RESUME_RESTORE_STATE)
return 0;
if (!drive->blocked)
panic("ide: Resume but not suspended?\n");
drive->blocked = 0;
return 0;
}
/* This is just a hook for the overall driver tree. /* This is just a hook for the overall driver tree.
*/ */
......
...@@ -1238,6 +1238,21 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t ...@@ -1238,6 +1238,21 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
set_bit(PC_DMA_RECOMMENDED, &pc->flags); set_bit(PC_DMA_RECOMMENDED, &pc->flags);
} }
static int
idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq)
{
/*
* just support eject for now, it would not be hard to make the
* REQ_BLOCK_PC support fully-featured
*/
if (rq->cmd[0] != IDEFLOPPY_START_STOP_CMD)
return 1;
idefloppy_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
return 0;
}
/* /*
* idefloppy_do_request is our request handling function. * idefloppy_do_request is our request handling function.
*/ */
...@@ -1280,6 +1295,12 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request ...@@ -1280,6 +1295,12 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
idefloppy_create_rw_cmd(floppy, pc, rq, block); idefloppy_create_rw_cmd(floppy, pc, rq, block);
} else if (rq->flags & REQ_SPECIAL) { } else if (rq->flags & REQ_SPECIAL) {
pc = (idefloppy_pc_t *) rq->buffer; pc = (idefloppy_pc_t *) rq->buffer;
} else if (rq->flags & REQ_BLOCK_PC) {
pc = idefloppy_next_pc_storage(drive);
if (idefloppy_blockpc_cmd(floppy, pc, rq)) {
idefloppy_do_end_request(drive, 0, 0);
return ide_stopped;
}
} else { } else {
blk_dump_rq_flags(rq, blk_dump_rq_flags(rq,
"ide-floppy: unsupported command in queue"); "ide-floppy: unsupported command in queue");
......
...@@ -878,13 +878,12 @@ ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ...@@ -878,13 +878,12 @@ ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{ {
ide_startstop_t startstop; ide_startstop_t startstop;
unsigned long block; unsigned long block;
ide_hwif_t *hwif = HWIF(drive);
BUG_ON(!(rq->flags & REQ_STARTED)); BUG_ON(!(rq->flags & REQ_STARTED));
#ifdef DEBUG #ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n", printk("%s: start_request: current=0x%08lx\n",
hwif->name, (unsigned long) rq); HWIF(drive)->name, (unsigned long) rq);
#endif #endif
/* bail early if we've exceeded max_failures */ /* bail early if we've exceeded max_failures */
...@@ -910,7 +909,7 @@ ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ...@@ -910,7 +909,7 @@ ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
block = 1; /* redirect MBR access to EZ-Drive partn table */ block = 1; /* redirect MBR access to EZ-Drive partn table */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME);
#endif #endif
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
...@@ -1128,9 +1127,15 @@ void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ...@@ -1128,9 +1127,15 @@ void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
break; break;
} }
/*
* we know that the queue isn't empty, but this can happen
* if the q->prep_rq_fn() decides to kill a request
*/
rq = elv_next_request(&drive->queue); rq = elv_next_request(&drive->queue);
if (!rq) if (!rq) {
hwgroup->busy = !!ata_pending_commands(drive);
break; break;
}
if (!rq->bio && ata_pending_commands(drive)) if (!rq->bio && ata_pending_commands(drive))
break; break;
...@@ -1515,10 +1520,8 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio ...@@ -1515,10 +1520,8 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
{ {
unsigned long flags; unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned int major = HWIF(drive)->major;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait); DECLARE_COMPLETION(wait);
int insert_end = 1, err;
#ifdef CONFIG_BLK_DEV_PDC4030 #ifdef CONFIG_BLK_DEV_PDC4030
if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL) if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL)
...@@ -1540,29 +1543,35 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio ...@@ -1540,29 +1543,35 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
} }
rq->rq_disk = drive->disk; rq->rq_disk = drive->disk;
if (action == ide_wait)
/*
* we need to hold an extra reference to request for safe inspection
* after completion
*/
if (action == ide_wait) {
rq->ref_count++;
rq->waiting = &wait; rq->waiting = &wait;
}
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (blk_queue_empty(q) || action == ide_preempt) { if (action == ide_preempt) {
if (action == ide_preempt) hwgroup->rq = NULL;
hwgroup->rq = NULL; insert_end = 0;
} else {
if (action == ide_wait || action == ide_end) {
queue_head = queue_head->prev;
} else
queue_head = queue_head->next;
} }
q->elevator.elevator_add_req_fn(q, rq, queue_head); __elv_add_request(&drive->queue, rq, insert_end, 0);
ide_do_request(hwgroup, 0); ide_do_request(hwgroup, 0);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
err = 0;
if (action == ide_wait) { if (action == ide_wait) {
/* wait for it to be serviced */
wait_for_completion(&wait); wait_for_completion(&wait);
/* return -EIO if errors */ if (rq->errors)
return rq->errors ? -EIO : 0; err = -EIO;
blk_put_request(rq);
} }
return 0;
return err;
} }
EXPORT_SYMBOL(ide_do_drive_cmd); EXPORT_SYMBOL(ide_do_drive_cmd);
...@@ -3369,7 +3378,7 @@ int ide_register_driver(ide_driver_t *driver) ...@@ -3369,7 +3378,7 @@ int ide_register_driver(ide_driver_t *driver)
list_del_init(&drive->list); list_del_init(&drive->list);
ata_attach(drive); ata_attach(drive);
} }
driver->gen_driver.name = driver->name; driver->gen_driver.name = (char *) driver->name;
driver->gen_driver.bus = &ide_bus_type; driver->gen_driver.bus = &ide_bus_type;
driver->gen_driver.remove = ide_drive_remove; driver->gen_driver.remove = ide_drive_remove;
return driver_register(&driver->gen_driver); return driver_register(&driver->gen_driver);
......
...@@ -316,7 +316,7 @@ static void hpt366_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -316,7 +316,7 @@ static void hpt366_tune_chipset (ide_drive_t *drive, u8 xferspeed)
#endif #endif
reg2 = pci_bus_clock_list(speed, reg2 = pci_bus_clock_list(speed,
(struct chipset_bus_clock_list_entry *) dev->driver_data); (struct chipset_bus_clock_list_entry *) pci_get_drvdata(dev));
/* /*
* Disable on-chip PIO FIFO/buffer * Disable on-chip PIO FIFO/buffer
* (to avoid problems handling I/O errors later) * (to avoid problems handling I/O errors later)
...@@ -369,7 +369,7 @@ static void hpt370_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -369,7 +369,7 @@ static void hpt370_tune_chipset (ide_drive_t *drive, u8 xferspeed)
list_conf = pci_bus_clock_list(speed, list_conf = pci_bus_clock_list(speed,
(struct chipset_bus_clock_list_entry *) (struct chipset_bus_clock_list_entry *)
dev->driver_data); pci_get_drvdata(dev));
pci_read_config_dword(dev, drive_pci, &drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf);
list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
...@@ -401,7 +401,7 @@ static void hpt372_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -401,7 +401,7 @@ static void hpt372_tune_chipset (ide_drive_t *drive, u8 xferspeed)
list_conf = pci_bus_clock_list(speed, list_conf = pci_bus_clock_list(speed,
(struct chipset_bus_clock_list_entry *) (struct chipset_bus_clock_list_entry *)
dev->driver_data); pci_get_drvdata(dev));
pci_read_config_dword(dev, drive_pci, &drive_conf); pci_read_config_dword(dev, drive_pci, &drive_conf);
list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
if (speed < XFER_MW_DMA_0) if (speed < XFER_MW_DMA_0)
...@@ -841,7 +841,7 @@ static int __init init_hpt37x(struct pci_dev *dev) ...@@ -841,7 +841,7 @@ static int __init init_hpt37x(struct pci_dev *dev)
* don't like to use the PLL because it will cause glitches * don't like to use the PLL because it will cause glitches
* on PRST/SRST when the HPT state engine gets reset. * on PRST/SRST when the HPT state engine gets reset.
*/ */
if (dev->driver_data) if (pci_get_drvdata(dev))
goto init_hpt37X_done; goto init_hpt37X_done;
/* /*
...@@ -923,7 +923,7 @@ static int __init init_hpt366 (struct pci_dev *dev) ...@@ -923,7 +923,7 @@ static int __init init_hpt366 (struct pci_dev *dev)
break; break;
} }
if (!dev->driver_data) if (!pci_get_drvdata(dev))
{ {
printk(KERN_ERR "hpt366: unknown bus timing.\n"); printk(KERN_ERR "hpt366: unknown bus timing.\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
......
...@@ -30,8 +30,8 @@ static int n_siimage_devs; ...@@ -30,8 +30,8 @@ static int n_siimage_devs;
static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index) static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index)
{ {
char *p = buf; char *p = buf;
u8 mmio = (dev->driver_data != NULL) ? 1 : 0; u8 mmio = (pci_get_drvdata(dev) != NULL) ? 1 : 0;
u32 bmdma = (mmio) ? ((u32) dev->driver_data) : u32 bmdma = (mmio) ? ((u32) pci_get_drvdata(dev)) :
(pci_resource_start(dev, 4)); (pci_resource_start(dev, 4));
p += sprintf(p, "\nController: %d\n", index); p += sprintf(p, "\nController: %d\n", index);
...@@ -769,14 +769,14 @@ static void __init init_iops_siimage (ide_hwif_t *hwif) ...@@ -769,14 +769,14 @@ static void __init init_iops_siimage (ide_hwif_t *hwif)
if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev))) if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev)))
hwif->rqsize = 16; hwif->rqsize = 16;
if (dev->driver_data == NULL) if (pci_get_drvdata(dev) == NULL)
return; return;
init_mmio_iops_siimage(hwif); init_mmio_iops_siimage(hwif);
} }
static unsigned int __init ata66_siimage (ide_hwif_t *hwif) static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
{ {
if (hwif->pci_dev->driver_data == NULL) { if (pci_get_drvdata(hwif->pci_dev) == NULL) {
u8 ata66 = 0; u8 ata66 = 0;
pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66); pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66);
return (ata66 & 0x01) ? 1 : 0; return (ata66 & 0x01) ? 1 : 0;
......
...@@ -52,19 +52,21 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) ...@@ -52,19 +52,21 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
* @bio: the buffer head that's been built up so far * @bio: the buffer head that's been built up so far
* @biovec: the request that could be merged to it. * @biovec: the request that could be merged to it.
* *
* Return 1 if the merge is not permitted (because the * Return amount of bytes we can take at this offset
* result would cross a device boundary), 0 otherwise.
*/ */
static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec) static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
dev_info_t *dev0, *dev1; dev_info_t *dev0;
int maxsectors, bio_sectors = (bio->bi_size + biovec->bv_len) >> 9;
dev0 = which_dev(mddev, bio->bi_sector); dev0 = which_dev(mddev, bio->bi_sector);
dev1 = which_dev(mddev, bio->bi_sector + maxsectors = (dev0->size << 1) - (bio->bi_sector - (dev0->offset<<1));
((bio->bi_size + biovec->bv_len - 1) >> 9));
return dev0 != dev1; if (bio_sectors <= maxsectors)
return biovec->bv_len;
return (maxsectors << 9) - bio->bi_size;
} }
static int linear_run (mddev_t *mddev) static int linear_run (mddev_t *mddev)
......
...@@ -168,8 +168,7 @@ static int create_strip_zones (mddev_t *mddev) ...@@ -168,8 +168,7 @@ static int create_strip_zones (mddev_t *mddev)
* @bio: the buffer head that's been built up so far * @bio: the buffer head that's been built up so far
* @biovec: the request that could be merged to it. * @biovec: the request that could be merged to it.
* *
* Return 1 if the merge is not permitted (because the * Return amount of bytes we can accept at this offset
* result would cross a chunk boundary), 0 otherwise.
*/ */
static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec) static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
{ {
...@@ -182,7 +181,7 @@ static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_ ...@@ -182,7 +181,7 @@ static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_
block = bio->bi_sector >> 1; block = bio->bi_sector >> 1;
bio_sz = (bio->bi_size + biovec->bv_len) >> 10; bio_sz = (bio->bi_size + biovec->bv_len) >> 10;
return chunk_size < ((block & (chunk_size - 1)) + bio_sz); return (chunk_size - ((block & (chunk_size - 1)) + bio_sz)) << 10;
} }
static int raid0_run (mddev_t *mddev) static int raid0_run (mddev_t *mddev)
......
...@@ -122,8 +122,7 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; ...@@ -122,8 +122,7 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
static int debug = -1; static int debug = -1;
#define DEBUG_DEFAULT (NETIF_MSG_DRV | \ #define DEBUG_DEFAULT (NETIF_MSG_DRV | \
NETIF_MSG_IFDOWN | \ NETIF_MSG_HW | \
NETIF_MSG_IFUP | \
NETIF_MSG_RX_ERR | \ NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR) NETIF_MSG_TX_ERR)
#define DEBUG ((debug >= 0) ? (1<<debug)-1 : DEBUG_DEFAULT) #define DEBUG ((debug >= 0) ? (1<<debug)-1 : DEBUG_DEFAULT)
...@@ -568,10 +567,8 @@ static inline unsigned char wait_for_cmd_done(struct net_device *dev) ...@@ -568,10 +567,8 @@ static inline unsigned char wait_for_cmd_done(struct net_device *dev)
r = inb(cmd_ioaddr); r = inb(cmd_ioaddr);
} while(r && --wait >= 0); } while(r && --wait >= 0);
#ifndef final_version
if (wait < 0) if (wait < 0)
printk(KERN_ALERT "%s: wait_for_cmd_done timeout!\n", dev->name); printk(KERN_ALERT "%s: wait_for_cmd_done timeout!\n", dev->name);
#endif
return r; return r;
} }
...@@ -852,7 +849,9 @@ static int __devinit speedo_found1(struct pci_dev *pdev, ...@@ -852,7 +849,9 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
sp->phy[0] = eeprom[6]; sp->phy[0] = eeprom[6];
sp->phy[1] = eeprom[7]; sp->phy[1] = eeprom[7];
sp->mii_if.phy_id = eeprom[6]; sp->mii_if.phy_id = eeprom[6] & 0x1f;
sp->mii_if.phy_id_mask = 0x1f;
sp->mii_if.reg_num_mask = 0x1f;
sp->mii_if.dev = dev; sp->mii_if.dev = dev;
sp->mii_if.mdio_read = mdio_read; sp->mii_if.mdio_read = mdio_read;
sp->mii_if.mdio_write = mdio_write; sp->mii_if.mdio_write = mdio_write;
...@@ -1207,7 +1206,7 @@ static void speedo_timer(unsigned long data) ...@@ -1207,7 +1206,7 @@ static void speedo_timer(unsigned long data)
/* We haven't received a packet in a Long Time. We might have been /* We haven't received a packet in a Long Time. We might have been
bitten by the receiver hang bug. This can be cleared by sending bitten by the receiver hang bug. This can be cleared by sending
a set multicast list command. */ a set multicast list command. */
if (netif_msg_rx_err(sp)) if (netif_msg_timer(sp))
printk(KERN_DEBUG "%s: Sending a multicast list set command" printk(KERN_DEBUG "%s: Sending a multicast list set command"
" from a timer routine," " from a timer routine,"
" m=%d, j=%ld, l=%ld.\n", " m=%d, j=%ld, l=%ld.\n",
...@@ -1224,25 +1223,26 @@ static void speedo_show_state(struct net_device *dev) ...@@ -1224,25 +1223,26 @@ static void speedo_show_state(struct net_device *dev)
struct speedo_private *sp = (struct speedo_private *)dev->priv; struct speedo_private *sp = (struct speedo_private *)dev->priv;
int i; int i;
/* Print a few items for debugging. */ if (netif_msg_pktdata(sp)) {
printk(KERN_DEBUG "%s: Tx ring dump, Tx queue %u / %u:\n", dev->name, printk(KERN_DEBUG "%s: Tx ring dump, Tx queue %u / %u:\n",
sp->cur_tx, sp->dirty_tx); dev->name, sp->cur_tx, sp->dirty_tx);
for (i = 0; i < TX_RING_SIZE; i++) for (i = 0; i < TX_RING_SIZE; i++)
printk(KERN_DEBUG "%s: %c%c%2d %8.8x.\n", dev->name, printk(KERN_DEBUG "%s: %c%c%2d %8.8x.\n", dev->name,
i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ', i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ', i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
i, sp->tx_ring[i].status); i, sp->tx_ring[i].status);
printk(KERN_DEBUG "%s: Printing Rx ring" printk(KERN_DEBUG "%s: Printing Rx ring"
" (next to receive into %u, dirty index %u).\n", " (next to receive into %u, dirty index %u).\n",
dev->name, sp->cur_rx, sp->dirty_rx); dev->name, sp->cur_rx, sp->dirty_rx);
for (i = 0; i < RX_RING_SIZE; i++) for (i = 0; i < RX_RING_SIZE; i++)
printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name, printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name,
sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ', sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ',
i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ', i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ',
i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ', i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ',
i, (sp->rx_ringp[i] != NULL) ? i, (sp->rx_ringp[i] != NULL) ?
(unsigned)sp->rx_ringp[i]->status : 0); (unsigned)sp->rx_ringp[i]->status : 0);
}
#if 0 #if 0
{ {
...@@ -1378,8 +1378,8 @@ static void speedo_tx_timeout(struct net_device *dev) ...@@ -1378,8 +1378,8 @@ static void speedo_tx_timeout(struct net_device *dev)
sp->dirty_tx, sp->cur_tx, sp->dirty_tx, sp->cur_tx,
sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status); sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
speedo_show_state(dev);
} }
speedo_show_state(dev);
#if 0 #if 0
if ((status & 0x00C0) != 0x0080 if ((status & 0x00C0) != 0x0080
&& (status & 0x003C) == 0x0010) { && (status & 0x003C) == 0x0010) {
...@@ -1564,13 +1564,6 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs) ...@@ -1564,13 +1564,6 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
long ioaddr, boguscnt = max_interrupt_work; long ioaddr, boguscnt = max_interrupt_work;
unsigned short status; unsigned short status;
#ifndef final_version
if (dev == NULL) {
printk(KERN_ERR "speedo_interrupt(): irq %d for unknown device.\n", irq);
return;
}
#endif
ioaddr = dev->base_addr; ioaddr = dev->base_addr;
sp = (struct speedo_private *)dev->priv; sp = (struct speedo_private *)dev->priv;
...@@ -1717,9 +1710,9 @@ static int speedo_refill_rx_buf(struct net_device *dev, int force) ...@@ -1717,9 +1710,9 @@ static int speedo_refill_rx_buf(struct net_device *dev, int force)
if (netif_msg_rx_err(sp) || !(sp->rx_ring_state & RrOOMReported)) { if (netif_msg_rx_err(sp) || !(sp->rx_ring_state & RrOOMReported)) {
printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n", printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n",
dev->name, force); dev->name, force);
speedo_show_state(dev);
sp->rx_ring_state |= RrOOMReported; sp->rx_ring_state |= RrOOMReported;
} }
speedo_show_state(dev);
if (!force) if (!force)
return -1; /* Better luck next time! */ return -1; /* Better luck next time! */
/* Borrow an skb from one of next entries. */ /* Borrow an skb from one of next entries. */
...@@ -1792,7 +1785,7 @@ speedo_rx(struct net_device *dev) ...@@ -1792,7 +1785,7 @@ speedo_rx(struct net_device *dev)
break; break;
} }
if (netif_msg_intr(sp)) if (netif_msg_rx_status(sp))
printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status, printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status,
pkt_len); pkt_len);
if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) { if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) {
...@@ -1894,10 +1887,7 @@ speedo_close(struct net_device *dev) ...@@ -1894,10 +1887,7 @@ speedo_close(struct net_device *dev)
udelay(10); udelay(10);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
speedo_show_state(dev);
/* Print a few items for debugging. */
if (netif_msg_ifdown(sp))
speedo_show_state(dev);
/* Free all the skbuffs in the Rx and Tx queues. */ /* Free all the skbuffs in the Rx and Tx queues. */
for (i = 0; i < RX_RING_SIZE; i++) { for (i = 0; i < RX_RING_SIZE; i++) {
......
This diff is collapsed.
...@@ -1412,8 +1412,7 @@ static int i596_close(struct net_device *dev) ...@@ -1412,8 +1412,7 @@ static int i596_close(struct net_device *dev)
DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n", DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n",
dev->name, lp->scb.status)); dev->name, lp->scb.status));
save_flags(flags); spin_lock_irqsave(&lp->lock, flags);
cli();
wait_cmd(dev,lp,100,"close1 timed out"); wait_cmd(dev,lp,100,"close1 timed out");
lp->scb.command = CUC_ABORT | RX_ABORT; lp->scb.command = CUC_ABORT | RX_ABORT;
...@@ -1422,7 +1421,7 @@ static int i596_close(struct net_device *dev) ...@@ -1422,7 +1421,7 @@ static int i596_close(struct net_device *dev)
CA(dev); CA(dev);
wait_cmd(dev,lp,100,"close2 timed out"); wait_cmd(dev,lp,100,"close2 timed out");
restore_flags(flags); spin_unlock_irqrestore(&lp->lock, flags);
DEB(DEB_STRUCT,i596_display_data(dev)); DEB(DEB_STRUCT,i596_display_data(dev));
i596_cleanup_cmd(dev,lp); i596_cleanup_cmd(dev,lp);
......
...@@ -299,9 +299,9 @@ int generic_mii_ioctl(struct mii_if_info *mii_if, ...@@ -299,9 +299,9 @@ int generic_mii_ioctl(struct mii_if_info *mii_if,
case MII_BMCR: { case MII_BMCR: {
unsigned int new_duplex = 0; unsigned int new_duplex = 0;
if (val & (BMCR_RESET|BMCR_ANENABLE)) if (val & (BMCR_RESET|BMCR_ANENABLE))
mii_if->force_media = 1;
else
mii_if->force_media = 0; mii_if->force_media = 0;
else
mii_if->force_media = 1;
if (mii_if->force_media && if (mii_if->force_media &&
(val & BMCR_FULLDPLX)) (val & BMCR_FULLDPLX))
new_duplex = 1; new_duplex = 1;
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
*************************************************************************/ *************************************************************************/
#define DRV_NAME "pcnet32" #define DRV_NAME "pcnet32"
#define DRV_VERSION "1.27a" #define DRV_VERSION "1.27b"
#define DRV_RELDATE "10.02.2002" #define DRV_RELDATE "01.10.2002"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
static const char *version = static const char *version =
...@@ -96,6 +96,8 @@ static int rx_copybreak = 200; ...@@ -96,6 +96,8 @@ static int rx_copybreak = 200;
#define PCNET32_DMA_MASK 0xffffffff #define PCNET32_DMA_MASK 0xffffffff
#define PCNET32_WATCHDOG_TIMEOUT (jiffies + (2 * HZ))
/* /*
* table to translate option values from tulip * table to translate option values from tulip
* to internal options * to internal options
...@@ -211,6 +213,8 @@ static int full_duplex[MAX_UNITS]; ...@@ -211,6 +213,8 @@ static int full_duplex[MAX_UNITS];
* fix pci probe not increment cards_found * fix pci probe not increment cards_found
* FD auto negotiate error workaround for xSeries250 * FD auto negotiate error workaround for xSeries250
* clean up and using new mii module * clean up and using new mii module
* v1.27b Sep 30 2002 Kent Yoder <yoder1@us.ibm.com>
* Added timer for cable connection state changes.
*/ */
...@@ -318,6 +322,7 @@ struct pcnet32_private { ...@@ -318,6 +322,7 @@ struct pcnet32_private {
mii:1; /* mii port available */ mii:1; /* mii port available */
struct net_device *next; struct net_device *next;
struct mii_if_info mii_if; struct mii_if_info mii_if;
struct timer_list watchdog_timer;
}; };
static void pcnet32_probe_vlbus(void); static void pcnet32_probe_vlbus(void);
...@@ -333,6 +338,7 @@ static int pcnet32_close(struct net_device *); ...@@ -333,6 +338,7 @@ static int pcnet32_close(struct net_device *);
static struct net_device_stats *pcnet32_get_stats(struct net_device *); static struct net_device_stats *pcnet32_get_stats(struct net_device *);
static void pcnet32_set_multicast_list(struct net_device *); static void pcnet32_set_multicast_list(struct net_device *);
static int pcnet32_ioctl(struct net_device *, struct ifreq *, int); static int pcnet32_ioctl(struct net_device *, struct ifreq *, int);
static void pcnet32_watchdog(struct net_device *);
static int mdio_read(struct net_device *dev, int phy_id, int reg_num); static int mdio_read(struct net_device *dev, int phy_id, int reg_num);
static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val); static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val);
...@@ -777,6 +783,13 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared, ...@@ -777,6 +783,13 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
} }
} }
/* Set the mii phy_id so that we can query the link state */
if (lp->mii)
lp->mii_if.phy_id = ((lp->a.read_bcr (ioaddr, 33)) >> 5) & 0x1f;
init_timer (&lp->watchdog_timer);
lp->watchdog_timer.data = (unsigned long) dev;
lp->watchdog_timer.function = (void *) &pcnet32_watchdog;
/* The PCNET32-specific entries in the device structure. */ /* The PCNET32-specific entries in the device structure. */
dev->open = &pcnet32_open; dev->open = &pcnet32_open;
...@@ -901,6 +914,12 @@ pcnet32_open(struct net_device *dev) ...@@ -901,6 +914,12 @@ pcnet32_open(struct net_device *dev)
netif_start_queue(dev); netif_start_queue(dev);
/* If we have mii, print the link status and start the watchdog */
if (lp->mii) {
mii_check_media (&lp->mii_if, 1, 1);
mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT);
}
i = 0; i = 0;
while (i++ < 100) while (i++ < 100)
if (lp->a.read_csr (ioaddr, 0) & 0x0100) if (lp->a.read_csr (ioaddr, 0) & 0x0100)
...@@ -1371,6 +1390,8 @@ pcnet32_close(struct net_device *dev) ...@@ -1371,6 +1390,8 @@ pcnet32_close(struct net_device *dev)
struct pcnet32_private *lp = dev->priv; struct pcnet32_private *lp = dev->priv;
int i; int i;
del_timer_sync(&lp->watchdog_timer);
netif_stop_queue(dev); netif_stop_queue(dev);
lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112); lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112);
...@@ -1651,6 +1672,17 @@ static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1651,6 +1672,17 @@ static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void pcnet32_watchdog(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
/* Print the link status if it has changed */
if (lp->mii)
mii_check_media (&lp->mii_if, 1, 0);
mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT);
}
static struct pci_driver pcnet32_driver = { static struct pci_driver pcnet32_driver = {
name: DRV_NAME, name: DRV_NAME,
probe: pcnet32_probe_pci, probe: pcnet32_probe_pci,
......
...@@ -1780,7 +1780,7 @@ static int xl_change_mtu(struct net_device *dev, int mtu) ...@@ -1780,7 +1780,7 @@ static int xl_change_mtu(struct net_device *dev, int mtu)
static void __devexit xl_remove_one (struct pci_dev *pdev) static void __devexit xl_remove_one (struct pci_dev *pdev)
{ {
struct net_device *dev = pdev->driver_data; struct net_device *dev = pci_get_drvdata(pdev);
struct xl_private *xl_priv=(struct xl_private *)dev->priv; struct xl_private *xl_priv=(struct xl_private *)dev->priv;
unregister_trdev(dev); unregister_trdev(dev);
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
* 11/05/01 - Restructured the interrupt function, added delays, reduced the * 11/05/01 - Restructured the interrupt function, added delays, reduced the
* the number of TX descriptors to 1, which together can prevent * the number of TX descriptors to 1, which together can prevent
* the card from locking up the box - <yoder1@us.ibm.com> * the card from locking up the box - <yoder1@us.ibm.com>
* 09/27/02 - New PCI interface + bug fix. - <yoder1@us.ibm.com>
* *
* To Do: * To Do:
* *
...@@ -136,7 +137,7 @@ ...@@ -136,7 +137,7 @@
*/ */
static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n" static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
" v0.5.1 03/04/02 - Kent Yoder"; " v0.5.2 09/30/02 - Kent Yoder";
static struct pci_device_id streamer_pci_tbl[] __initdata = { static struct pci_device_id streamer_pci_tbl[] __initdata = {
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,}, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
...@@ -250,6 +251,12 @@ static int __devinit streamer_init_one(struct pci_dev *pdev, ...@@ -250,6 +251,12 @@ static int __devinit streamer_init_one(struct pci_dev *pdev,
dev_streamer=streamer_priv; dev_streamer=streamer_priv;
#endif #endif
#endif #endif
if(pci_set_dma_mask(pdev, 0xFFFFFFFF)) {
printk(KERN_ERR "%s: No suitable PCI mapping available.\n", dev->name);
rc = -ENODEV;
goto err_out;
}
if (pci_enable_device(pdev)) { if (pci_enable_device(pdev)) {
printk(KERN_ERR "lanstreamer: unable to enable pci device\n"); printk(KERN_ERR "lanstreamer: unable to enable pci device\n");
...@@ -481,9 +488,11 @@ static int streamer_reset(struct net_device *dev) ...@@ -481,9 +488,11 @@ static int streamer_reset(struct net_device *dev)
data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc); data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc);
rx_ring->forward=0; rx_ring->forward=0;
rx_ring->status=0; rx_ring->status=0;
rx_ring->buffer=virt_to_bus(data); rx_ring->buffer=cpu_to_le32(pci_map_single(streamer_priv->pci_dev, data,
512, PCI_DMA_FROMDEVICE));
rx_ring->framelen_buflen=512; rx_ring->framelen_buflen=512;
writel(virt_to_bus(rx_ring),streamer_mmio+RXBDA); writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, rx_ring, 512, PCI_DMA_FROMDEVICE)),
streamer_mmio+RXBDA);
} }
#if STREAMER_DEBUG #if STREAMER_DEBUG
...@@ -499,6 +508,8 @@ static int streamer_reset(struct net_device *dev) ...@@ -499,6 +508,8 @@ static int streamer_reset(struct net_device *dev)
printk(KERN_ERR printk(KERN_ERR
"IBM PCI tokenring card not responding\n"); "IBM PCI tokenring card not responding\n");
release_region(dev->base_addr, STREAMER_IO_SPACE); release_region(dev->base_addr, STREAMER_IO_SPACE);
if (skb)
dev_kfree_skb(skb);
return -1; return -1;
} }
} }
...@@ -773,14 +784,19 @@ static int streamer_open(struct net_device *dev) ...@@ -773,14 +784,19 @@ static int streamer_open(struct net_device *dev)
skb->dev = dev; skb->dev = dev;
streamer_priv->streamer_rx_ring[i].forward = virt_to_bus(&streamer_priv->streamer_rx_ring[i + 1]); streamer_priv->streamer_rx_ring[i].forward =
cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[i + 1],
sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE));
streamer_priv->streamer_rx_ring[i].status = 0; streamer_priv->streamer_rx_ring[i].status = 0;
streamer_priv->streamer_rx_ring[i].buffer = virt_to_bus(skb->data); streamer_priv->streamer_rx_ring[i].buffer =
cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data,
streamer_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
streamer_priv->streamer_rx_ring[i].framelen_buflen = streamer_priv->pkt_buf_sz; streamer_priv->streamer_rx_ring[i].framelen_buflen = streamer_priv->pkt_buf_sz;
streamer_priv->rx_ring_skb[i] = skb; streamer_priv->rx_ring_skb[i] = skb;
} }
streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1].forward = streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1].forward =
virt_to_bus(&streamer_priv->streamer_rx_ring[0]); cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0],
sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE));
if (i == 0) { if (i == 0) {
printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n", dev->name); printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n", dev->name);
...@@ -790,8 +806,12 @@ static int streamer_open(struct net_device *dev) ...@@ -790,8 +806,12 @@ static int streamer_open(struct net_device *dev)
streamer_priv->rx_ring_last_received = STREAMER_RX_RING_SIZE - 1; /* last processed rx status */ streamer_priv->rx_ring_last_received = STREAMER_RX_RING_SIZE - 1; /* last processed rx status */
writel(virt_to_bus(&streamer_priv->streamer_rx_ring[0]), streamer_mmio + RXBDA); writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0],
writel(virt_to_bus(&streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1]), streamer_mmio + RXLBDA); sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)),
streamer_mmio + RXBDA);
writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1],
sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)),
streamer_mmio + RXLBDA);
/* set bus master interrupt event mask */ /* set bus master interrupt event mask */
writew(MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK); writew(MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK);
...@@ -807,7 +827,10 @@ static int streamer_open(struct net_device *dev) ...@@ -807,7 +827,10 @@ static int streamer_open(struct net_device *dev)
writew(~BMCTL_TX2_DIS, streamer_mmio + BMCTL_RUM); /* Enables TX channel 2 */ writew(~BMCTL_TX2_DIS, streamer_mmio + BMCTL_RUM); /* Enables TX channel 2 */
for (i = 0; i < STREAMER_TX_RING_SIZE; i++) { for (i = 0; i < STREAMER_TX_RING_SIZE; i++) {
streamer_priv->streamer_tx_ring[i].forward = virt_to_bus(&streamer_priv->streamer_tx_ring[i + 1]); streamer_priv->streamer_tx_ring[i].forward = cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
&streamer_priv->streamer_tx_ring[i + 1],
sizeof(struct streamer_tx_desc),
PCI_DMA_TODEVICE));
streamer_priv->streamer_tx_ring[i].status = 0; streamer_priv->streamer_tx_ring[i].status = 0;
streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0; streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0;
streamer_priv->streamer_tx_ring[i].buffer = 0; streamer_priv->streamer_tx_ring[i].buffer = 0;
...@@ -817,7 +840,8 @@ static int streamer_open(struct net_device *dev) ...@@ -817,7 +840,8 @@ static int streamer_open(struct net_device *dev)
streamer_priv->streamer_tx_ring[i].rsvd3 = 0; streamer_priv->streamer_tx_ring[i].rsvd3 = 0;
} }
streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward = streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward =
virt_to_bus(&streamer_priv->streamer_tx_ring[0]); cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_tx_ring[0],
sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE));
streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE; streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE;
streamer_priv->tx_ring_free = 0; /* next entry in tx ring to use */ streamer_priv->tx_ring_free = 0; /* next entry in tx ring to use */
...@@ -915,6 +939,11 @@ static void streamer_rx(struct net_device *dev) ...@@ -915,6 +939,11 @@ static void streamer_rx(struct net_device *dev)
skb->dev = dev; skb->dev = dev;
if (buffer_cnt == 1) { if (buffer_cnt == 1) {
/* release the DMA mapping */
pci_unmap_single(streamer_priv->pci_dev,
le32_to_cpu(streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer),
streamer_priv->pkt_buf_sz,
PCI_DMA_FROMDEVICE);
skb2 = streamer_priv->rx_ring_skb[rx_ring_last_received]; skb2 = streamer_priv->rx_ring_skb[rx_ring_last_received];
#if STREAMER_DEBUG_PACKETS #if STREAMER_DEBUG_PACKETS
{ {
...@@ -934,20 +963,29 @@ static void streamer_rx(struct net_device *dev) ...@@ -934,20 +963,29 @@ static void streamer_rx(struct net_device *dev)
/* recycle this descriptor */ /* recycle this descriptor */
streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0;
streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz;
streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer = virt_to_bus(skb->data); streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer =
streamer_priv-> rx_ring_skb[rx_ring_last_received] = skb; cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, streamer_priv->pkt_buf_sz,
PCI_DMA_FROMDEVICE));
streamer_priv->rx_ring_skb[rx_ring_last_received] = skb;
/* place recycled descriptor back on the adapter */ /* place recycled descriptor back on the adapter */
writel(virt_to_bus(&streamer_priv->streamer_rx_ring[rx_ring_last_received]),streamer_mmio + RXLBDA); writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
&streamer_priv->streamer_rx_ring[rx_ring_last_received],
sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)),
streamer_mmio + RXLBDA);
/* pass the received skb up to the protocol */ /* pass the received skb up to the protocol */
netif_rx(skb2); netif_rx(skb2);
} else { } else {
do { /* Walk the buffers */ do { /* Walk the buffers */
memcpy(skb_put(skb, length),bus_to_virt(rx_desc->buffer), length); /* copy this fragment */ pci_unmap_single(streamer_priv->pci_dev, le32_to_cpu(rx_desc->buffer), length, PCI_DMA_FROMDEVICE),
memcpy(skb_put(skb, length), (void *)rx_desc->buffer, length); /* copy this fragment */
streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0; streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0;
streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz; streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz;
/* give descriptor back to the adapter */ /* give descriptor back to the adapter */
writel(virt_to_bus(&streamer_priv->streamer_rx_ring[rx_ring_last_received]), streamer_mmio + RXLBDA); writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
&streamer_priv->streamer_rx_ring[rx_ring_last_received],
length, PCI_DMA_FROMDEVICE)),
streamer_mmio + RXLBDA);
if (rx_desc->status & 0x80000000) if (rx_desc->status & 0x80000000)
break; /* this descriptor completes the frame */ break; /* this descriptor completes the frame */
...@@ -1114,7 +1152,8 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1114,7 +1152,8 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
if (streamer_priv->free_tx_ring_entries) { if (streamer_priv->free_tx_ring_entries) {
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = virt_to_bus(skb->data); streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer =
cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE));
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0;
...@@ -1135,7 +1174,10 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1135,7 +1174,10 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
} }
#endif #endif
writel(virt_to_bus (&streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free]),streamer_mmio + TX2LFDA); writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
&streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free],
sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)),
streamer_mmio + TX2LFDA);
(void)readl(streamer_mmio + TX2LFDA); (void)readl(streamer_mmio + TX2LFDA);
streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1); streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);
......
...@@ -210,6 +210,7 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { ...@@ -210,6 +210,7 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = {
{ 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
{ 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
{ 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
{ 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
{ 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
{ 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
...@@ -1409,7 +1410,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, ...@@ -1409,7 +1410,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
tp->timer.function = tulip_tbl[tp->chip_id].media_timer; tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
dev->base_addr = ioaddr; dev->base_addr = ioaddr;
dev->irq = irq;
#ifdef CONFIG_TULIP_MWI #ifdef CONFIG_TULIP_MWI
if (!force_csr0 && (tp->flags & HAS_PCI_MWI)) if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
...@@ -1553,6 +1553,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, ...@@ -1553,6 +1553,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
last_phys_addr[i] = dev->dev_addr[i]; last_phys_addr[i] = dev->dev_addr[i];
last_irq = irq; last_irq = irq;
dev->irq = irq;
/* The lower four bits are the media type. */ /* The lower four bits are the media type. */
if (board_idx >= 0 && board_idx < MAX_UNITS) { if (board_idx >= 0 && board_idx < MAX_UNITS) {
......
...@@ -299,7 +299,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -299,7 +299,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
dev->get_stats = &xircom_get_stats; dev->get_stats = &xircom_get_stats;
dev->priv = private; dev->priv = private;
dev->do_ioctl = &private_ioctl; dev->do_ioctl = &private_ioctl;
pdev->driver_data = dev; pci_set_drvdata(pdev, dev);
/* start the transmitter to get a heartbeat */ /* start the transmitter to get a heartbeat */
...@@ -326,7 +326,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -326,7 +326,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
*/ */
static void __devexit xircom_remove(struct pci_dev *pdev) static void __devexit xircom_remove(struct pci_dev *pdev)
{ {
struct net_device *dev = pdev->driver_data; struct net_device *dev = pci_get_drvdata(pdev);
struct xircom_private *card; struct xircom_private *card;
enter("xircom_remove"); enter("xircom_remove");
if (dev!=NULL) { if (dev!=NULL) {
......
...@@ -3556,7 +3556,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3556,7 +3556,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#endif #endif
/* Set PCI drv pointer to the card structure */ /* Set PCI drv pointer to the card structure */
pdev->driver_data = card; pci_set_drvdata(pdev, card);
/* Set board type */ /* Set board type */
switch (device_id) { switch (device_id) {
...@@ -3631,7 +3631,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3631,7 +3631,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
static void __devexit cpc_remove_one(struct pci_dev *pdev) static void __devexit cpc_remove_one(struct pci_dev *pdev)
{ {
pc300_t *card = (pc300_t *) pdev->driver_data; pc300_t *card = pci_get_drvdata(pdev);
if (card->hw.rambase != 0) { if (card->hw.rambase != 0) {
int i; int i;
......
...@@ -122,6 +122,7 @@ inline void bio_init(struct bio *bio) ...@@ -122,6 +122,7 @@ inline void bio_init(struct bio *bio)
bio->bi_max_vecs = 0; bio->bi_max_vecs = 0;
bio->bi_end_io = NULL; bio->bi_end_io = NULL;
atomic_set(&bio->bi_cnt, 1); atomic_set(&bio->bi_cnt, 1);
bio->bi_private = NULL;
} }
/** /**
...@@ -354,7 +355,7 @@ int bio_get_nr_vecs(struct block_device *bdev) ...@@ -354,7 +355,7 @@ int bio_get_nr_vecs(struct block_device *bdev)
request_queue_t *q = bdev_get_queue(bdev); request_queue_t *q = bdev_get_queue(bdev);
int nr_pages; int nr_pages;
nr_pages = q->max_sectors >> (PAGE_SHIFT - 9); nr_pages = ((q->max_sectors << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT;
if (nr_pages > q->max_phys_segments) if (nr_pages > q->max_phys_segments)
nr_pages = q->max_phys_segments; nr_pages = q->max_phys_segments;
if (nr_pages > q->max_hw_segments) if (nr_pages > q->max_hw_segments)
...@@ -385,13 +386,13 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, ...@@ -385,13 +386,13 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
* cloned bio must not modify vec list * cloned bio must not modify vec list
*/ */
if (unlikely(bio_flagged(bio, BIO_CLONED))) if (unlikely(bio_flagged(bio, BIO_CLONED)))
return 1; return 0;
if (bio->bi_vcnt >= bio->bi_max_vecs) if (bio->bi_vcnt >= bio->bi_max_vecs)
return 1; return 0;
if (((bio->bi_size + len) >> 9) > q->max_sectors) if (((bio->bi_size + len) >> 9) > q->max_sectors)
return 1; return 0;
/* /*
* we might loose a segment or two here, but rather that than * we might loose a segment or two here, but rather that than
...@@ -404,7 +405,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, ...@@ -404,7 +405,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
if (fail_segments) { if (fail_segments) {
if (retried_segments) if (retried_segments)
return 1; return 0;
bio->bi_flags &= ~(1 << BIO_SEG_VALID); bio->bi_flags &= ~(1 << BIO_SEG_VALID);
retried_segments = 1; retried_segments = 1;
...@@ -425,20 +426,151 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, ...@@ -425,20 +426,151 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
* depending on offset), it can specify a merge_bvec_fn in the * depending on offset), it can specify a merge_bvec_fn in the
* queue to get further control * queue to get further control
*/ */
if (q->merge_bvec_fn && q->merge_bvec_fn(q, bio, bvec)) { if (q->merge_bvec_fn) {
bvec->bv_page = NULL; /*
bvec->bv_len = 0; * merge_bvec_fn() returns number of bytes it can accept
bvec->bv_offset = 0; * at this offset
return 1; */
if (q->merge_bvec_fn(q, bio, bvec) < len) {
bvec->bv_page = NULL;
bvec->bv_len = 0;
bvec->bv_offset = 0;
return 0;
}
} }
bio->bi_vcnt++; bio->bi_vcnt++;
bio->bi_phys_segments++; bio->bi_phys_segments++;
bio->bi_hw_segments++; bio->bi_hw_segments++;
bio->bi_size += len; bio->bi_size += len;
return 0; return len;
} }
/**
* bio_map_user - map user address into bio
* @bdev: destination block device
* @uaddr: start of user address
* @len: length in bytes
* @write_to_vm: bool indicating writing to pages or not
*
* Map the user space address into a bio suitable for io to a block
* device. Caller should check the size of the returned bio, we might
* not have mapped the entire range specified.
*/
struct bio *bio_map_user(struct block_device *bdev, unsigned long uaddr,
unsigned int len, int write_to_vm)
{
unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned long start = uaddr >> PAGE_SHIFT;
const int nr_pages = end - start;
request_queue_t *q = bdev_get_queue(bdev);
int ret, offset, i;
struct page **pages;
struct bio *bio;
/*
* transfer and buffer must be aligned to at least hardsector
* size for now, in the future we can relax this restriction
*/
if ((uaddr & queue_dma_alignment(q)) || (len & queue_dma_alignment(q)))
return NULL;
bio = bio_alloc(GFP_KERNEL, nr_pages);
if (!bio)
return NULL;
pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL);
if (!pages)
goto out;
down_read(&current->mm->mmap_sem);
ret = get_user_pages(current, current->mm, uaddr, nr_pages,
write_to_vm, 0, pages, NULL);
up_read(&current->mm->mmap_sem);
if (ret < nr_pages)
goto out;
bio->bi_bdev = bdev;
offset = uaddr & ~PAGE_MASK;
for (i = 0; i < nr_pages; i++) {
unsigned int bytes = PAGE_SIZE - offset;
if (len <= 0)
break;
if (bytes > len)
bytes = len;
/*
* sorry...
*/
if (bio_add_page(bio, pages[i], bytes, offset) < bytes)
break;
len -= bytes;
offset = 0;
}
/*
* release the pages we didn't map into the bio, if any
*/
while (i < nr_pages)
page_cache_release(pages[i++]);
kfree(pages);
/*
* check if the mapped pages need bouncing for an isa host.
*/
blk_queue_bounce(q, &bio);
return bio;
out:
kfree(pages);
bio_put(bio);
return NULL;
}
/**
* bio_unmap_user - unmap a bio
* @bio: the bio being unmapped
* @write_to_vm: bool indicating whether pages were written to
*
* Unmap a bio previously mapped by bio_map_user(). The @write_to_vm
* must be the same as passed into bio_map_user(). Must be called with
* a process context.
*/
void bio_unmap_user(struct bio *bio, int write_to_vm)
{
struct bio_vec *bvec;
int i;
/*
* find original bio if it was bounced
*/
if (bio->bi_private) {
/*
* someone stole our bio, must not happen
*/
BUG_ON(!bio_flagged(bio, BIO_BOUNCED));
bio = bio->bi_private;
}
/*
* make sure we dirty pages we wrote to
*/
__bio_for_each_segment(bvec, bio, i, 0) {
if (write_to_vm)
set_page_dirty(bvec->bv_page);
page_cache_release(bvec->bv_page);
}
bio_put(bio);
}
/** /**
* bio_endio - end I/O on a bio * bio_endio - end I/O on a bio
* @bio: bio * @bio: bio
...@@ -446,14 +578,15 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, ...@@ -446,14 +578,15 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
* @error: error, if any * @error: error, if any
* *
* Description: * Description:
* bio_endio() will end I/O @bytes_done number of bytes. This may be just * bio_endio() will end I/O on @bytes_done number of bytes. This may be
* a partial part of the bio, or it may be the whole bio. bio_endio() is * just a partial part of the bio, or it may be the whole bio. bio_endio()
* the preferred way to end I/O on a bio, it takes care of decrementing * is the preferred way to end I/O on a bio, it takes care of decrementing
* bi_size and clearing BIO_UPTODATE on error. @error is 0 on success, and * bi_size and clearing BIO_UPTODATE on error. @error is 0 on success, and
* and one of the established -Exxxx (-EIO, for instance) error values in * and one of the established -Exxxx (-EIO, for instance) error values in
* case something went wrong. * case something went wrong. Noone should call bi_end_io() directly on
* a bio unless they own it and thus know that it has an end_io function.
**/ **/
int bio_endio(struct bio *bio, unsigned int bytes_done, int error) void bio_endio(struct bio *bio, unsigned int bytes_done, int error)
{ {
if (error) if (error)
clear_bit(BIO_UPTODATE, &bio->bi_flags); clear_bit(BIO_UPTODATE, &bio->bi_flags);
...@@ -465,7 +598,9 @@ int bio_endio(struct bio *bio, unsigned int bytes_done, int error) ...@@ -465,7 +598,9 @@ int bio_endio(struct bio *bio, unsigned int bytes_done, int error)
} }
bio->bi_size -= bytes_done; bio->bi_size -= bytes_done;
return bio->bi_end_io(bio, bytes_done, error);
if (bio->bi_end_io)
bio->bi_end_io(bio, bytes_done, error);
} }
static void __init biovec_init_pools(void) static void __init biovec_init_pools(void)
...@@ -537,7 +672,7 @@ static int __init init_bio(void) ...@@ -537,7 +672,7 @@ static int __init init_bio(void)
return 0; return 0;
} }
module_init(init_bio); subsys_initcall(init_bio);
EXPORT_SYMBOL(bio_alloc); EXPORT_SYMBOL(bio_alloc);
EXPORT_SYMBOL(bio_put); EXPORT_SYMBOL(bio_put);
...@@ -550,3 +685,5 @@ EXPORT_SYMBOL(bio_phys_segments); ...@@ -550,3 +685,5 @@ EXPORT_SYMBOL(bio_phys_segments);
EXPORT_SYMBOL(bio_hw_segments); EXPORT_SYMBOL(bio_hw_segments);
EXPORT_SYMBOL(bio_add_page); EXPORT_SYMBOL(bio_add_page);
EXPORT_SYMBOL(bio_get_nr_vecs); EXPORT_SYMBOL(bio_get_nr_vecs);
EXPORT_SYMBOL(bio_map_user);
EXPORT_SYMBOL(bio_unmap_user);
...@@ -417,12 +417,12 @@ dio_bio_add_page(struct dio *dio, struct page *page, ...@@ -417,12 +417,12 @@ dio_bio_add_page(struct dio *dio, struct page *page,
/* Take a ref against the page each time it is placed into a BIO */ /* Take a ref against the page each time it is placed into a BIO */
page_cache_get(page); page_cache_get(page);
if (bio_add_page(dio->bio, page, bv_len, bv_offset)) { if (bio_add_page(dio->bio, page, bv_len, bv_offset) < bv_len) {
dio_bio_submit(dio); dio_bio_submit(dio);
ret = dio_new_bio(dio, blkno); ret = dio_new_bio(dio, blkno);
if (ret == 0) { if (ret == 0) {
ret = bio_add_page(dio->bio, page, bv_len, bv_offset); ret = bio_add_page(dio->bio, page, bv_len, bv_offset);
BUG_ON(ret != 0); BUG_ON(ret < bv_len);
} else { } else {
/* The page didn't make it into a BIO */ /* The page didn't make it into a BIO */
page_cache_release(page); page_cache_release(page);
......
...@@ -176,6 +176,7 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages, ...@@ -176,6 +176,7 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
unsigned first_hole = blocks_per_page; unsigned first_hole = blocks_per_page;
struct block_device *bdev = NULL; struct block_device *bdev = NULL;
struct buffer_head bh; struct buffer_head bh;
int length;
if (page_has_buffers(page)) if (page_has_buffers(page))
goto confused; goto confused;
...@@ -233,7 +234,8 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages, ...@@ -233,7 +234,8 @@ do_mpage_readpage(struct bio *bio, struct page *page, unsigned nr_pages,
goto confused; goto confused;
} }
if (bio_add_page(bio, page, first_hole << blkbits, 0)) { length = first_hole << blkbits;
if (bio_add_page(bio, page, length, 0) < length) {
bio = mpage_bio_submit(READ, bio); bio = mpage_bio_submit(READ, bio);
goto alloc_new; goto alloc_new;
} }
...@@ -334,6 +336,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block, ...@@ -334,6 +336,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
int boundary = 0; int boundary = 0;
sector_t boundary_block = 0; sector_t boundary_block = 0;
struct block_device *boundary_bdev = NULL; struct block_device *boundary_bdev = NULL;
int length;
if (page_has_buffers(page)) { if (page_has_buffers(page)) {
struct buffer_head *head = page_buffers(page); struct buffer_head *head = page_buffers(page);
...@@ -467,7 +470,8 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block, ...@@ -467,7 +470,8 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
try_to_free_buffers(page); try_to_free_buffers(page);
} }
if (bio_add_page(bio, page, first_unmapped << blkbits, 0)) { length = first_unmapped << blkbits;
if (bio_add_page(bio, page, length, 0) < length) {
bio = mpage_bio_submit(WRITE, bio); bio = mpage_bio_submit(WRITE, bio);
goto alloc_new; goto alloc_new;
} }
......
...@@ -1448,7 +1448,7 @@ pagebuf_iorequest( /* start real I/O */ ...@@ -1448,7 +1448,7 @@ pagebuf_iorequest( /* start real I/O */
if (nbytes > size) if (nbytes > size)
nbytes = size; nbytes = size;
if (bio_add_page(bio, pb->pb_pages[map_i], nbytes, offset)) if (bio_add_page(bio, pb->pb_pages[map_i], nbytes, offset) < nbytes)
break; break;
offset = 0; offset = 0;
......
...@@ -70,6 +70,7 @@ static __inline__ void ide_init_default_hwifs(void) ...@@ -70,6 +70,7 @@ static __inline__ void ide_init_default_hwifs(void)
int index; int index;
for(index = 0; index < MAX_HWIFS; index++) { for(index = 0; index < MAX_HWIFS; index++) {
memset(&hw, 0, sizeof hw);
ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
hw.irq = ide_default_irq(ide_default_io_base(index)); hw.irq = ide_default_irq(ide_default_io_base(index));
ide_register_hw(&hw, NULL); ide_register_hw(&hw, NULL);
......
...@@ -132,6 +132,7 @@ struct bio { ...@@ -132,6 +132,7 @@ struct bio {
#define bio_page(bio) bio_iovec((bio))->bv_page #define bio_page(bio) bio_iovec((bio))->bv_page
#define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_offset(bio) bio_iovec((bio))->bv_offset
#define bio_sectors(bio) ((bio)->bi_size >> 9) #define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio))) #define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) #define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
...@@ -202,7 +203,7 @@ struct bio { ...@@ -202,7 +203,7 @@ struct bio {
extern struct bio *bio_alloc(int, int); extern struct bio *bio_alloc(int, int);
extern void bio_put(struct bio *); extern void bio_put(struct bio *);
extern int bio_endio(struct bio *, unsigned int, int); extern void bio_endio(struct bio *, unsigned int, int);
struct request_queue; struct request_queue;
extern inline int bio_phys_segments(struct request_queue *, struct bio *); extern inline int bio_phys_segments(struct request_queue *, struct bio *);
extern inline int bio_hw_segments(struct request_queue *, struct bio *); extern inline int bio_hw_segments(struct request_queue *, struct bio *);
...@@ -215,6 +216,9 @@ extern inline void bio_init(struct bio *); ...@@ -215,6 +216,9 @@ extern inline void bio_init(struct bio *);
extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int); extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
extern int bio_get_nr_vecs(struct block_device *); extern int bio_get_nr_vecs(struct block_device *);
extern struct bio *bio_map_user(struct block_device *, unsigned long,
unsigned int, int);
extern void bio_unmap_user(struct bio *, int);
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
/* /*
......
...@@ -39,12 +39,15 @@ void initrd_init(void); ...@@ -39,12 +39,15 @@ void initrd_init(void);
*/ */
extern int end_that_request_first(struct request *, int, int); extern int end_that_request_first(struct request *, int, int);
extern int end_that_request_chunk(struct request *, int, int);
extern void end_that_request_last(struct request *); extern void end_that_request_last(struct request *);
struct request *elv_next_request(request_queue_t *q); struct request *elv_next_request(request_queue_t *q);
static inline void blkdev_dequeue_request(struct request *req) static inline void blkdev_dequeue_request(struct request *req)
{ {
list_del(&req->queuelist); BUG_ON(list_empty(&req->queuelist));
list_del_init(&req->queuelist);
if (req->q) if (req->q)
elv_remove_request(req->q, req); elv_remove_request(req->q, req);
......
...@@ -26,6 +26,8 @@ struct request { ...@@ -26,6 +26,8 @@ struct request {
struct list_head queuelist; /* looking for ->queue? you must _not_ struct list_head queuelist; /* looking for ->queue? you must _not_
* access it directly, use * access it directly, use
* blkdev_dequeue_request! */ * blkdev_dequeue_request! */
int ref_count;
void *elevator_private; void *elevator_private;
unsigned char cmd[16]; unsigned char cmd[16];
...@@ -64,7 +66,10 @@ struct request { ...@@ -64,7 +66,10 @@ struct request {
/* For packet commands */ /* For packet commands */
unsigned int data_len; unsigned int data_len;
void *data, *sense; void *data;
unsigned int sense_len;
void *sense;
unsigned int timeout; unsigned int timeout;
struct completion *waiting; struct completion *waiting;
...@@ -150,12 +155,6 @@ struct blk_queue_tag { ...@@ -150,12 +155,6 @@ struct blk_queue_tag {
int max_depth; int max_depth;
}; };
/*
* Default nr free requests per queue, ll_rw_blk will scale it down
* according to available RAM at init time
*/
#define QUEUE_NR_REQUESTS 8192
struct request_queue struct request_queue
{ {
/* /*
...@@ -220,6 +219,12 @@ struct request_queue ...@@ -220,6 +219,12 @@ struct request_queue
wait_queue_head_t queue_wait; wait_queue_head_t queue_wait;
struct blk_queue_tag *queue_tags; struct blk_queue_tag *queue_tags;
/*
* sg stuff
*/
unsigned int sg_timeout;
unsigned int sg_reserved_size;
}; };
#define RQ_INACTIVE (-1) #define RQ_INACTIVE (-1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment