Commit 2b5d343e authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://jfs.bkbits.net/linux-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 3aa8e204 3c4cb3be
...@@ -137,8 +137,24 @@ deadline_find_hash(struct deadline_data *dd, sector_t offset) ...@@ -137,8 +137,24 @@ deadline_find_hash(struct deadline_data *dd, sector_t offset)
return rq; return rq;
} }
static sector_t deadline_get_last_sector(struct deadline_data *dd)
{
sector_t last_sec = dd->last_sector;
/*
* if dispatch is non-empty, disregard last_sector and check last one
*/
if (!list_empty(dd->dispatch)) {
struct request *__rq = list_entry_rq(dd->dispatch->prev);
last_sec = __rq->sector + __rq->nr_sectors;
}
return last_sec;
}
static int static int
deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
{ {
struct deadline_data *dd = q->elevator.elevator_data; struct deadline_data *dd = q->elevator.elevator_data;
const int data_dir = bio_data_dir(bio); const int data_dir = bio_data_dir(bio);
...@@ -150,9 +166,11 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -150,9 +166,11 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
/* /*
* try last_merge to avoid going to hash * try last_merge to avoid going to hash
*/ */
ret = elv_try_last_merge(q, req, bio); ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) if (ret != ELEVATOR_NO_MERGE) {
*insert = q->last_merge;
goto out; goto out;
}
/* /*
* see if the merge hash can satisfy a back merge * see if the merge hash can satisfy a back merge
...@@ -161,12 +179,15 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -161,12 +179,15 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
if (elv_rq_merge_ok(__rq, bio)) { if (elv_rq_merge_ok(__rq, bio)) {
*req = __rq; *insert = &__rq->queuelist;
ret = ELEVATOR_BACK_MERGE; ret = ELEVATOR_BACK_MERGE;
goto out; goto out;
} }
} }
/*
* scan list from back to find insertion point.
*/
entry = sort_list = &dd->sort_list[data_dir]; entry = sort_list = &dd->sort_list[data_dir];
while ((entry = entry->prev) != sort_list) { while ((entry = entry->prev) != sort_list) {
__rq = list_entry_rq(entry); __rq = list_entry_rq(entry);
...@@ -177,8 +198,8 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -177,8 +198,8 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
if (!(__rq->flags & REQ_CMD)) if (!(__rq->flags & REQ_CMD))
continue; continue;
if (!*req && bio_rq_in_between(bio, __rq, sort_list)) if (!*insert && bio_rq_in_between(bio, __rq, sort_list))
*req = __rq; *insert = &__rq->queuelist;
if (__rq->flags & REQ_BARRIER) if (__rq->flags & REQ_BARRIER)
break; break;
...@@ -189,12 +210,23 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) ...@@ -189,12 +210,23 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
if (__rq->sector - bio_sectors(bio) == bio->bi_sector) { if (__rq->sector - bio_sectors(bio) == bio->bi_sector) {
ret = elv_try_merge(__rq, bio); ret = elv_try_merge(__rq, bio);
if (ret != ELEVATOR_NO_MERGE) { if (ret != ELEVATOR_NO_MERGE) {
*req = __rq; *insert = &__rq->queuelist;
break; break;
} }
} }
} }
/*
* no insertion point found, check the very front
*/
if (!*insert && !list_empty(sort_list)) {
__rq = list_entry_rq(sort_list->next);
if (bio->bi_sector + bio_sectors(bio) < __rq->sector &&
bio->bi_sector > deadline_get_last_sector(dd))
*insert = sort_list;
}
out: out:
return ret; return ret;
} }
...@@ -254,18 +286,9 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq) ...@@ -254,18 +286,9 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
static void deadline_move_requests(struct deadline_data *dd, struct request *rq) static void deadline_move_requests(struct deadline_data *dd, struct request *rq)
{ {
struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)]; struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)];
sector_t last_sec = dd->last_sector; sector_t last_sec = deadline_get_last_sector(dd);
int batch_count = dd->fifo_batch; int batch_count = dd->fifo_batch;
/*
* if dispatch is non-empty, disregard last_sector and check last one
*/
if (!list_empty(dd->dispatch)) {
struct request *__rq = list_entry_rq(dd->dispatch->prev);
last_sec = __rq->sector + __rq->nr_sectors;
}
do { do {
struct list_head *nxt = rq->queuelist.next; struct list_head *nxt = rq->queuelist.next;
int this_rq_cost; int this_rq_cost;
......
...@@ -136,8 +136,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio) ...@@ -136,8 +136,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
return ret; return ret;
} }
inline int elv_try_last_merge(request_queue_t *q, struct request **req, inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
struct bio *bio)
{ {
int ret = ELEVATOR_NO_MERGE; int ret = ELEVATOR_NO_MERGE;
...@@ -150,8 +149,8 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req, ...@@ -150,8 +149,8 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req,
if (!rq_mergeable(__rq)) if (!rq_mergeable(__rq))
q->last_merge = NULL; q->last_merge = NULL;
else if ((ret = elv_try_merge(__rq, bio))) else
*req = __rq; ret = elv_try_merge(__rq, bio);
} }
return ret; return ret;
...@@ -162,15 +161,17 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req, ...@@ -162,15 +161,17 @@ inline int elv_try_last_merge(request_queue_t *q, struct request **req,
* *
* See if we can find a request that this buffer can be coalesced with. * See if we can find a request that this buffer can be coalesced with.
*/ */
int elevator_noop_merge(request_queue_t *q, struct request **req, int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
struct bio *bio) struct bio *bio)
{ {
struct list_head *entry = &q->queue_head; struct list_head *entry = &q->queue_head;
struct request *__rq; struct request *__rq;
int ret; int ret;
if ((ret = elv_try_last_merge(q, req, bio))) if ((ret = elv_try_last_merge(q, bio))) {
*insert = q->last_merge;
return ret; return ret;
}
while ((entry = entry->prev) != &q->queue_head) { while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry); __rq = list_entry_rq(entry);
...@@ -182,7 +183,7 @@ int elevator_noop_merge(request_queue_t *q, struct request **req, ...@@ -182,7 +183,7 @@ int elevator_noop_merge(request_queue_t *q, struct request **req,
continue; continue;
if ((ret = elv_try_merge(__rq, bio))) { if ((ret = elv_try_merge(__rq, bio))) {
*req = __rq; *insert = &__rq->queuelist;
q->last_merge = &__rq->queuelist; q->last_merge = &__rq->queuelist;
return ret; return ret;
} }
...@@ -240,12 +241,12 @@ int elevator_global_init(void) ...@@ -240,12 +241,12 @@ int elevator_global_init(void)
return 0; return 0;
} }
int elv_merge(request_queue_t *q, struct request **rq, struct bio *bio) int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio)
{ {
elevator_t *e = &q->elevator; elevator_t *e = &q->elevator;
if (e->elevator_merge_fn) if (e->elevator_merge_fn)
return e->elevator_merge_fn(q, rq, bio); return e->elevator_merge_fn(q, entry, bio);
return ELEVATOR_NO_MERGE; return ELEVATOR_NO_MERGE;
} }
......
...@@ -1583,7 +1583,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1583,7 +1583,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
again: again:
req = NULL;
insert_here = NULL; insert_here = NULL;
if (blk_queue_empty(q)) { if (blk_queue_empty(q)) {
...@@ -1593,10 +1592,13 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1593,10 +1592,13 @@ static int __make_request(request_queue_t *q, struct bio *bio)
if (barrier) if (barrier)
goto get_rq; goto get_rq;
el_ret = elv_merge(q, &req, bio); el_ret = elv_merge(q, &insert_here, bio);
switch (el_ret) { switch (el_ret) {
case ELEVATOR_BACK_MERGE: case ELEVATOR_BACK_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req)); BUG_ON(!rq_mergeable(req));
if (!q->back_merge_fn(q, req, bio)) { if (!q->back_merge_fn(q, req, bio)) {
insert_here = &req->queuelist; insert_here = &req->queuelist;
break; break;
...@@ -1611,7 +1613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1611,7 +1613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
goto out; goto out;
case ELEVATOR_FRONT_MERGE: case ELEVATOR_FRONT_MERGE:
req = list_entry_rq(insert_here);
BUG_ON(!rq_mergeable(req)); BUG_ON(!rq_mergeable(req));
if (!q->front_merge_fn(q, req, bio)) { if (!q->front_merge_fn(q, req, bio)) {
insert_here = req->queuelist.prev; insert_here = req->queuelist.prev;
break; break;
...@@ -1638,13 +1643,6 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1638,13 +1643,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
* elevator says don't/can't merge. get new request * elevator says don't/can't merge. get new request
*/ */
case ELEVATOR_NO_MERGE: case ELEVATOR_NO_MERGE:
/*
* use elevator hints as to where to insert the
* request. if no hints, just add it to the back
* of the queue
*/
if (req)
insert_here = &req->queuelist;
break; break;
default: default:
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "i82092aa.h" #include "i82092aa.h"
#include "i82365.h" #include "i82365.h"
MODULE_LICENSE("GPL");
/* PCI core routines */ /* PCI core routines */
static struct pci_device_id i82092aa_pci_ids[] = { static struct pci_device_id i82092aa_pci_ids[] = {
{ {
......
...@@ -1048,11 +1048,19 @@ int isapnp_cfg_begin(int csn, int logdev) ...@@ -1048,11 +1048,19 @@ int isapnp_cfg_begin(int csn, int logdev)
isapnp_wait(); isapnp_wait();
isapnp_key(); isapnp_key();
isapnp_wake(csn); isapnp_wake(csn);
#if 1 /* to avoid malfunction when the isapnptools package is used */ #if 1
isapnp_set_rdp(); /* to avoid malfunction when the isapnptools package is used */
udelay(1000); /* delay 1000us */ /* we must set RDP to our value again */
write_address(0x01); /* it is possible to set RDP only in the isolation phase */
udelay(1000); /* delay 1000us */ /* Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
isapnp_write_byte(0x02, 0x04); /* clear CSN of card */
mdelay(2); /* is this necessary? */
isapnp_wake(csn); /* bring card into sleep state */
isapnp_wake(0); /* bring card into isolation state */
isapnp_set_rdp(); /* reset the RDP port */
udelay(1000); /* delay 1000us */
isapnp_write_byte(0x06, csn); /* reset CSN to previous value */
udelay(250); /* is this necessary? */
#endif #endif
if (logdev >= 0) if (logdev >= 0)
isapnp_device(logdev); isapnp_device(logdev);
......
...@@ -1459,10 +1459,8 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l) ...@@ -1459,10 +1459,8 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock *l)
break; break;
} }
out: out:
if (error) { locks_free_lock(file_lock);
locks_free_lock(file_lock);
}
return error; return error;
} }
...@@ -1601,11 +1599,8 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l) ...@@ -1601,11 +1599,8 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 *l)
break; break;
} }
out: out:
if (error) { locks_free_lock(file_lock);
locks_free_lock(file_lock);
}
return error; return error;
} }
#endif /* BITS_PER_LONG == 32 */ #endif /* BITS_PER_LONG == 32 */
......
#ifndef _LINUX_ELEVATOR_H #ifndef _LINUX_ELEVATOR_H
#define _LINUX_ELEVATOR_H #define _LINUX_ELEVATOR_H
typedef int (elevator_merge_fn) (request_queue_t *, struct request **, typedef int (elevator_merge_fn) (request_queue_t *, struct list_head **,
struct bio *); struct bio *);
typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *); typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
...@@ -42,7 +42,7 @@ struct elevator_s ...@@ -42,7 +42,7 @@ struct elevator_s
*/ */
extern void __elv_add_request(request_queue_t *, struct request *, extern void __elv_add_request(request_queue_t *, struct request *,
struct list_head *); struct list_head *);
extern int elv_merge(request_queue_t *, struct request **, struct bio *); extern int elv_merge(request_queue_t *, struct list_head **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *, extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *); struct request *);
extern void elv_merged_request(request_queue_t *, struct request *); extern void elv_merged_request(request_queue_t *, struct request *);
...@@ -78,7 +78,7 @@ extern void elevator_exit(request_queue_t *, elevator_t *); ...@@ -78,7 +78,7 @@ extern void elevator_exit(request_queue_t *, elevator_t *);
extern inline int bio_rq_in_between(struct bio *, struct request *, struct list_head *); extern inline int bio_rq_in_between(struct bio *, struct request *, struct list_head *);
extern inline int elv_rq_merge_ok(struct request *, struct bio *); extern inline int elv_rq_merge_ok(struct request *, struct bio *);
extern inline int elv_try_merge(struct request *, struct bio *); extern inline int elv_try_merge(struct request *, struct bio *);
extern inline int elv_try_last_merge(request_queue_t *, struct request **, struct bio *); extern inline int elv_try_last_merge(request_queue_t *, struct bio *);
/* /*
* Return values from elevator merger * Return values from elevator merger
......
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