diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/acsi.c | 2 | ||||
-rw-r--r-- | drivers/block/acsi_slm.c | 2 | ||||
-rw-r--r-- | drivers/block/aoe/aoe.h | 12 | ||||
-rw-r--r-- | drivers/block/ataflop.c | 14 | ||||
-rw-r--r-- | drivers/block/cciss.c | 7 | ||||
-rw-r--r-- | drivers/block/cfq-iosched.c | 3 | ||||
-rw-r--r-- | drivers/block/deadline-iosched.c | 5 | ||||
-rw-r--r-- | drivers/block/floppy.c | 4 | ||||
-rw-r--r-- | drivers/block/paride/pcd.c | 3 | ||||
-rw-r--r-- | drivers/block/paride/pf.c | 3 | ||||
-rw-r--r-- | drivers/block/paride/pg.c | 3 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 3 | ||||
-rw-r--r-- | drivers/block/ps2esdi.c | 3 | ||||
-rw-r--r-- | drivers/block/scsi_ioctl.c | 1 | ||||
-rw-r--r-- | drivers/block/swim3.c | 9 | ||||
-rw-r--r-- | drivers/block/swim_iop.c | 3 | ||||
-rw-r--r-- | drivers/block/ub.c | 273 | ||||
-rw-r--r-- | drivers/block/umem.c | 11 | ||||
-rw-r--r-- | drivers/block/xd.c | 21 | ||||
-rw-r--r-- | drivers/block/z2ram.c | 2 |
20 files changed, 197 insertions, 187 deletions
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c index ce933de48084..0e1f34fef0c8 100644 --- a/drivers/block/acsi.c +++ b/drivers/block/acsi.c @@ -371,7 +371,7 @@ static int acsi_revalidate (struct gendisk *disk); /************************* End of Prototypes **************************/ -struct timer_list acsi_timer = TIMER_INITIALIZER(acsi_times_out, 0, 0); +DEFINE_TIMER(acsi_timer, acsi_times_out, 0, 0); #ifdef CONFIG_ATARI_SLM diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c index e3be8c31a74c..a5c1c8e871ec 100644 --- a/drivers/block/acsi_slm.c +++ b/drivers/block/acsi_slm.c @@ -268,7 +268,7 @@ static int slm_get_pagesize( int device, int *w, int *h ); /************************* End of Prototypes **************************/ -static struct timer_list slm_timer = TIMER_INITIALIZER(slm_test_ready, 0, 0); +static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0); static struct file_operations slm_fops = { .owner = THIS_MODULE, diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 721ba8086043..0e9e586e9ba3 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -1,5 +1,5 @@ /* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ -#define VERSION "10" +#define VERSION "12" #define AOE_MAJOR 152 #define DEVICE_NAME "aoe" @@ -7,12 +7,12 @@ * default is 16, which is 15 partitions plus the whole disk */ #ifndef AOE_PARTITIONS -#define AOE_PARTITIONS 16 +#define AOE_PARTITIONS (16) #endif -#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor)) -#define AOEMAJOR(sysminor) ((sysminor) / 10) -#define AOEMINOR(sysminor) ((sysminor) % 10) +#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor)) +#define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF) +#define AOEMINOR(sysminor) ((sysminor) % NPERSHELF) #define WHITESPACE " \t\v\f\n" enum { @@ -83,7 +83,7 @@ enum { enum { MAXATADATA = 1024, - NPERSHELF = 10, + NPERSHELF = 16, /* number of slots per shelf address */ FREETAG = -1, MIN_BUFS = 8, }; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index db05a5a99f35..22bda05fc693 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -371,16 +371,10 @@ static int floppy_release( struct inode * inode, struct file * filp ); /************************* End of Prototypes **************************/ -static struct timer_list motor_off_timer = - TIMER_INITIALIZER(fd_motor_off_timer, 0, 0); -static struct timer_list readtrack_timer = - TIMER_INITIALIZER(fd_readtrack_check, 0, 0); - -static struct timer_list timeout_timer = - TIMER_INITIALIZER(fd_times_out, 0, 0); - -static struct timer_list fd_timer = - TIMER_INITIALIZER(check_change, 0, 0); +static DEFINE_TIMER(motor_off_timer, fd_motor_off_timer, 0, 0); +static DEFINE_TIMER(readtrack_timer, fd_readtrack_check, 0, 0); +static DEFINE_TIMER(timeout_timer, fd_times_out, 0, 0); +static DEFINE_TIMER(fd_timer, check_change, 0, 0); static inline void start_motor_off_timer(void) { diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 418b1469d75d..28f2c177a541 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1713,10 +1713,9 @@ static unsigned long pollcomplete(int ctlr) for (i = 20 * HZ; i > 0; i--) { done = hba[ctlr]->access.command_completed(hba[ctlr]); - if (done == FIFO_EMPTY) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } else + if (done == FIFO_EMPTY) + schedule_timeout_uninterruptible(1); + else return (done); } /* Invalid address to tell caller we ran out of time */ diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index 30c0903c7cdd..cd056e7e64ec 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c @@ -2260,6 +2260,8 @@ static void cfq_put_cfqd(struct cfq_data *cfqd) if (!atomic_dec_and_test(&cfqd->ref)) return; + blk_put_queue(q); + cfq_shutdown_timer_wq(cfqd); q->elevator->elevator_data = NULL; @@ -2316,6 +2318,7 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e) e->elevator_data = cfqd; cfqd->queue = q; + atomic_inc(&q->refcnt); cfqd->max_queued = q->nr_requests / 4; q->nr_batching = cfq_queued; diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c index 24594c57c323..52a3ae5289a0 100644 --- a/drivers/block/deadline-iosched.c +++ b/drivers/block/deadline-iosched.c @@ -512,7 +512,10 @@ static int deadline_dispatch_requests(struct deadline_data *dd) /* * batches are currently reads XOR writes */ - drq = dd->next_drq[WRITE] ? : dd->next_drq[READ]; + if (dd->next_drq[WRITE]) + drq = dd->next_drq[WRITE]; + else + drq = dd->next_drq[READ]; if (drq) { /* we have a "next request" */ diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 888dad5eef34..00895477155e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -628,7 +628,7 @@ static inline void debugt(const char *message) { } #endif /* DEBUGT */ typedef void (*timeout_fn) (unsigned long); -static struct timer_list fd_timeout = TIMER_INITIALIZER(floppy_shutdown, 0, 0); +static DEFINE_TIMER(fd_timeout, floppy_shutdown, 0, 0); static const char *timeout_message; @@ -1012,7 +1012,7 @@ static void schedule_bh(void (*handler) (void)) schedule_work(&floppy_work); } -static struct timer_list fd_timer = TIMER_INITIALIZER(NULL, 0, 0); +static DEFINE_TIMER(fd_timer, NULL, 0, 0); static void cancel_activity(void) { diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 7289f67e9568..ac5ba462710b 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -516,8 +516,7 @@ static int pcd_tray_move(struct cdrom_device_info *cdi, int position) static void pcd_sleep(int cs) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(cs); + schedule_timeout_interruptible(cs); } static int pcd_reset(struct pcd_unit *cd) diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 060b1f2a91dd..711d2f314ac3 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -507,8 +507,7 @@ static void pf_eject(struct pf_unit *pf) static void pf_sleep(int cs) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(cs); + schedule_timeout_interruptible(cs); } /* the ATAPI standard actually specifies the contents of all 7 registers diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 84d8e291ed96..b3982395f22b 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -276,8 +276,7 @@ static inline u8 DRIVE(struct pg *dev) static void pg_sleep(int cs) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(cs); + schedule_timeout_interruptible(cs); } static int pg_wait(struct pg *dev, int go, int stop, unsigned long tmo, char *msg) diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 5fe8ee86f095..d8d35233cf49 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -383,8 +383,7 @@ static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char * static void pt_sleep(int cs) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(cs); + schedule_timeout_interruptible(cs); } static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg) diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c index 29548784cb7b..29d1518be72a 100644 --- a/drivers/block/ps2esdi.c +++ b/drivers/block/ps2esdi.c @@ -99,8 +99,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int); static int no_int_yet; static int ps2esdi_drives; static u_short io_base; -static struct timer_list esdi_timer = - TIMER_INITIALIZER(ps2esdi_reset_timer, 0, 0); +static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0); static int reset_status; static int ps2esdi_slot = -1; static int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */ diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index abb2df249fd3..856c2278e9d0 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c @@ -123,6 +123,7 @@ static int verify_command(struct file *file, unsigned char *cmd) safe_for_read(READ_12), safe_for_read(READ_16), safe_for_read(READ_BUFFER), + safe_for_read(READ_DEFECT_DATA), safe_for_read(READ_LONG), safe_for_read(INQUIRY), safe_for_read(MODE_SENSE), diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index e5f7494c00ee..e425ad3eebba 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -834,8 +834,7 @@ static int fd_eject(struct floppy_state *fs) break; } swim3_select(fs, RELAX); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(1); if (swim3_readbit(fs, DISK_IN) == 0) break; } @@ -906,8 +905,7 @@ static int floppy_open(struct inode *inode, struct file *filp) break; } swim3_select(fs, RELAX); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(1); } if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0 || swim3_readbit(fs, DISK_IN) == 0)) @@ -992,8 +990,7 @@ static int floppy_revalidate(struct gendisk *disk) if (signal_pending(current)) break; swim3_select(fs, RELAX); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(1); } ret = swim3_readbit(fs, SEEK_COMPLETE) == 0 || swim3_readbit(fs, DISK_IN) == 0; diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c index a1283f6dc018..89e3c2f8b776 100644 --- a/drivers/block/swim_iop.c +++ b/drivers/block/swim_iop.c @@ -338,8 +338,7 @@ static int swimiop_eject(struct floppy_state *fs) err = -EINTR; break; } - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); + schedule_timeout_interruptible(1); } release_drive(fs); return cmd->error; diff --git a/drivers/block/ub.c b/drivers/block/ub.c index a026567f5d18..aa0bf7ee008d 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -16,9 +16,10 @@ * -- verify the 13 conditions and do bulk resets * -- kill last_pipe and simply do two-state clearing on both pipes * -- verify protocol (bulk) from USB descriptors (maybe...) - * -- highmem and sg + * -- highmem * -- move top_sense and work_bcs into separate allocations (if they survive) * for cache purists and esoteric architectures. + * -- Allocate structure for LUN 0 before the first ub_sync_tur, avoid NULL. ? * -- prune comments, they are too volumnous * -- Exterminate P3 printks * -- Resove XXX's @@ -171,7 +172,7 @@ struct bulk_cs_wrap { */ struct ub_dev; -#define UB_MAX_REQ_SG 1 +#define UB_MAX_REQ_SG 4 #define UB_MAX_SECTORS 64 /* @@ -234,13 +235,10 @@ struct ub_scsi_cmd { int stat_count; /* Retries getting status. */ - /* - * We do not support transfers from highmem pages - * because the underlying USB framework does not do what we need. - */ - char *data; /* Requested buffer */ unsigned int len; /* Requested length */ - // struct scatterlist sgv[UB_MAX_REQ_SG]; + unsigned int current_sg; + unsigned int nsg; /* sgv[nsg] */ + struct scatterlist sgv[UB_MAX_REQ_SG]; struct ub_lun *lun; void (*done)(struct ub_dev *, struct ub_scsi_cmd *); @@ -389,17 +387,18 @@ struct ub_dev { struct bulk_cs_wrap work_bcs; struct usb_ctrlrequest work_cr; + int sg_stat[UB_MAX_REQ_SG+1]; struct ub_scsi_trace tr; }; /* */ static void ub_cleanup(struct ub_dev *sc); -static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq); +static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, struct ub_scsi_cmd *cmd, struct request *rq); -static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, - struct request *rq); +static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, + struct ub_scsi_cmd *cmd, struct request *rq); static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static void ub_end_rq(struct request *rq, int uptodate); static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -407,6 +406,7 @@ static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); static void ub_scsi_action(unsigned long _dev); static void ub_scsi_dispatch(struct ub_dev *sc); static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd); +static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc); static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -500,7 +500,8 @@ static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd, } } -static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page) +static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, + char *page) { struct usb_interface *intf; struct ub_dev *sc; @@ -523,6 +524,13 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, c cnt += sprintf(page + cnt, "qlen %d qmax %d\n", sc->cmd_queue.qlen, sc->cmd_queue.qmax); + cnt += sprintf(page + cnt, + "sg %d %d %d %d %d\n", + sc->sg_stat[0], + sc->sg_stat[1], + sc->sg_stat[2], + sc->sg_stat[3], + sc->sg_stat[4]); list_for_each (p, &sc->luns) { lun = list_entry(p, struct ub_lun, link); @@ -744,20 +752,20 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) * The request function is our main entry point */ -static void ub_bd_rq_fn(request_queue_t *q) +static void ub_request_fn(request_queue_t *q) { struct ub_lun *lun = q->queuedata; struct request *rq; while ((rq = elv_next_request(q)) != NULL) { - if (ub_bd_rq_fn_1(lun, rq) != 0) { + if (ub_request_fn_1(lun, rq) != 0) { blk_stop_queue(q); break; } } } -static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) +static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) { struct ub_dev *sc = lun->udev; struct ub_scsi_cmd *cmd; @@ -774,9 +782,8 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) memset(cmd, 0, sizeof(struct ub_scsi_cmd)); blkdev_dequeue_request(rq); - if (blk_pc_request(rq)) { - rc = ub_cmd_build_packet(sc, cmd, rq); + rc = ub_cmd_build_packet(sc, lun, cmd, rq); } else { rc = ub_cmd_build_block(sc, lun, cmd, rq); } @@ -791,7 +798,7 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) cmd->back = rq; cmd->tag = sc->tagcnt++; - if ((rc = ub_submit_scsi(sc, cmd)) != 0) { + if (ub_submit_scsi(sc, cmd) != 0) { ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); return 0; @@ -804,58 +811,31 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, struct ub_scsi_cmd *cmd, struct request *rq) { int ub_dir; -#if 0 /* We use rq->buffer for now */ - struct scatterlist *sg; int n_elem; -#endif unsigned int block, nblks; if (rq_data_dir(rq) == WRITE) ub_dir = UB_DIR_WRITE; else ub_dir = UB_DIR_READ; + cmd->dir = ub_dir; /* * get scatterlist from block layer */ -#if 0 /* We use rq->buffer for now */ - sg = &cmd->sgv[0]; - n_elem = blk_rq_map_sg(q, rq, sg); + n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); if (n_elem <= 0) { - ub_put_cmd(lun, cmd); - ub_end_rq(rq, 0); - blk_start_queue(q); - return 0; /* request with no s/g entries? */ + printk(KERN_INFO "%s: failed request map (%d)\n", + sc->name, n_elem); /* P3 */ + return -1; /* request with no s/g entries? */ } - - if (n_elem != 1) { /* Paranoia */ + if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ printk(KERN_WARNING "%s: request with %d segments\n", sc->name, n_elem); - ub_put_cmd(lun, cmd); - ub_end_rq(rq, 0); - blk_start_queue(q); - return 0; - } -#endif - - /* - * XXX Unfortunately, this check does not work. It is quite possible - * to get bogus non-null rq->buffer if you allow sg by mistake. - */ - if (rq->buffer == NULL) { - /* - * This must not happen if we set the queue right. - * The block level must create bounce buffers for us. - */ - static int do_print = 1; - if (do_print) { - printk(KERN_WARNING "%s: unmapped block request" - " flags 0x%lx sectors %lu\n", - sc->name, rq->flags, rq->nr_sectors); - do_print = 0; - } return -1; } + cmd->nsg = n_elem; + sc->sg_stat[n_elem]++; /* * build the command @@ -876,30 +856,15 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, cmd->cdb[8] = nblks; cmd->cdb_len = 10; - cmd->dir = ub_dir; - cmd->data = rq->buffer; cmd->len = rq->nr_sectors * 512; return 0; } -static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, - struct request *rq) +static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, + struct ub_scsi_cmd *cmd, struct request *rq) { - - if (rq->data_len != 0 && rq->data == NULL) { - static int do_print = 1; - if (do_print) { - printk(KERN_WARNING "%s: unmapped packet request" - " flags 0x%lx length %d\n", - sc->name, rq->flags, rq->data_len); - do_print = 0; - } - return -1; - } - - memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); - cmd->cdb_len = rq->cmd_len; + int n_elem; if (rq->data_len == 0) { cmd->dir = UB_DIR_NONE; @@ -908,8 +873,29 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, cmd->dir = UB_DIR_WRITE; else cmd->dir = UB_DIR_READ; + + } + + /* + * get scatterlist from block layer + */ + n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); + if (n_elem < 0) { + printk(KERN_INFO "%s: failed request map (%d)\n", + sc->name, n_elem); /* P3 */ + return -1; } - cmd->data = rq->data; + if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ + printk(KERN_WARNING "%s: request with %d segments\n", + sc->name, n_elem); + return -1; + } + cmd->nsg = n_elem; + sc->sg_stat[n_elem]++; + + memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); + cmd->cdb_len = rq->cmd_len; + cmd->len = rq->data_len; return 0; @@ -919,24 +905,34 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { struct request *rq = cmd->back; struct ub_lun *lun = cmd->lun; - struct gendisk *disk = lun->disk; - request_queue_t *q = disk->queue; int uptodate; - if (blk_pc_request(rq)) { - /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ - memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); - rq->sense_len = UB_SENSE_SIZE; - } - - if (cmd->error == 0) + if (cmd->error == 0) { uptodate = 1; - else + + if (blk_pc_request(rq)) { + if (cmd->act_len >= rq->data_len) + rq->data_len = 0; + else + rq->data_len -= cmd->act_len; + } + } else { uptodate = 0; + if (blk_pc_request(rq)) { + /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ + memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); + rq->sense_len = UB_SENSE_SIZE; + if (sc->top_sense[0] != 0) + rq->errors = SAM_STAT_CHECK_CONDITION; + else + rq->errors = DID_ERROR << 16; + } + } + ub_put_cmd(lun, cmd); ub_end_rq(rq, uptodate); - blk_start_queue(q); + blk_start_queue(lun->disk->queue); } static void ub_end_rq(struct request *rq, int uptodate) @@ -1014,7 +1010,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) sc->last_pipe = sc->send_bulk_pipe; usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); - sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; + sc->work_urb.transfer_flags = 0; /* Fill what we shouldn't be filling, because usb-storage did so. */ sc->work_urb.actual_length = 0; @@ -1103,7 +1099,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { struct urb *urb = &sc->work_urb; struct bulk_cs_wrap *bcs; - int pipe; int rc; if (atomic_read(&sc->poison)) { @@ -1204,38 +1199,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) goto Bad_End; } - if (cmd->dir == UB_DIR_NONE) { + if (cmd->dir == UB_DIR_NONE || cmd->nsg < 1) { ub_state_stat(sc, cmd); return; } - UB_INIT_COMPLETION(sc->work_done); - - if (cmd->dir == UB_DIR_READ) - pipe = sc->recv_bulk_pipe; - else - pipe = sc->send_bulk_pipe; - sc->last_pipe = pipe; - usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, - cmd->data, cmd->len, ub_urb_complete, sc); - sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; - - if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { - /* XXX Clear stalls */ - printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */ - ub_complete(&sc->work_done); - ub_state_done(sc, cmd, rc); - return; - } - - sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; - add_timer(&sc->work_timer); - - cmd->state = UB_CMDST_DATA; - ub_cmdtr_state(sc, cmd); + // udelay(125); // usb-storage has this + ub_data_start(sc, cmd); } else if (cmd->state == UB_CMDST_DATA) { if (urb->status == -EPIPE) { @@ -1257,16 +1227,22 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) if (urb->status == -EOVERFLOW) { /* * A babble? Failure, but we must transfer CSW now. + * XXX This is going to end in perpetual babble. Reset. */ cmd->error = -EOVERFLOW; /* A cheap trick... */ - } else { - if (urb->status != 0) - goto Bad_End; + ub_state_stat(sc, cmd); + return; } + if (urb->status != 0) + goto Bad_End; - cmd->act_len = urb->actual_length; + cmd->act_len += urb->actual_length; ub_cmdtr_act_len(sc, cmd); + if (++cmd->current_sg < cmd->nsg) { + ub_data_start(sc, cmd); + return; + } ub_state_stat(sc, cmd); } else if (cmd->state == UB_CMDST_STAT) { @@ -1401,6 +1377,46 @@ Bad_End: /* Little Excel is dead */ /* * Factorization helper for the command state machine: + * Initiate a data segment transfer. + */ +static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) +{ + struct scatterlist *sg = &cmd->sgv[cmd->current_sg]; + int pipe; + int rc; + + UB_INIT_COMPLETION(sc->work_done); + + if (cmd->dir == UB_DIR_READ) + pipe = sc->recv_bulk_pipe; + else + pipe = sc->send_bulk_pipe; + sc->last_pipe = pipe; + usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, + page_address(sg->page) + sg->offset, sg->length, + ub_urb_complete, sc); + sc->work_urb.transfer_flags = 0; + sc->work_urb.actual_length = 0; + sc->work_urb.error_count = 0; + sc->work_urb.status = 0; + + if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { + /* XXX Clear stalls */ + printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */ + ub_complete(&sc->work_done); + ub_state_done(sc, cmd, rc); + return; + } + + sc->work_timer.expires = jiffies + UB_DATA_TIMEOUT; + add_timer(&sc->work_timer); + + cmd->state = UB_CMDST_DATA; + ub_cmdtr_state(sc, cmd); +} + +/* + * Factorization helper for the command state machine: * Finish the command. */ static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc) @@ -1426,7 +1442,7 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) sc->last_pipe = sc->recv_bulk_pipe; usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); - sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; + sc->work_urb.transfer_flags = 0; sc->work_urb.actual_length = 0; sc->work_urb.error_count = 0; sc->work_urb.status = 0; @@ -1484,6 +1500,7 @@ static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd) static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { struct ub_scsi_cmd *scmd; + struct scatterlist *sg; int rc; if (cmd->cdb[0] == REQUEST_SENSE) { @@ -1492,12 +1509,17 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) } scmd = &sc->top_rqs_cmd; + memset(scmd, 0, sizeof(struct ub_scsi_cmd)); scmd->cdb[0] = REQUEST_SENSE; scmd->cdb[4] = UB_SENSE_SIZE; scmd->cdb_len = 6; scmd->dir = UB_DIR_READ; scmd->state = UB_CMDST_INIT; - scmd->data = sc->top_sense; + scmd->nsg = 1; + sg = &scmd->sgv[0]; + sg->page = virt_to_page(sc->top_sense); + sg->offset = (unsigned int)sc->top_sense & (PAGE_SIZE-1); + sg->length = UB_SENSE_SIZE; scmd->len = UB_SENSE_SIZE; scmd->lun = cmd->lun; scmd->done = ub_top_sense_done; @@ -1541,7 +1563,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); - sc->work_urb.transfer_flags = URB_ASYNC_UNLINK; + sc->work_urb.transfer_flags = 0; sc->work_urb.actual_length = 0; sc->work_urb.error_count = 0; sc->work_urb.status = 0; @@ -1560,7 +1582,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, */ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) { - unsigned char *sense = scmd->data; + unsigned char *sense = sc->top_sense; struct ub_scsi_cmd *cmd; /* @@ -1852,6 +1874,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, struct ub_capacity *ret) { struct ub_scsi_cmd *cmd; + struct scatterlist *sg; char *p; enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) + 8 }; unsigned long flags; @@ -1872,7 +1895,11 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, cmd->cdb_len = 10; cmd->dir = UB_DIR_READ; cmd->state = UB_CMDST_INIT; - cmd->data = p; + cmd->nsg = 1; + sg = &cmd->sgv[0]; + sg->page = virt_to_page(p); + sg->offset = (unsigned int)p & (PAGE_SIZE-1); + sg->length = 8; cmd->len = 8; cmd->lun = lun; cmd->done = ub_probe_done; @@ -2289,7 +2316,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ rc = -ENOMEM; - if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) + if ((q = blk_init_queue(ub_request_fn, &sc->lock)) == NULL) goto err_blkqinit; disk->queue = q; diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 0c4c121d2e79..0f48301342da 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -34,6 +34,7 @@ * - set initialised bit then. */ +//#define DEBUG /* uncomment if you want debugging info (pr_debug) */ #include <linux/config.h> #include <linux/sched.h> #include <linux/fs.h> @@ -58,10 +59,6 @@ #include <asm/uaccess.h> #include <asm/io.h> -#define PRINTK(x...) do {} while (0) -#define dprintk(x...) do {} while (0) -/*#define dprintk(x...) printk(x) */ - #define MM_MAXCARDS 4 #define MM_RAHEAD 2 /* two sectors */ #define MM_BLKSIZE 1024 /* 1k blocks */ @@ -299,7 +296,7 @@ static void mm_start_io(struct cardinfo *card) /* make the last descriptor end the chain */ page = &card->mm_pages[card->Active]; - PRINTK("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1); + pr_debug("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1); desc = &page->desc[page->cnt-1]; desc->control_bits |= cpu_to_le32(DMASCR_CHAIN_COMP_EN); @@ -532,7 +529,7 @@ static void process_page(unsigned long data) activate(card); } else { /* haven't finished with this one yet */ - PRINTK("do some more\n"); + pr_debug("do some more\n"); mm_start_io(card); } out_unlock: @@ -555,7 +552,7 @@ static void process_page(unsigned long data) static int mm_make_request(request_queue_t *q, struct bio *bio) { struct cardinfo *card = q->queuedata; - PRINTK("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size); + pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size); bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/ spin_lock_irq(&card->lock); diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 1676033da6c6..68b6d7b154cf 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -47,6 +47,7 @@ #include <linux/wait.h> #include <linux/blkdev.h> #include <linux/blkpg.h> +#include <linux/delay.h> #include <asm/system.h> #include <asm/io.h> @@ -62,7 +63,7 @@ static int xd[5] = { -1,-1,-1,-1, }; #define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using "nodma" module option */ -#define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */ +#define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */ /* Above may need to be increased if a problem with the 2nd drive detection (ST11M controller) or resetting a controller (WD) appears */ @@ -529,10 +530,8 @@ static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long t int success; xdc_busy = 1; - while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } + while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) + schedule_timeout_uninterruptible(1); xdc_busy = 0; return (success); } @@ -633,14 +632,12 @@ static u_char __init xd_initdrives (void (*init_drive)(u_char drive)) for (i = 0; i < XD_MAXDRIVES; i++) { xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0); if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(XD_INIT_DISK_DELAY); + msleep_interruptible(XD_INIT_DISK_DELAY); init_drive(count); count++; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(XD_INIT_DISK_DELAY); + msleep_interruptible(XD_INIT_DISK_DELAY); } } return (count); @@ -761,8 +758,7 @@ static void __init xd_wd_init_controller (unsigned int address) outb(0,XD_RESET); /* reset the controller */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(XD_INIT_DISK_DELAY); + msleep(XD_INIT_DISK_DELAY); } static void __init xd_wd_init_drive (u_char drive) @@ -936,8 +932,7 @@ If you need non-standard settings use the xd=... command */ xd_maxsectors = 0x01; outb(0,XD_RESET); /* reset the controller */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(XD_INIT_DISK_DELAY); + msleep(XD_INIT_DISK_DELAY); } static void __init xd_xebec_init_drive (u_char drive) diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 007f6a662439..bb5e8d665a2a 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -296,7 +296,7 @@ z2_open( struct inode *inode, struct file *filp ) return 0; err_out_kfree: - kfree( z2ram_map ); + kfree(z2ram_map); err_out: return rc; } |