diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 23:58:31 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 23:58:31 -0800 |
| commit | ef40d49b1f2892a4cbacd534403e45bcc5cb2694 (patch) | |
| tree | b18d60f42ea5d7311a53c742846028730f9487d1 /include/linux | |
| parent | cc5979c373db310084dc03b4cba091840dda2491 (diff) | |
v2.5.0.5 -> v2.5.0.6
- Jens Axboe: more bio stuff
- Coda compile fixes
- Nathan Laredo: stradis driver update
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bio.h | 27 | ||||
| -rw-r--r-- | include/linux/blk.h | 109 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 109 | ||||
| -rw-r--r-- | include/linux/coda_linux.h | 6 |
4 files changed, 140 insertions, 111 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index fc6335642dfb..550679134fd8 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -38,20 +38,26 @@ struct bio_vec { }; /* + * weee, c forward decl... + */ +struct bio; +typedef int (bio_end_io_t) (struct bio *, int); +typedef void (bio_destructor_t) (struct bio *); + +/* * main unit of I/O for the block layer and lower layers (ie drivers and * stacking drivers) */ struct bio { sector_t bi_sector; struct bio *bi_next; /* request queue link */ - atomic_t bi_cnt; /* pin count */ kdev_t bi_dev; /* will be block device */ unsigned long bi_flags; /* status, command, etc */ unsigned long bi_rw; /* bottom bits READ/WRITE, * top bits priority */ - unsigned int bi_vcnt; /* how may bio_vec's */ + unsigned int bi_vcnt; /* how many bio_vec's */ unsigned int bi_idx; /* current index into bvl_vec */ unsigned int bi_size; /* total size in bytes */ unsigned int bi_max; /* max bvl_vecs we can hold, @@ -59,10 +65,12 @@ struct bio { struct bio_vec *bi_io_vec; /* the actual vec list */ - int (*bi_end_io)(struct bio *bio, int nr_sectors); + bio_end_io_t *bi_end_io; + atomic_t bi_cnt; /* pin count */ + void *bi_private; - void (*bi_destructor)(struct bio *); /* destructor */ + bio_destructor_t *bi_destructor; /* destructor */ }; /* @@ -83,13 +91,13 @@ struct bio { */ #define BIO_RW 0 #define BIO_RW_AHEAD 1 -#define BIO_BARRIER 2 +#define BIO_RW_BARRIER 2 /* * various member access, note that bio_data should of course not be used * on highmem page vectors */ -#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(bio)->bi_idx])) +#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)])) #define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx) #define bio_page(bio) bio_iovec((bio))->bv_page #define __bio_offset(bio, idx) bio_iovec_idx((bio), (idx))->bv_offset @@ -118,17 +126,14 @@ struct bio { /* * merge helpers etc */ -#define __BVEC_END(bio) bio_iovec_idx((bio), (bio)->bi_idx - 1) +#define __BVEC_END(bio) bio_iovec_idx((bio), (bio)->bi_vcnt - 1) #define BIO_CONTIG(bio, nxt) \ - (bvec_to_phys(__BVEC_END((bio)) + (bio)->bi_size) == bio_to_phys((nxt))) + (bvec_to_phys(__BVEC_END((bio))) + (bio)->bi_size == bio_to_phys((nxt))) #define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \ (((addr1) | (mask)) == (((addr2) - 1) | (mask))) #define BIO_SEG_BOUNDARY(q, b1, b2) \ __BIO_SEG_BOUNDARY(bvec_to_phys(__BVEC_END((b1))), bio_to_phys((b2)) + (b2)->bi_size, (q)->seg_boundary_mask) -typedef int (bio_end_io_t) (struct bio *, int); -typedef void (bio_destructor_t) (struct bio *); - #define bio_io_error(bio) bio_endio((bio), 0, bio_sectors((bio))) #define bio_for_each_segment(bvl, bio, i) \ diff --git a/include/linux/blk.h b/include/linux/blk.h index 71712cbc6619..29db6a337ef5 100644 --- a/include/linux/blk.h +++ b/include/linux/blk.h @@ -8,56 +8,12 @@ #include <linux/compiler.h> /* - * Initialization functions. + * get rid of this next... */ -extern int isp16_init(void); -extern int cdu31a_init(void); -extern int acsi_init(void); -extern int mcd_init(void); -extern int mcdx_init(void); -extern int sbpcd_init(void); -extern int aztcd_init(void); -extern int sony535_init(void); -extern int gscd_init(void); -extern int cm206_init(void); -extern int optcd_init(void); -extern int sjcd_init(void); -extern int cdi_init(void); -extern int hd_init(void); extern int ide_init(void); -extern int xd_init(void); -extern int mfm_init(void); -extern int loop_init(void); -extern int md_init(void); -extern int ap_init(void); -extern int ddv_init(void); -extern int z2_init(void); -extern int swim3_init(void); -extern int swimiop_init(void); -extern int amiga_floppy_init(void); -extern int atari_floppy_init(void); -extern int ez_init(void); -extern int bpcd_init(void); -extern int ps2esdi_init(void); -extern int jsfd_init(void); -extern int viodasd_init(void); -extern int viocd_init(void); - -#if defined(CONFIG_ARCH_S390) -extern int dasd_init(void); -extern int xpram_init(void); -extern int tapeblock_init(void); -#endif /* CONFIG_ARCH_S390 */ extern void set_device_ro(kdev_t dev,int flag); -void add_blkdev_randomness(int major); - -extern int floppy_init(void); -extern void rd_load(void); -extern int rd_init(void); -extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ -extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ -extern int rd_image_start; /* starting block # of image */ +extern void add_blkdev_randomness(int major); #ifdef CONFIG_BLK_DEV_INITRD @@ -69,8 +25,6 @@ extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < m void initrd_init(void); #endif - - /* * end_request() and friends. Must be called with the request queue spinlock * acquired. All functions called within end_request() _must_be_ atomic. @@ -81,13 +35,50 @@ void initrd_init(void); * code duplication in drivers. */ +extern int end_that_request_first(struct request *, int, int); +extern void end_that_request_last(struct request *); + static inline void blkdev_dequeue_request(struct request *req) { list_del(&req->queuelist); } -int end_that_request_first(struct request *, int uptodate, int nr_sectors); -void end_that_request_last(struct request *); +#define __elv_next_request(q) (q)->elevator.elevator_next_req_fn((q)) + +extern inline struct request *elv_next_request(request_queue_t *q) +{ + struct request *rq; + + while ((rq = __elv_next_request(q))) { + rq->flags |= REQ_STARTED; + + if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) + break; + + /* + * all ok, break and return it + */ + if (!q->prep_rq_fn(q, rq)) + break; + + /* + * prep said no-go, kill it + */ + blkdev_dequeue_request(rq); + if (end_that_request_first(rq, 0, rq->nr_sectors)) + BUG(); + + end_that_request_last(rq); + } + + 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); +} #if defined(MAJOR_NR) || defined(IDE_DRIVER) @@ -364,15 +355,15 @@ static void (DEVICE_REQUEST)(request_queue_t *); #define CLEAR_INTR #endif -#define INIT_REQUEST \ - if (QUEUE_EMPTY) { \ - CLEAR_INTR; \ - return; \ - } \ - if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ - panic(DEVICE_NAME ": request list destroyed"); \ - if (!CURRENT->bio) \ - panic(DEVICE_NAME ": no bio"); \ +#define INIT_REQUEST \ + if (QUEUE_EMPTY) { \ + CLEAR_INTR; \ + return; \ + } \ + if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \ + panic(DEVICE_NAME ": request list destroyed"); \ + if (!CURRENT->bio) \ + panic(DEVICE_NAME ": no bio"); \ #endif /* !defined(IDE_DRIVER) */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index c061ce013036..e9e0cf21005a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -15,21 +15,32 @@ typedef struct request_queue request_queue_t; struct elevator_s; typedef struct elevator_s elevator_t; +struct request_list { + unsigned int count; + struct list_head free; + wait_queue_head_t wait; +}; + struct request { struct list_head queuelist; /* looking for ->queue? you must _not_ * access it directly, use * blkdev_dequeue_request! */ int elevator_sequence; - int inactive; /* driver hasn't seen it yet */ + unsigned char cmd[16]; + + unsigned long flags; /* see REQ_ bits below */ int rq_status; /* should split this into a few status bits */ kdev_t rq_dev; - int cmd; /* READ or WRITE */ int errors; sector_t sector; unsigned long nr_sectors; - unsigned long hard_sector, hard_nr_sectors; + unsigned long hard_sector; /* the hard_* are block layer + * internals, no driver should + * touch them + */ + unsigned long hard_nr_sectors; unsigned short nr_segments; unsigned short nr_hw_segments; unsigned int current_nr_sectors; @@ -39,8 +50,49 @@ struct request { struct completion *waiting; struct bio *bio, *biotail; request_queue_t *q; + struct request_list *rl; }; +/* + * first three bits match BIO_RW* bits, important + */ +enum rq_flag_bits { + __REQ_RW, /* not set, read. set, write */ + __REQ_RW_AHEAD, /* READA */ + __REQ_BARRIER, /* may not be passed */ + __REQ_CMD, /* is a regular fs rw request */ + __REQ_NOMERGE, /* don't touch this for merging */ + __REQ_STARTED, /* drive already may have started this one */ + __REQ_DONTPREP, /* don't call prep for this one */ + /* + * for IDE + */ + __REQ_DRIVE_CMD, + __REQ_DRIVE_TASK, + + __REQ_PC, /* packet command (special) */ + __REQ_BLOCK_PC, /* queued down pc from block layer */ + __REQ_SENSE, /* sense retrival */ + + __REQ_SPECIAL, /* driver special command */ + + __REQ_NR_BITS, /* stops here */ +}; + +#define REQ_RW (1 << __REQ_RW) +#define REQ_RW_AHEAD (1 << __REQ_RW_AHEAD) +#define REQ_BARRIER (1 << __REQ_BARRIER) +#define REQ_CMD (1 << __REQ_CMD) +#define REQ_NOMERGE (1 << __REQ_NOMERGE) +#define REQ_STARTED (1 << __REQ_STARTED) +#define REQ_DONTPREP (1 << __REQ_DONTPREP) +#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD) +#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK) +#define REQ_PC (1 << __REQ_PC) +#define REQ_SENSE (1 << __REQ_SENSE) +#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC) +#define REQ_SPECIAL (1 << __REQ_SPECIAL) + #include <linux/elevator.h> typedef int (merge_request_fn) (request_queue_t *, struct request *, @@ -50,6 +102,7 @@ typedef int (merge_requests_fn) (request_queue_t *, struct request *, typedef void (request_fn_proc) (request_queue_t *q); typedef request_queue_t * (queue_proc) (kdev_t dev); typedef int (make_request_fn) (request_queue_t *q, struct bio *bio); +typedef int (prep_rq_fn) (request_queue_t *, struct request *); typedef void (unplug_device_fn) (void *q); enum blk_queue_state { @@ -63,12 +116,6 @@ enum blk_queue_state { */ #define QUEUE_NR_REQUESTS 8192 -struct request_list { - unsigned int count; - struct list_head free; - wait_queue_head_t wait; -}; - struct request_queue { /* @@ -82,17 +129,18 @@ struct request_queue struct list_head queue_head; elevator_t elevator; - request_fn_proc * request_fn; - merge_request_fn * back_merge_fn; - merge_request_fn * front_merge_fn; - merge_requests_fn * merge_requests_fn; - make_request_fn * make_request_fn; + request_fn_proc *request_fn; + merge_request_fn *back_merge_fn; + merge_request_fn *front_merge_fn; + merge_requests_fn *merge_requests_fn; + make_request_fn *make_request_fn; + prep_rq_fn *prep_rq_fn; /* * The queue owner gets to use this for whatever they like. * ll_rw_blk doesn't touch it. */ - void * queuedata; + void *queuedata; /* * queue needs bounce pages for pages above this limit @@ -138,13 +186,12 @@ struct request_queue #define QUEUE_FLAG_CLUSTER 2 /* cluster several segments into 1 */ #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) - #define blk_mark_plugged(q) set_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) - #define blk_queue_empty(q) elv_queue_empty(q) - #define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) +#define rq_data_dir(rq) ((rq)->flags & 1) + /* * noop, requests are automagically marked as active/inactive by I/O * scheduler -- see elv_next_request @@ -153,20 +200,6 @@ struct request_queue extern unsigned long blk_max_low_pfn, blk_max_pfn; -#define __elv_next_request(q) (q)->elevator.elevator_next_req_fn((q)) - -extern inline struct request *elv_next_request(request_queue_t *q) -{ - struct request *rq = __elv_next_request(q); - - if (rq) { - rq->inactive = 0; - wmb(); - } - - return rq; -} - #define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT) #define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT) @@ -186,7 +219,8 @@ extern inline void blk_queue_bounce(request_queue_t *q, struct bio **bio) #endif /* CONFIG_HIGHMEM */ #define rq_for_each_bio(bio, rq) \ - for (bio = (rq)->bio; bio; bio = bio->bi_next) + if ((rq->bio)) \ + for (bio = (rq)->bio; bio; bio = bio->bi_next) struct blk_dev_struct { /* @@ -219,6 +253,11 @@ extern void generic_make_request(struct bio *bio); extern inline request_queue_t *blk_get_queue(kdev_t dev); extern void blkdev_release_request(struct request *); extern void blk_attempt_remerge(request_queue_t *, struct request *); +extern struct request *blk_get_request(request_queue_t *, int, int); +extern void blk_put_request(struct request *); +extern void blk_plug_device(request_queue_t *); + +extern int block_ioctl(kdev_t, unsigned int, unsigned long); /* * Access functions for manipulating queue properties @@ -233,6 +272,7 @@ extern void blk_queue_max_segment_size(request_queue_t *q, unsigned int); extern void blk_queue_hardsect_size(request_queue_t *q, unsigned short); extern void blk_queue_segment_boundary(request_queue_t *q, unsigned long); extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *); +extern void blk_dump_rq_flags(struct request *, char *); extern void generic_unplug_device(void *); extern int * blk_size[MAX_BLKDEV]; @@ -256,8 +296,7 @@ extern int * max_readahead[MAX_BLKDEV]; #define blkdev_next_request(req) blkdev_entry_to_request((req)->queuelist.next) #define blkdev_prev_request(req) blkdev_entry_to_request((req)->queuelist.prev) -extern void drive_stat_acct (kdev_t dev, int rw, - unsigned long nr_sectors, int new_io); +extern void drive_stat_acct(struct request *, int, int); extern inline void blk_clear(int major) { diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h index 9b221556097f..d514f908a3a5 100644 --- a/include/linux/coda_linux.h +++ b/include/linux/coda_linux.h @@ -92,12 +92,6 @@ void coda_sysctl_clean(void); printk(format, ## a); } \ } while (0) -#define ENTRY \ - if(coda_print_entry) printk("Process %d entered %s\n",current->pid,__FUNCTION__) - -#define EXIT \ - if(coda_print_entry) printk("Process %d leaving %s\n",current->pid,__FUNCTION__) - #define CODA_ALLOC(ptr, cast, size) \ do { \ if (size < PAGE_SIZE) { \ |
