diff options
Diffstat (limited to 'drivers')
55 files changed, 1053 insertions, 776 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ce803d18e96a..bdbd55af7022 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4924,7 +4924,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
4924 | * @dev: device to target | 4924 | * @dev: device to target |
4925 | * @buf: data buffer | 4925 | * @buf: data buffer |
4926 | * @buflen: buffer length | 4926 | * @buflen: buffer length |
4927 | * @write_data: read/write | 4927 | * @rw: read/write |
4928 | * | 4928 | * |
4929 | * Transfer data from/to the device data register by PIO. | 4929 | * Transfer data from/to the device data register by PIO. |
4930 | * | 4930 | * |
@@ -4970,7 +4970,7 @@ unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf, | |||
4970 | * @dev: device to target | 4970 | * @dev: device to target |
4971 | * @buf: data buffer | 4971 | * @buf: data buffer |
4972 | * @buflen: buffer length | 4972 | * @buflen: buffer length |
4973 | * @write_data: read/write | 4973 | * @rw: read/write |
4974 | * | 4974 | * |
4975 | * Transfer data from/to the device data register by PIO. Do the | 4975 | * Transfer data from/to the device data register by PIO. Do the |
4976 | * transfer with interrupts disabled. | 4976 | * transfer with interrupts disabled. |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 9030c373ce67..cd03473f3547 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -3455,19 +3455,12 @@ static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, | |||
3455 | bool SuccessfulIO) | 3455 | bool SuccessfulIO) |
3456 | { | 3456 | { |
3457 | struct request *Request = Command->Request; | 3457 | struct request *Request = Command->Request; |
3458 | int UpToDate; | 3458 | int Error = SuccessfulIO ? 0 : -EIO; |
3459 | |||
3460 | UpToDate = 0; | ||
3461 | if (SuccessfulIO) | ||
3462 | UpToDate = 1; | ||
3463 | 3459 | ||
3464 | pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist, | 3460 | pci_unmap_sg(Command->Controller->PCIDevice, Command->cmd_sglist, |
3465 | Command->SegmentCount, Command->DmaDirection); | 3461 | Command->SegmentCount, Command->DmaDirection); |
3466 | 3462 | ||
3467 | if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { | 3463 | if (!__blk_end_request(Request, Error, Command->BlockCount << 9)) { |
3468 | add_disk_randomness(Request->rq_disk); | ||
3469 | end_that_request_last(Request, UpToDate); | ||
3470 | |||
3471 | if (Command->Completion) { | 3464 | if (Command->Completion) { |
3472 | complete(Command->Completion); | 3465 | complete(Command->Completion); |
3473 | Command->Completion = NULL; | 3466 | Command->Completion = NULL; |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 509b6490413b..ef50068def88 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1187,17 +1187,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
1187 | } | 1187 | } |
1188 | } | 1188 | } |
1189 | 1189 | ||
1190 | static inline void complete_buffers(struct bio *bio, int status) | ||
1191 | { | ||
1192 | while (bio) { | ||
1193 | struct bio *xbh = bio->bi_next; | ||
1194 | |||
1195 | bio->bi_next = NULL; | ||
1196 | bio_endio(bio, status ? 0 : -EIO); | ||
1197 | bio = xbh; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | static void cciss_check_queues(ctlr_info_t *h) | 1190 | static void cciss_check_queues(ctlr_info_t *h) |
1202 | { | 1191 | { |
1203 | int start_queue = h->next_to_run; | 1192 | int start_queue = h->next_to_run; |
@@ -1263,21 +1252,14 @@ static void cciss_softirq_done(struct request *rq) | |||
1263 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); | 1252 | pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); |
1264 | } | 1253 | } |
1265 | 1254 | ||
1266 | complete_buffers(rq->bio, (rq->errors == 0)); | ||
1267 | |||
1268 | if (blk_fs_request(rq)) { | ||
1269 | const int rw = rq_data_dir(rq); | ||
1270 | |||
1271 | disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); | ||
1272 | } | ||
1273 | |||
1274 | #ifdef CCISS_DEBUG | 1255 | #ifdef CCISS_DEBUG |
1275 | printk("Done with %p\n", rq); | 1256 | printk("Done with %p\n", rq); |
1276 | #endif /* CCISS_DEBUG */ | 1257 | #endif /* CCISS_DEBUG */ |
1277 | 1258 | ||
1278 | add_disk_randomness(rq->rq_disk); | 1259 | if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq))) |
1260 | BUG(); | ||
1261 | |||
1279 | spin_lock_irqsave(&h->lock, flags); | 1262 | spin_lock_irqsave(&h->lock, flags); |
1280 | end_that_request_last(rq, (rq->errors == 0)); | ||
1281 | cmd_free(h, cmd, 1); | 1263 | cmd_free(h, cmd, 1); |
1282 | cciss_check_queues(h); | 1264 | cciss_check_queues(h); |
1283 | spin_unlock_irqrestore(&h->lock, flags); | 1265 | spin_unlock_irqrestore(&h->lock, flags); |
@@ -2544,7 +2526,6 @@ after_error_processing: | |||
2544 | } | 2526 | } |
2545 | cmd->rq->data_len = 0; | 2527 | cmd->rq->data_len = 0; |
2546 | cmd->rq->completion_data = cmd; | 2528 | cmd->rq->completion_data = cmd; |
2547 | blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); | ||
2548 | blk_complete_request(cmd->rq); | 2529 | blk_complete_request(cmd->rq); |
2549 | } | 2530 | } |
2550 | 2531 | ||
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index c8132d958795..69199185ff4b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -167,7 +167,6 @@ static void start_io(ctlr_info_t *h); | |||
167 | 167 | ||
168 | static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); | 168 | static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); |
169 | static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); | 169 | static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); |
170 | static inline void complete_buffers(struct bio *bio, int ok); | ||
171 | static inline void complete_command(cmdlist_t *cmd, int timeout); | 170 | static inline void complete_command(cmdlist_t *cmd, int timeout); |
172 | 171 | ||
173 | static irqreturn_t do_ida_intr(int irq, void *dev_id); | 172 | static irqreturn_t do_ida_intr(int irq, void *dev_id); |
@@ -980,26 +979,13 @@ static void start_io(ctlr_info_t *h) | |||
980 | } | 979 | } |
981 | } | 980 | } |
982 | 981 | ||
983 | static inline void complete_buffers(struct bio *bio, int ok) | ||
984 | { | ||
985 | struct bio *xbh; | ||
986 | |||
987 | while (bio) { | ||
988 | xbh = bio->bi_next; | ||
989 | bio->bi_next = NULL; | ||
990 | |||
991 | bio_endio(bio, ok ? 0 : -EIO); | ||
992 | |||
993 | bio = xbh; | ||
994 | } | ||
995 | } | ||
996 | /* | 982 | /* |
997 | * Mark all buffers that cmd was responsible for | 983 | * Mark all buffers that cmd was responsible for |
998 | */ | 984 | */ |
999 | static inline void complete_command(cmdlist_t *cmd, int timeout) | 985 | static inline void complete_command(cmdlist_t *cmd, int timeout) |
1000 | { | 986 | { |
1001 | struct request *rq = cmd->rq; | 987 | struct request *rq = cmd->rq; |
1002 | int ok=1; | 988 | int error = 0; |
1003 | int i, ddir; | 989 | int i, ddir; |
1004 | 990 | ||
1005 | if (cmd->req.hdr.rcode & RCODE_NONFATAL && | 991 | if (cmd->req.hdr.rcode & RCODE_NONFATAL && |
@@ -1011,16 +997,17 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) | |||
1011 | if (cmd->req.hdr.rcode & RCODE_FATAL) { | 997 | if (cmd->req.hdr.rcode & RCODE_FATAL) { |
1012 | printk(KERN_WARNING "Fatal error on ida/c%dd%d\n", | 998 | printk(KERN_WARNING "Fatal error on ida/c%dd%d\n", |
1013 | cmd->ctlr, cmd->hdr.unit); | 999 | cmd->ctlr, cmd->hdr.unit); |
1014 | ok = 0; | 1000 | error = -EIO; |
1015 | } | 1001 | } |
1016 | if (cmd->req.hdr.rcode & RCODE_INVREQ) { | 1002 | if (cmd->req.hdr.rcode & RCODE_INVREQ) { |
1017 | printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n", | 1003 | printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n", |
1018 | cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd, | 1004 | cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd, |
1019 | cmd->req.hdr.blk, cmd->req.hdr.blk_cnt, | 1005 | cmd->req.hdr.blk, cmd->req.hdr.blk_cnt, |
1020 | cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode); | 1006 | cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode); |
1021 | ok = 0; | 1007 | error = -EIO; |
1022 | } | 1008 | } |
1023 | if (timeout) ok = 0; | 1009 | if (timeout) |
1010 | error = -EIO; | ||
1024 | /* unmap the DMA mapping for all the scatter gather elements */ | 1011 | /* unmap the DMA mapping for all the scatter gather elements */ |
1025 | if (cmd->req.hdr.cmd == IDA_READ) | 1012 | if (cmd->req.hdr.cmd == IDA_READ) |
1026 | ddir = PCI_DMA_FROMDEVICE; | 1013 | ddir = PCI_DMA_FROMDEVICE; |
@@ -1030,18 +1017,9 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) | |||
1030 | pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, | 1017 | pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, |
1031 | cmd->req.sg[i].size, ddir); | 1018 | cmd->req.sg[i].size, ddir); |
1032 | 1019 | ||
1033 | complete_buffers(rq->bio, ok); | ||
1034 | |||
1035 | if (blk_fs_request(rq)) { | ||
1036 | const int rw = rq_data_dir(rq); | ||
1037 | |||
1038 | disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors); | ||
1039 | } | ||
1040 | |||
1041 | add_disk_randomness(rq->rq_disk); | ||
1042 | |||
1043 | DBGPX(printk("Done with %p\n", rq);); | 1020 | DBGPX(printk("Done with %p\n", rq);); |
1044 | end_that_request_last(rq, ok ? 1 : -EIO); | 1021 | if (__blk_end_request(rq, error, blk_rq_bytes(rq))) |
1022 | BUG(); | ||
1045 | } | 1023 | } |
1046 | 1024 | ||
1047 | /* | 1025 | /* |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 639ed14bb08d..32c79a55511b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -2287,21 +2287,19 @@ static int do_format(int drive, struct format_descr *tmp_format_req) | |||
2287 | * ============================= | 2287 | * ============================= |
2288 | */ | 2288 | */ |
2289 | 2289 | ||
2290 | static void floppy_end_request(struct request *req, int uptodate) | 2290 | static void floppy_end_request(struct request *req, int error) |
2291 | { | 2291 | { |
2292 | unsigned int nr_sectors = current_count_sectors; | 2292 | unsigned int nr_sectors = current_count_sectors; |
2293 | unsigned int drive = (unsigned long)req->rq_disk->private_data; | ||
2293 | 2294 | ||
2294 | /* current_count_sectors can be zero if transfer failed */ | 2295 | /* current_count_sectors can be zero if transfer failed */ |
2295 | if (!uptodate) | 2296 | if (error) |
2296 | nr_sectors = req->current_nr_sectors; | 2297 | nr_sectors = req->current_nr_sectors; |
2297 | if (end_that_request_first(req, uptodate, nr_sectors)) | 2298 | if (__blk_end_request(req, error, nr_sectors << 9)) |
2298 | return; | 2299 | return; |
2299 | add_disk_randomness(req->rq_disk); | ||
2300 | floppy_off((long)req->rq_disk->private_data); | ||
2301 | blkdev_dequeue_request(req); | ||
2302 | end_that_request_last(req, uptodate); | ||
2303 | 2300 | ||
2304 | /* We're done with the request */ | 2301 | /* We're done with the request */ |
2302 | floppy_off(drive); | ||
2305 | current_req = NULL; | 2303 | current_req = NULL; |
2306 | } | 2304 | } |
2307 | 2305 | ||
@@ -2332,7 +2330,7 @@ static void request_done(int uptodate) | |||
2332 | 2330 | ||
2333 | /* unlock chained buffers */ | 2331 | /* unlock chained buffers */ |
2334 | spin_lock_irqsave(q->queue_lock, flags); | 2332 | spin_lock_irqsave(q->queue_lock, flags); |
2335 | floppy_end_request(req, 1); | 2333 | floppy_end_request(req, 0); |
2336 | spin_unlock_irqrestore(q->queue_lock, flags); | 2334 | spin_unlock_irqrestore(q->queue_lock, flags); |
2337 | } else { | 2335 | } else { |
2338 | if (rq_data_dir(req) == WRITE) { | 2336 | if (rq_data_dir(req) == WRITE) { |
@@ -2346,7 +2344,7 @@ static void request_done(int uptodate) | |||
2346 | DRWE->last_error_generation = DRS->generation; | 2344 | DRWE->last_error_generation = DRS->generation; |
2347 | } | 2345 | } |
2348 | spin_lock_irqsave(q->queue_lock, flags); | 2346 | spin_lock_irqsave(q->queue_lock, flags); |
2349 | floppy_end_request(req, 0); | 2347 | floppy_end_request(req, -EIO); |
2350 | spin_unlock_irqrestore(q->queue_lock, flags); | 2348 | spin_unlock_irqrestore(q->queue_lock, flags); |
2351 | } | 2349 | } |
2352 | } | 2350 | } |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index ba9b17e507e0..ae3106045ee5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -100,17 +100,15 @@ static const char *nbdcmd_to_ascii(int cmd) | |||
100 | 100 | ||
101 | static void nbd_end_request(struct request *req) | 101 | static void nbd_end_request(struct request *req) |
102 | { | 102 | { |
103 | int uptodate = (req->errors == 0) ? 1 : 0; | 103 | int error = req->errors ? -EIO : 0; |
104 | struct request_queue *q = req->q; | 104 | struct request_queue *q = req->q; |
105 | unsigned long flags; | 105 | unsigned long flags; |
106 | 106 | ||
107 | dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, | 107 | dprintk(DBG_BLKDEV, "%s: request %p: %s\n", req->rq_disk->disk_name, |
108 | req, uptodate? "done": "failed"); | 108 | req, error ? "failed" : "done"); |
109 | 109 | ||
110 | spin_lock_irqsave(q->queue_lock, flags); | 110 | spin_lock_irqsave(q->queue_lock, flags); |
111 | if (!end_that_request_first(req, uptodate, req->nr_sectors)) { | 111 | __blk_end_request(req, error, req->nr_sectors << 9); |
112 | end_that_request_last(req, uptodate); | ||
113 | } | ||
114 | spin_unlock_irqrestore(q->queue_lock, flags); | 112 | spin_unlock_irqrestore(q->queue_lock, flags); |
115 | } | 113 | } |
116 | 114 | ||
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index e354bfc070e1..7483f947f0e9 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c | |||
@@ -229,7 +229,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) | |||
229 | struct ps3_storage_device *dev = data; | 229 | struct ps3_storage_device *dev = data; |
230 | struct ps3disk_private *priv; | 230 | struct ps3disk_private *priv; |
231 | struct request *req; | 231 | struct request *req; |
232 | int res, read, uptodate; | 232 | int res, read, error; |
233 | u64 tag, status; | 233 | u64 tag, status; |
234 | unsigned long num_sectors; | 234 | unsigned long num_sectors; |
235 | const char *op; | 235 | const char *op; |
@@ -270,21 +270,17 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) | |||
270 | if (status) { | 270 | if (status) { |
271 | dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, | 271 | dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__, |
272 | __LINE__, op, status); | 272 | __LINE__, op, status); |
273 | uptodate = 0; | 273 | error = -EIO; |
274 | } else { | 274 | } else { |
275 | dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, | 275 | dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__, |
276 | __LINE__, op); | 276 | __LINE__, op); |
277 | uptodate = 1; | 277 | error = 0; |
278 | if (read) | 278 | if (read) |
279 | ps3disk_scatter_gather(dev, req, 0); | 279 | ps3disk_scatter_gather(dev, req, 0); |
280 | } | 280 | } |
281 | 281 | ||
282 | spin_lock(&priv->lock); | 282 | spin_lock(&priv->lock); |
283 | if (!end_that_request_first(req, uptodate, num_sectors)) { | 283 | __blk_end_request(req, error, num_sectors << 9); |
284 | add_disk_randomness(req->rq_disk); | ||
285 | blkdev_dequeue_request(req); | ||
286 | end_that_request_last(req, uptodate); | ||
287 | } | ||
288 | priv->req = NULL; | 284 | priv->req = NULL; |
289 | ps3disk_do_request(dev, priv->queue); | 285 | ps3disk_do_request(dev, priv->queue); |
290 | spin_unlock(&priv->lock); | 286 | spin_unlock(&priv->lock); |
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index fac4c6cd04f7..66e30155b0ab 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c | |||
@@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) | |||
212 | vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); | 212 | vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); |
213 | } | 213 | } |
214 | 214 | ||
215 | static void vdc_end_request(struct request *req, int uptodate, int num_sectors) | 215 | static void vdc_end_request(struct request *req, int error, int num_sectors) |
216 | { | 216 | { |
217 | if (end_that_request_first(req, uptodate, num_sectors)) | 217 | __blk_end_request(req, error, num_sectors << 9); |
218 | return; | ||
219 | add_disk_randomness(req->rq_disk); | ||
220 | end_that_request_last(req, uptodate); | ||
221 | } | 218 | } |
222 | 219 | ||
223 | static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, | 220 | static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, |
@@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, | |||
242 | 239 | ||
243 | rqe->req = NULL; | 240 | rqe->req = NULL; |
244 | 241 | ||
245 | vdc_end_request(req, !desc->status, desc->size >> 9); | 242 | vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9); |
246 | 243 | ||
247 | if (blk_queue_stopped(port->disk->queue)) | 244 | if (blk_queue_stopped(port->disk->queue)) |
248 | blk_start_queue(port->disk->queue); | 245 | blk_start_queue(port->disk->queue); |
@@ -456,7 +453,7 @@ static void do_vdc_request(struct request_queue *q) | |||
456 | 453 | ||
457 | blkdev_dequeue_request(req); | 454 | blkdev_dequeue_request(req); |
458 | if (__send_request(req) < 0) | 455 | if (__send_request(req) < 0) |
459 | vdc_end_request(req, 0, req->hard_nr_sectors); | 456 | vdc_end_request(req, -EIO, req->hard_nr_sectors); |
460 | } | 457 | } |
461 | } | 458 | } |
462 | 459 | ||
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 52dc5e131718..cd5674b63faf 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -744,16 +744,14 @@ static unsigned int carm_fill_get_fw_ver(struct carm_host *host, | |||
744 | 744 | ||
745 | static inline void carm_end_request_queued(struct carm_host *host, | 745 | static inline void carm_end_request_queued(struct carm_host *host, |
746 | struct carm_request *crq, | 746 | struct carm_request *crq, |
747 | int uptodate) | 747 | int error) |
748 | { | 748 | { |
749 | struct request *req = crq->rq; | 749 | struct request *req = crq->rq; |
750 | int rc; | 750 | int rc; |
751 | 751 | ||
752 | rc = end_that_request_first(req, uptodate, req->hard_nr_sectors); | 752 | rc = __blk_end_request(req, error, blk_rq_bytes(req)); |
753 | assert(rc == 0); | 753 | assert(rc == 0); |
754 | 754 | ||
755 | end_that_request_last(req, uptodate); | ||
756 | |||
757 | rc = carm_put_request(host, crq); | 755 | rc = carm_put_request(host, crq); |
758 | assert(rc == 0); | 756 | assert(rc == 0); |
759 | } | 757 | } |
@@ -793,9 +791,9 @@ static inline void carm_round_robin(struct carm_host *host) | |||
793 | } | 791 | } |
794 | 792 | ||
795 | static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, | 793 | static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq, |
796 | int is_ok) | 794 | int error) |
797 | { | 795 | { |
798 | carm_end_request_queued(host, crq, is_ok); | 796 | carm_end_request_queued(host, crq, error); |
799 | if (max_queue == 1) | 797 | if (max_queue == 1) |
800 | carm_round_robin(host); | 798 | carm_round_robin(host); |
801 | else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && | 799 | else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && |
@@ -873,14 +871,14 @@ queue_one_request: | |||
873 | sg = &crq->sg[0]; | 871 | sg = &crq->sg[0]; |
874 | n_elem = blk_rq_map_sg(q, rq, sg); | 872 | n_elem = blk_rq_map_sg(q, rq, sg); |
875 | if (n_elem <= 0) { | 873 | if (n_elem <= 0) { |
876 | carm_end_rq(host, crq, 0); | 874 | carm_end_rq(host, crq, -EIO); |
877 | return; /* request with no s/g entries? */ | 875 | return; /* request with no s/g entries? */ |
878 | } | 876 | } |
879 | 877 | ||
880 | /* map scatterlist to PCI bus addresses */ | 878 | /* map scatterlist to PCI bus addresses */ |
881 | n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); | 879 | n_elem = pci_map_sg(host->pdev, sg, n_elem, pci_dir); |
882 | if (n_elem <= 0) { | 880 | if (n_elem <= 0) { |
883 | carm_end_rq(host, crq, 0); | 881 | carm_end_rq(host, crq, -EIO); |
884 | return; /* request with no s/g entries? */ | 882 | return; /* request with no s/g entries? */ |
885 | } | 883 | } |
886 | crq->n_elem = n_elem; | 884 | crq->n_elem = n_elem; |
@@ -941,7 +939,7 @@ queue_one_request: | |||
941 | 939 | ||
942 | static void carm_handle_array_info(struct carm_host *host, | 940 | static void carm_handle_array_info(struct carm_host *host, |
943 | struct carm_request *crq, u8 *mem, | 941 | struct carm_request *crq, u8 *mem, |
944 | int is_ok) | 942 | int error) |
945 | { | 943 | { |
946 | struct carm_port *port; | 944 | struct carm_port *port; |
947 | u8 *msg_data = mem + sizeof(struct carm_array_info); | 945 | u8 *msg_data = mem + sizeof(struct carm_array_info); |
@@ -952,9 +950,9 @@ static void carm_handle_array_info(struct carm_host *host, | |||
952 | 950 | ||
953 | DPRINTK("ENTER\n"); | 951 | DPRINTK("ENTER\n"); |
954 | 952 | ||
955 | carm_end_rq(host, crq, is_ok); | 953 | carm_end_rq(host, crq, error); |
956 | 954 | ||
957 | if (!is_ok) | 955 | if (error) |
958 | goto out; | 956 | goto out; |
959 | if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) | 957 | if (le32_to_cpu(desc->array_status) & ARRAY_NO_EXIST) |
960 | goto out; | 958 | goto out; |
@@ -1001,7 +999,7 @@ out: | |||
1001 | 999 | ||
1002 | static void carm_handle_scan_chan(struct carm_host *host, | 1000 | static void carm_handle_scan_chan(struct carm_host *host, |
1003 | struct carm_request *crq, u8 *mem, | 1001 | struct carm_request *crq, u8 *mem, |
1004 | int is_ok) | 1002 | int error) |
1005 | { | 1003 | { |
1006 | u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; | 1004 | u8 *msg_data = mem + IOC_SCAN_CHAN_OFFSET; |
1007 | unsigned int i, dev_count = 0; | 1005 | unsigned int i, dev_count = 0; |
@@ -1009,9 +1007,9 @@ static void carm_handle_scan_chan(struct carm_host *host, | |||
1009 | 1007 | ||
1010 | DPRINTK("ENTER\n"); | 1008 | DPRINTK("ENTER\n"); |
1011 | 1009 | ||
1012 | carm_end_rq(host, crq, is_ok); | 1010 | carm_end_rq(host, crq, error); |
1013 | 1011 | ||
1014 | if (!is_ok) { | 1012 | if (error) { |
1015 | new_state = HST_ERROR; | 1013 | new_state = HST_ERROR; |
1016 | goto out; | 1014 | goto out; |
1017 | } | 1015 | } |
@@ -1033,23 +1031,23 @@ out: | |||
1033 | } | 1031 | } |
1034 | 1032 | ||
1035 | static void carm_handle_generic(struct carm_host *host, | 1033 | static void carm_handle_generic(struct carm_host *host, |
1036 | struct carm_request *crq, int is_ok, | 1034 | struct carm_request *crq, int error, |
1037 | int cur_state, int next_state) | 1035 | int cur_state, int next_state) |
1038 | { | 1036 | { |
1039 | DPRINTK("ENTER\n"); | 1037 | DPRINTK("ENTER\n"); |
1040 | 1038 | ||
1041 | carm_end_rq(host, crq, is_ok); | 1039 | carm_end_rq(host, crq, error); |
1042 | 1040 | ||
1043 | assert(host->state == cur_state); | 1041 | assert(host->state == cur_state); |
1044 | if (is_ok) | 1042 | if (error) |
1045 | host->state = next_state; | ||
1046 | else | ||
1047 | host->state = HST_ERROR; | 1043 | host->state = HST_ERROR; |
1044 | else | ||
1045 | host->state = next_state; | ||
1048 | schedule_work(&host->fsm_task); | 1046 | schedule_work(&host->fsm_task); |
1049 | } | 1047 | } |
1050 | 1048 | ||
1051 | static inline void carm_handle_rw(struct carm_host *host, | 1049 | static inline void carm_handle_rw(struct carm_host *host, |
1052 | struct carm_request *crq, int is_ok) | 1050 | struct carm_request *crq, int error) |
1053 | { | 1051 | { |
1054 | int pci_dir; | 1052 | int pci_dir; |
1055 | 1053 | ||
@@ -1062,7 +1060,7 @@ static inline void carm_handle_rw(struct carm_host *host, | |||
1062 | 1060 | ||
1063 | pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); | 1061 | pci_unmap_sg(host->pdev, &crq->sg[0], crq->n_elem, pci_dir); |
1064 | 1062 | ||
1065 | carm_end_rq(host, crq, is_ok); | 1063 | carm_end_rq(host, crq, error); |
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | static inline void carm_handle_resp(struct carm_host *host, | 1066 | static inline void carm_handle_resp(struct carm_host *host, |
@@ -1071,7 +1069,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1071 | u32 handle = le32_to_cpu(ret_handle_le); | 1069 | u32 handle = le32_to_cpu(ret_handle_le); |
1072 | unsigned int msg_idx; | 1070 | unsigned int msg_idx; |
1073 | struct carm_request *crq; | 1071 | struct carm_request *crq; |
1074 | int is_ok = (status == RMSG_OK); | 1072 | int error = (status == RMSG_OK) ? 0 : -EIO; |
1075 | u8 *mem; | 1073 | u8 *mem; |
1076 | 1074 | ||
1077 | VPRINTK("ENTER, handle == 0x%x\n", handle); | 1075 | VPRINTK("ENTER, handle == 0x%x\n", handle); |
@@ -1090,7 +1088,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1090 | /* fast path */ | 1088 | /* fast path */ |
1091 | if (likely(crq->msg_type == CARM_MSG_READ || | 1089 | if (likely(crq->msg_type == CARM_MSG_READ || |
1092 | crq->msg_type == CARM_MSG_WRITE)) { | 1090 | crq->msg_type == CARM_MSG_WRITE)) { |
1093 | carm_handle_rw(host, crq, is_ok); | 1091 | carm_handle_rw(host, crq, error); |
1094 | return; | 1092 | return; |
1095 | } | 1093 | } |
1096 | 1094 | ||
@@ -1100,7 +1098,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1100 | case CARM_MSG_IOCTL: { | 1098 | case CARM_MSG_IOCTL: { |
1101 | switch (crq->msg_subtype) { | 1099 | switch (crq->msg_subtype) { |
1102 | case CARM_IOC_SCAN_CHAN: | 1100 | case CARM_IOC_SCAN_CHAN: |
1103 | carm_handle_scan_chan(host, crq, mem, is_ok); | 1101 | carm_handle_scan_chan(host, crq, mem, error); |
1104 | break; | 1102 | break; |
1105 | default: | 1103 | default: |
1106 | /* unknown / invalid response */ | 1104 | /* unknown / invalid response */ |
@@ -1112,21 +1110,21 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1112 | case CARM_MSG_MISC: { | 1110 | case CARM_MSG_MISC: { |
1113 | switch (crq->msg_subtype) { | 1111 | switch (crq->msg_subtype) { |
1114 | case MISC_ALLOC_MEM: | 1112 | case MISC_ALLOC_MEM: |
1115 | carm_handle_generic(host, crq, is_ok, | 1113 | carm_handle_generic(host, crq, error, |
1116 | HST_ALLOC_BUF, HST_SYNC_TIME); | 1114 | HST_ALLOC_BUF, HST_SYNC_TIME); |
1117 | break; | 1115 | break; |
1118 | case MISC_SET_TIME: | 1116 | case MISC_SET_TIME: |
1119 | carm_handle_generic(host, crq, is_ok, | 1117 | carm_handle_generic(host, crq, error, |
1120 | HST_SYNC_TIME, HST_GET_FW_VER); | 1118 | HST_SYNC_TIME, HST_GET_FW_VER); |
1121 | break; | 1119 | break; |
1122 | case MISC_GET_FW_VER: { | 1120 | case MISC_GET_FW_VER: { |
1123 | struct carm_fw_ver *ver = (struct carm_fw_ver *) | 1121 | struct carm_fw_ver *ver = (struct carm_fw_ver *) |
1124 | mem + sizeof(struct carm_msg_get_fw_ver); | 1122 | mem + sizeof(struct carm_msg_get_fw_ver); |
1125 | if (is_ok) { | 1123 | if (!error) { |
1126 | host->fw_ver = le32_to_cpu(ver->version); | 1124 | host->fw_ver = le32_to_cpu(ver->version); |
1127 | host->flags |= (ver->features & FL_FW_VER_MASK); | 1125 | host->flags |= (ver->features & FL_FW_VER_MASK); |
1128 | } | 1126 | } |
1129 | carm_handle_generic(host, crq, is_ok, | 1127 | carm_handle_generic(host, crq, error, |
1130 | HST_GET_FW_VER, HST_PORT_SCAN); | 1128 | HST_GET_FW_VER, HST_PORT_SCAN); |
1131 | break; | 1129 | break; |
1132 | } | 1130 | } |
@@ -1140,7 +1138,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1140 | case CARM_MSG_ARRAY: { | 1138 | case CARM_MSG_ARRAY: { |
1141 | switch (crq->msg_subtype) { | 1139 | switch (crq->msg_subtype) { |
1142 | case CARM_ARRAY_INFO: | 1140 | case CARM_ARRAY_INFO: |
1143 | carm_handle_array_info(host, crq, mem, is_ok); | 1141 | carm_handle_array_info(host, crq, mem, error); |
1144 | break; | 1142 | break; |
1145 | default: | 1143 | default: |
1146 | /* unknown / invalid response */ | 1144 | /* unknown / invalid response */ |
@@ -1159,7 +1157,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1159 | err_out: | 1157 | err_out: |
1160 | printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", | 1158 | printk(KERN_WARNING DRV_NAME "(%s): BUG: unhandled message type %d/%d\n", |
1161 | pci_name(host->pdev), crq->msg_type, crq->msg_subtype); | 1159 | pci_name(host->pdev), crq->msg_type, crq->msg_subtype); |
1162 | carm_end_rq(host, crq, 0); | 1160 | carm_end_rq(host, crq, -EIO); |
1163 | } | 1161 | } |
1164 | 1162 | ||
1165 | static inline void carm_handle_responses(struct carm_host *host) | 1163 | static inline void carm_handle_responses(struct carm_host *host) |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 08e909dc7944..c6179d6ac6e4 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -808,16 +808,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
808 | 808 | ||
809 | static void ub_end_rq(struct request *rq, unsigned int scsi_status) | 809 | static void ub_end_rq(struct request *rq, unsigned int scsi_status) |
810 | { | 810 | { |
811 | int uptodate; | 811 | int error; |
812 | 812 | ||
813 | if (scsi_status == 0) { | 813 | if (scsi_status == 0) { |
814 | uptodate = 1; | 814 | error = 0; |
815 | } else { | 815 | } else { |
816 | uptodate = 0; | 816 | error = -EIO; |
817 | rq->errors = scsi_status; | 817 | rq->errors = scsi_status; |
818 | } | 818 | } |
819 | end_that_request_first(rq, uptodate, rq->hard_nr_sectors); | 819 | if (__blk_end_request(rq, error, blk_rq_bytes(rq))) |
820 | end_that_request_last(rq, uptodate); | 820 | BUG(); |
821 | } | 821 | } |
822 | 822 | ||
823 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, | 823 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, |
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ab5d404faa11..9e61fca46117 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -229,13 +229,10 @@ static struct block_device_operations viodasd_fops = { | |||
229 | /* | 229 | /* |
230 | * End a request | 230 | * End a request |
231 | */ | 231 | */ |
232 | static void viodasd_end_request(struct request *req, int uptodate, | 232 | static void viodasd_end_request(struct request *req, int error, |
233 | int num_sectors) | 233 | int num_sectors) |
234 | { | 234 | { |
235 | if (end_that_request_first(req, uptodate, num_sectors)) | 235 | __blk_end_request(req, error, num_sectors << 9); |
236 | return; | ||
237 | add_disk_randomness(req->rq_disk); | ||
238 | end_that_request_last(req, uptodate); | ||
239 | } | 236 | } |
240 | 237 | ||
241 | /* | 238 | /* |
@@ -374,12 +371,12 @@ static void do_viodasd_request(struct request_queue *q) | |||
374 | blkdev_dequeue_request(req); | 371 | blkdev_dequeue_request(req); |
375 | /* check that request contains a valid command */ | 372 | /* check that request contains a valid command */ |
376 | if (!blk_fs_request(req)) { | 373 | if (!blk_fs_request(req)) { |
377 | viodasd_end_request(req, 0, req->hard_nr_sectors); | 374 | viodasd_end_request(req, -EIO, req->hard_nr_sectors); |
378 | continue; | 375 | continue; |
379 | } | 376 | } |
380 | /* Try sending the request */ | 377 | /* Try sending the request */ |
381 | if (send_request(req) != 0) | 378 | if (send_request(req) != 0) |
382 | viodasd_end_request(req, 0, req->hard_nr_sectors); | 379 | viodasd_end_request(req, -EIO, req->hard_nr_sectors); |
383 | } | 380 | } |
384 | } | 381 | } |
385 | 382 | ||
@@ -591,7 +588,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) | |||
591 | num_req_outstanding--; | 588 | num_req_outstanding--; |
592 | spin_unlock_irqrestore(&viodasd_spinlock, irq_flags); | 589 | spin_unlock_irqrestore(&viodasd_spinlock, irq_flags); |
593 | 590 | ||
594 | error = event->xRc != HvLpEvent_Rc_Good; | 591 | error = (event->xRc == HvLpEvent_Rc_Good) ? 0 : -EIO; |
595 | if (error) { | 592 | if (error) { |
596 | const struct vio_error_entry *err; | 593 | const struct vio_error_entry *err; |
597 | err = vio_lookup_rc(viodasd_err_table, bevent->sub_result); | 594 | err = vio_lookup_rc(viodasd_err_table, bevent->sub_result); |
@@ -601,7 +598,7 @@ static int viodasd_handle_read_write(struct vioblocklpevent *bevent) | |||
601 | } | 598 | } |
602 | qlock = req->q->queue_lock; | 599 | qlock = req->q->queue_lock; |
603 | spin_lock_irqsave(qlock, irq_flags); | 600 | spin_lock_irqsave(qlock, irq_flags); |
604 | viodasd_end_request(req, !error, num_sect); | 601 | viodasd_end_request(req, error, num_sect); |
605 | spin_unlock_irqrestore(qlock, irq_flags); | 602 | spin_unlock_irqrestore(qlock, irq_flags); |
606 | 603 | ||
607 | /* Finally, try to get more requests off of this device's queue */ | 604 | /* Finally, try to get more requests off of this device's queue */ |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2bdebcb3ff16..8afce67c0aa5 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -452,7 +452,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) | |||
452 | RING_IDX i, rp; | 452 | RING_IDX i, rp; |
453 | unsigned long flags; | 453 | unsigned long flags; |
454 | struct blkfront_info *info = (struct blkfront_info *)dev_id; | 454 | struct blkfront_info *info = (struct blkfront_info *)dev_id; |
455 | int uptodate; | 455 | int error; |
456 | 456 | ||
457 | spin_lock_irqsave(&blkif_io_lock, flags); | 457 | spin_lock_irqsave(&blkif_io_lock, flags); |
458 | 458 | ||
@@ -477,13 +477,13 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) | |||
477 | 477 | ||
478 | add_id_to_freelist(info, id); | 478 | add_id_to_freelist(info, id); |
479 | 479 | ||
480 | uptodate = (bret->status == BLKIF_RSP_OKAY); | 480 | error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; |
481 | switch (bret->operation) { | 481 | switch (bret->operation) { |
482 | case BLKIF_OP_WRITE_BARRIER: | 482 | case BLKIF_OP_WRITE_BARRIER: |
483 | if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { | 483 | if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { |
484 | printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", | 484 | printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", |
485 | info->gd->disk_name); | 485 | info->gd->disk_name); |
486 | uptodate = -EOPNOTSUPP; | 486 | error = -EOPNOTSUPP; |
487 | info->feature_barrier = 0; | 487 | info->feature_barrier = 0; |
488 | xlvbd_barrier(info); | 488 | xlvbd_barrier(info); |
489 | } | 489 | } |
@@ -494,10 +494,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) | |||
494 | dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " | 494 | dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " |
495 | "request: %x\n", bret->status); | 495 | "request: %x\n", bret->status); |
496 | 496 | ||
497 | ret = end_that_request_first(req, uptodate, | 497 | ret = __blk_end_request(req, error, blk_rq_bytes(req)); |
498 | req->hard_nr_sectors); | ||
499 | BUG_ON(ret); | 498 | BUG_ON(ret); |
500 | end_that_request_last(req, uptodate); | ||
501 | break; | 499 | break; |
502 | default: | 500 | default: |
503 | BUG(); | 501 | BUG(); |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 82effce97c51..2c81465fd60c 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -703,7 +703,7 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
703 | 703 | ||
704 | /* bio finished; is there another one? */ | 704 | /* bio finished; is there another one? */ |
705 | i = ace->req->current_nr_sectors; | 705 | i = ace->req->current_nr_sectors; |
706 | if (end_that_request_first(ace->req, 1, i)) { | 706 | if (__blk_end_request(ace->req, 0, i)) { |
707 | /* dev_dbg(ace->dev, "next block; h=%li c=%i\n", | 707 | /* dev_dbg(ace->dev, "next block; h=%li c=%i\n", |
708 | * ace->req->hard_nr_sectors, | 708 | * ace->req->hard_nr_sectors, |
709 | * ace->req->current_nr_sectors); | 709 | * ace->req->current_nr_sectors); |
@@ -718,9 +718,6 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
718 | break; | 718 | break; |
719 | 719 | ||
720 | case ACE_FSM_STATE_REQ_COMPLETE: | 720 | case ACE_FSM_STATE_REQ_COMPLETE: |
721 | /* Complete the block request */ | ||
722 | blkdev_dequeue_request(ace->req); | ||
723 | end_that_request_last(ace->req, 1); | ||
724 | ace->req = NULL; | 721 | ace->req = NULL; |
725 | 722 | ||
726 | /* Finished request; go to idle state */ | 723 | /* Finished request; go to idle state */ |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index d8bb44b98a6a..8473b9f1da96 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -289,7 +289,7 @@ static int send_request(struct request *req) | |||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
291 | 291 | ||
292 | static void viocd_end_request(struct request *req, int uptodate) | 292 | static void viocd_end_request(struct request *req, int error) |
293 | { | 293 | { |
294 | int nsectors = req->hard_nr_sectors; | 294 | int nsectors = req->hard_nr_sectors; |
295 | 295 | ||
@@ -302,11 +302,8 @@ static void viocd_end_request(struct request *req, int uptodate) | |||
302 | if (!nsectors) | 302 | if (!nsectors) |
303 | nsectors = 1; | 303 | nsectors = 1; |
304 | 304 | ||
305 | if (end_that_request_first(req, uptodate, nsectors)) | 305 | if (__blk_end_request(req, error, nsectors << 9)) |
306 | BUG(); | 306 | BUG(); |
307 | add_disk_randomness(req->rq_disk); | ||
308 | blkdev_dequeue_request(req); | ||
309 | end_that_request_last(req, uptodate); | ||
310 | } | 307 | } |
311 | 308 | ||
312 | static int rwreq; | 309 | static int rwreq; |
@@ -317,11 +314,11 @@ static void do_viocd_request(struct request_queue *q) | |||
317 | 314 | ||
318 | while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) { | 315 | while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) { |
319 | if (!blk_fs_request(req)) | 316 | if (!blk_fs_request(req)) |
320 | viocd_end_request(req, 0); | 317 | viocd_end_request(req, -EIO); |
321 | else if (send_request(req) < 0) { | 318 | else if (send_request(req) < 0) { |
322 | printk(VIOCD_KERN_WARNING | 319 | printk(VIOCD_KERN_WARNING |
323 | "unable to send message to OS/400!"); | 320 | "unable to send message to OS/400!"); |
324 | viocd_end_request(req, 0); | 321 | viocd_end_request(req, -EIO); |
325 | } else | 322 | } else |
326 | rwreq++; | 323 | rwreq++; |
327 | } | 324 | } |
@@ -532,9 +529,9 @@ return_complete: | |||
532 | "with rc %d:0x%04X: %s\n", | 529 | "with rc %d:0x%04X: %s\n", |
533 | req, event->xRc, | 530 | req, event->xRc, |
534 | bevent->sub_result, err->msg); | 531 | bevent->sub_result, err->msg); |
535 | viocd_end_request(req, 0); | 532 | viocd_end_request(req, -EIO); |
536 | } else | 533 | } else |
537 | viocd_end_request(req, 1); | 534 | viocd_end_request(req, 0); |
538 | 535 | ||
539 | /* restart handling of incoming requests */ | 536 | /* restart handling of incoming requests */ |
540 | spin_unlock_irqrestore(&viocd_reqlock, flags); | 537 | spin_unlock_irqrestore(&viocd_reqlock, flags); |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 1ac5103f7c93..275dc522c738 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the HID driver | 2 | # Makefile for the HID driver |
3 | # | 3 | # |
4 | hid-objs := hid-core.o hid-input.o | 4 | hid-objs := hid-core.o hid-input.o hid-input-quirks.o |
5 | 5 | ||
6 | obj-$(CONFIG_HID) += hid.o | 6 | obj-$(CONFIG_HID) += hid.o |
7 | 7 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 2884b036495a..d73a768e176e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/sched.h> | ||
29 | 30 | ||
30 | #include <linux/hid.h> | 31 | #include <linux/hid.h> |
31 | #include <linux/hiddev.h> | 32 | #include <linux/hiddev.h> |
@@ -758,7 +759,9 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | |||
758 | { | 759 | { |
759 | u64 x; | 760 | u64 x; |
760 | 761 | ||
761 | WARN_ON(n > 32); | 762 | if (n > 32) |
763 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", | ||
764 | n, current->comm); | ||
762 | 765 | ||
763 | report += offset >> 3; /* adjust byte index */ | 766 | report += offset >> 3; /* adjust byte index */ |
764 | offset &= 7; /* now only need bit offset into one byte */ | 767 | offset &= 7; /* now only need bit offset into one byte */ |
@@ -780,8 +783,13 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3 | |||
780 | __le64 x; | 783 | __le64 x; |
781 | u64 m = (1ULL << n) - 1; | 784 | u64 m = (1ULL << n) - 1; |
782 | 785 | ||
783 | WARN_ON(n > 32); | 786 | if (n > 32) |
787 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", | ||
788 | n, current->comm); | ||
784 | 789 | ||
790 | if (value > m) | ||
791 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", | ||
792 | value, current->comm); | ||
785 | WARN_ON(value > m); | 793 | WARN_ON(value > m); |
786 | value &= m; | 794 | value &= m; |
787 | 795 | ||
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c new file mode 100644 index 000000000000..a870ba58faa3 --- /dev/null +++ b/drivers/hid/hid-input-quirks.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /* | ||
2 | * HID-input usage mapping quirks | ||
3 | * | ||
4 | * This is used to handle HID-input mappings for devices violating | ||
5 | * HUT 1.12 specification. | ||
6 | * | ||
7 | * Copyright (c) 2007-2008 Jiri Kosina | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/hid.h> | ||
18 | |||
19 | #define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0) | ||
20 | #define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0) | ||
21 | #define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0) | ||
22 | #define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0) | ||
23 | |||
24 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, *bit); } while (0) | ||
25 | #define map_key_clear(c) do { map_key(c); clear_bit(c, *bit); } while (0) | ||
26 | |||
27 | static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input, | ||
28 | unsigned long **bit, int *max) | ||
29 | { | ||
30 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
31 | return 0; | ||
32 | |||
33 | switch (usage->hid & HID_USAGE) { | ||
34 | case 0x03a: map_key_clear(KEY_SOUND); break; | ||
35 | case 0x03b: map_key_clear(KEY_CAMERA); break; | ||
36 | case 0x03c: map_key_clear(KEY_DOCUMENTS); break; | ||
37 | default: | ||
38 | return 0; | ||
39 | } | ||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input, | ||
44 | unsigned long **bit, int *max) | ||
45 | { | ||
46 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
47 | return 0; | ||
48 | |||
49 | switch (usage->hid & HID_USAGE) { | ||
50 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
51 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
52 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
53 | default: | ||
54 | return 0; | ||
55 | } | ||
56 | return 1; | ||
57 | } | ||
58 | |||
59 | static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input, | ||
60 | unsigned long **bit, int *max) | ||
61 | { | ||
62 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | ||
63 | return 0; | ||
64 | |||
65 | set_bit(EV_REP, input->evbit); | ||
66 | switch(usage->hid & HID_USAGE) { | ||
67 | /* Reported on Logitech Ultra X Media Remote */ | ||
68 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
69 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
70 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
71 | case 0x025: map_key_clear(KEY_TV); break; | ||
72 | case 0x026: map_key_clear(KEY_MENU); break; | ||
73 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
74 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
75 | case 0x033: map_key_clear(KEY_LAST); break; | ||
76 | case 0x047: map_key_clear(KEY_MP3); break; | ||
77 | case 0x048: map_key_clear(KEY_DVD); break; | ||
78 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
79 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
80 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
81 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
82 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
83 | case 0x051: map_key_clear(KEY_RED); break; | ||
84 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
85 | |||
86 | default: | ||
87 | return 0; | ||
88 | } | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, | ||
93 | unsigned long **bit, int *max) | ||
94 | { | ||
95 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
96 | return 0; | ||
97 | |||
98 | set_bit(EV_REP, input->evbit); | ||
99 | switch (usage->hid & HID_USAGE) { | ||
100 | case 0xff01: map_key_clear(BTN_1); break; | ||
101 | case 0xff02: map_key_clear(BTN_2); break; | ||
102 | case 0xff03: map_key_clear(BTN_3); break; | ||
103 | case 0xff04: map_key_clear(BTN_4); break; | ||
104 | case 0xff05: map_key_clear(BTN_5); break; | ||
105 | case 0xff06: map_key_clear(BTN_6); break; | ||
106 | case 0xff07: map_key_clear(BTN_7); break; | ||
107 | case 0xff08: map_key_clear(BTN_8); break; | ||
108 | case 0xff09: map_key_clear(BTN_9); break; | ||
109 | case 0xff0a: map_key_clear(BTN_A); break; | ||
110 | case 0xff0b: map_key_clear(BTN_B); break; | ||
111 | default: | ||
112 | return 0; | ||
113 | } | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input, | ||
118 | unsigned long **bit, int *max) | ||
119 | { | ||
120 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
121 | return 0; | ||
122 | |||
123 | switch(usage->hid & HID_USAGE) { | ||
124 | case 0xfd06: map_key_clear(KEY_CHAT); break; | ||
125 | case 0xfd07: map_key_clear(KEY_PHONE); break; | ||
126 | case 0xff05: | ||
127 | set_bit(EV_REP, input->evbit); | ||
128 | map_key_clear(KEY_F13); | ||
129 | set_bit(KEY_F14, input->keybit); | ||
130 | set_bit(KEY_F15, input->keybit); | ||
131 | set_bit(KEY_F16, input->keybit); | ||
132 | set_bit(KEY_F17, input->keybit); | ||
133 | set_bit(KEY_F18, input->keybit); | ||
134 | default: | ||
135 | return 0; | ||
136 | } | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input, | ||
141 | unsigned long **bit, int *max) | ||
142 | { | ||
143 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
144 | return 0; | ||
145 | |||
146 | set_bit(EV_REP, input->evbit); | ||
147 | switch(usage->hid & HID_USAGE) { | ||
148 | case 0xfd08: map_key_clear(KEY_FORWARD); break; | ||
149 | case 0xfd09: map_key_clear(KEY_BACK); break; | ||
150 | case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break; | ||
151 | case 0xfd0e: map_key_clear(KEY_CLOSE); break; | ||
152 | case 0xfd0f: map_key_clear(KEY_PLAY); break; | ||
153 | default: | ||
154 | return 0; | ||
155 | } | ||
156 | return 1; | ||
157 | } | ||
158 | |||
159 | static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input, | ||
160 | unsigned long **bit, int *max) | ||
161 | { | ||
162 | if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) && | ||
163 | ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)) | ||
164 | return 0; | ||
165 | |||
166 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) | ||
167 | switch(usage->hid & HID_USAGE) { | ||
168 | case 0x05a: map_key_clear(KEY_TEXT); break; | ||
169 | case 0x05b: map_key_clear(KEY_RED); break; | ||
170 | case 0x05c: map_key_clear(KEY_GREEN); break; | ||
171 | case 0x05d: map_key_clear(KEY_YELLOW); break; | ||
172 | case 0x05e: map_key_clear(KEY_BLUE); break; | ||
173 | default: | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) | ||
178 | switch(usage->hid & HID_USAGE) { | ||
179 | case 0x0f6: map_key_clear(KEY_NEXT); break; | ||
180 | case 0x0fa: map_key_clear(KEY_BACK); break; | ||
181 | default: | ||
182 | return 0; | ||
183 | } | ||
184 | return 1; | ||
185 | } | ||
186 | |||
187 | static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input, | ||
188 | unsigned long **bit, int *max) | ||
189 | { | ||
190 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
191 | return 0; | ||
192 | |||
193 | switch (usage->hid & HID_USAGE) { | ||
194 | case 0x1001: map_key_clear(KEY_MESSENGER); break; | ||
195 | case 0x1003: map_key_clear(KEY_SOUND); break; | ||
196 | case 0x1004: map_key_clear(KEY_VIDEO); break; | ||
197 | case 0x1005: map_key_clear(KEY_AUDIO); break; | ||
198 | case 0x100a: map_key_clear(KEY_DOCUMENTS); break; | ||
199 | case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; | ||
200 | case 0x1012: map_key_clear(KEY_NEXTSONG); break; | ||
201 | case 0x1013: map_key_clear(KEY_CAMERA); break; | ||
202 | case 0x1014: map_key_clear(KEY_MESSENGER); break; | ||
203 | case 0x1015: map_key_clear(KEY_RECORD); break; | ||
204 | case 0x1016: map_key_clear(KEY_PLAYER); break; | ||
205 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | ||
206 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
207 | case 0x1019: map_key_clear(KEY_PROG1); break; | ||
208 | case 0x101a: map_key_clear(KEY_PROG2); break; | ||
209 | case 0x101b: map_key_clear(KEY_PROG3); break; | ||
210 | case 0x101f: map_key_clear(KEY_ZOOMIN); break; | ||
211 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | ||
212 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | ||
213 | case 0x1023: map_key_clear(KEY_CLOSE); break; | ||
214 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
215 | /* this one is marked as 'Rotate' */ | ||
216 | case 0x1028: map_key_clear(KEY_ANGLE); break; | ||
217 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | ||
218 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
219 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
220 | case 0x1041: map_key_clear(KEY_BATTERY); break; | ||
221 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | ||
222 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | ||
223 | case 0x1044: map_key_clear(KEY_PRESENTATION); break; | ||
224 | case 0x1045: map_key_clear(KEY_UNDO); break; | ||
225 | case 0x1046: map_key_clear(KEY_REDO); break; | ||
226 | case 0x1047: map_key_clear(KEY_PRINT); break; | ||
227 | case 0x1048: map_key_clear(KEY_SAVE); break; | ||
228 | case 0x1049: map_key_clear(KEY_PROG1); break; | ||
229 | case 0x104a: map_key_clear(KEY_PROG2); break; | ||
230 | case 0x104b: map_key_clear(KEY_PROG3); break; | ||
231 | case 0x104c: map_key_clear(KEY_PROG4); break; | ||
232 | |||
233 | default: | ||
234 | return 0; | ||
235 | } | ||
236 | return 1; | ||
237 | } | ||
238 | |||
239 | static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input, | ||
240 | unsigned long **bit, int *max) | ||
241 | { | ||
242 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
243 | return 0; | ||
244 | |||
245 | switch (usage->hid & HID_USAGE) { | ||
246 | case 0x156: map_key_clear(KEY_WORDPROCESSOR); break; | ||
247 | case 0x157: map_key_clear(KEY_SPREADSHEET); break; | ||
248 | case 0x158: map_key_clear(KEY_PRESENTATION); break; | ||
249 | case 0x15c: map_key_clear(KEY_STOP); break; | ||
250 | |||
251 | default: | ||
252 | return 0; | ||
253 | } | ||
254 | return 1; | ||
255 | } | ||
256 | |||
257 | static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input, | ||
258 | unsigned long **bit, int *max) | ||
259 | { | ||
260 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
261 | return 0; | ||
262 | |||
263 | switch (usage->hid & HID_USAGE) { | ||
264 | case 0x230: map_key(BTN_MOUSE); break; | ||
265 | case 0x231: map_rel(REL_WHEEL); break; | ||
266 | /* | ||
267 | * this keyboard has a scrollwheel implemented in | ||
268 | * totally broken way. We map this usage temporarily | ||
269 | * to HWHEEL and handle it in the event quirk handler | ||
270 | */ | ||
271 | case 0x232: map_rel(REL_HWHEEL); break; | ||
272 | |||
273 | default: | ||
274 | return 0; | ||
275 | } | ||
276 | return 1; | ||
277 | } | ||
278 | |||
279 | #define VENDOR_ID_BELKIN 0x1020 | ||
280 | #define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006 | ||
281 | |||
282 | #define VENDOR_ID_CHERRY 0x046a | ||
283 | #define DEVICE_ID_CHERRY_CYMOTION 0x0023 | ||
284 | |||
285 | #define VENDOR_ID_CHICONY 0x04f2 | ||
286 | #define DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 | ||
287 | |||
288 | #define VENDOR_ID_EZKEY 0x0518 | ||
289 | #define DEVICE_ID_BTC_8193 0x0002 | ||
290 | |||
291 | #define VENDOR_ID_LOGITECH 0x046d | ||
292 | #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 | ||
293 | #define DEVICE_ID_S510_RECEIVER 0xc50c | ||
294 | #define DEVICE_ID_S510_RECEIVER_2 0xc517 | ||
295 | #define DEVICE_ID_MX3000_RECEIVER 0xc513 | ||
296 | |||
297 | #define VENDOR_ID_MICROSOFT 0x045e | ||
298 | #define DEVICE_ID_MS4K 0x00db | ||
299 | #define DEVICE_ID_MS6K 0x00f9 | ||
300 | #define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701 | ||
301 | #define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | ||
302 | |||
303 | #define VENDOR_ID_MONTEREY 0x0566 | ||
304 | #define DEVICE_ID_GENIUS_KB29E 0x3004 | ||
305 | |||
306 | #define VENDOR_ID_PETALYNX 0x18b1 | ||
307 | #define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | ||
308 | |||
309 | static const struct hid_input_blacklist { | ||
310 | __u16 idVendor; | ||
311 | __u16 idProduct; | ||
312 | int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *); | ||
313 | } hid_input_blacklist[] = { | ||
314 | { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd }, | ||
315 | |||
316 | { VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion }, | ||
317 | |||
318 | { VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad }, | ||
319 | |||
320 | { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, | ||
321 | |||
322 | { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, | ||
323 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, | ||
324 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, | ||
325 | { VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless }, | ||
326 | |||
327 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb }, | ||
328 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb }, | ||
329 | { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k }, | ||
330 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k }, | ||
331 | |||
332 | { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e }, | ||
333 | |||
334 | { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote }, | ||
335 | |||
336 | { 0, 0, 0 } | ||
337 | }; | ||
338 | |||
339 | int hidinput_mapping_quirks(struct hid_usage *usage, | ||
340 | struct input_dev *input, | ||
341 | unsigned long **bit, int *max) | ||
342 | { | ||
343 | struct hid_device *device = input_get_drvdata(input); | ||
344 | int i = 0; | ||
345 | |||
346 | while (hid_input_blacklist[i].quirk) { | ||
347 | if (hid_input_blacklist[i].idVendor == device->vendor && | ||
348 | hid_input_blacklist[i].idProduct == device->product) | ||
349 | return hid_input_blacklist[i].quirk(usage, input, bit, max); | ||
350 | i++; | ||
351 | } | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
356 | { | ||
357 | struct input_dev *input; | ||
358 | |||
359 | input = field->hidinput->input; | ||
360 | |||
361 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | ||
362 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | ||
363 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
364 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
369 | (usage->type == EV_REL) && | ||
370 | (usage->code == REL_WHEEL)) { | ||
371 | hid->delayed_value = value; | ||
372 | return; | ||
373 | } | ||
374 | |||
375 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
376 | (usage->hid == 0x000100b8)) { | ||
377 | input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); | ||
378 | return; | ||
379 | } | ||
380 | |||
381 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
382 | input_event(input, usage->type, usage->code, -value); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
387 | input_event(input, usage->type, REL_HWHEEL, value); | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) | ||
392 | return; | ||
393 | |||
394 | /* Handling MS keyboards special buttons */ | ||
395 | if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && | ||
396 | usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
397 | int key = 0; | ||
398 | static int last_key = 0; | ||
399 | switch (value) { | ||
400 | case 0x01: key = KEY_F14; break; | ||
401 | case 0x02: key = KEY_F15; break; | ||
402 | case 0x04: key = KEY_F16; break; | ||
403 | case 0x08: key = KEY_F17; break; | ||
404 | case 0x10: key = KEY_F18; break; | ||
405 | default: break; | ||
406 | } | ||
407 | if (key) { | ||
408 | input_event(input, usage->type, key, 1); | ||
409 | last_key = key; | ||
410 | } else { | ||
411 | input_event(input, usage->type, last_key, 0); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* handle the temporary quirky mapping to HWHEEL */ | ||
416 | if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && | ||
417 | usage->type == EV_REL && usage->code == REL_HWHEEL) { | ||
418 | input_event(input, usage->type, REL_WHEEL, -value); | ||
419 | return; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | |||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 0b27da7d7497..5325d98b4328 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/hid.h> | 34 | #include <linux/hid.h> |
35 | #include <linux/hid-debug.h> | 35 | #include <linux/hid-debug.h> |
36 | 36 | ||
37 | static int hid_pb_fnmode = 1; | 37 | static int hid_apple_fnmode = 1; |
38 | module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); | 38 | module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644); |
39 | MODULE_PARM_DESC(pb_fnmode, | 39 | MODULE_PARM_DESC(pb_fnmode, |
40 | "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); | 40 | "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); |
41 | 41 | ||
42 | #define unk KEY_UNKNOWN | 42 | #define unk KEY_UNKNOWN |
43 | 43 | ||
@@ -86,10 +86,6 @@ static const struct { | |||
86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) | 86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) |
87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) | 87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) |
88 | 88 | ||
89 | /* hardware needing special handling due to colliding MSVENDOR page usages */ | ||
90 | #define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418) | ||
91 | #define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9)) | ||
92 | |||
93 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 89 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
94 | 90 | ||
95 | struct hidinput_key_translation { | 91 | struct hidinput_key_translation { |
@@ -98,20 +94,36 @@ struct hidinput_key_translation { | |||
98 | u8 flags; | 94 | u8 flags; |
99 | }; | 95 | }; |
100 | 96 | ||
101 | #define POWERBOOK_FLAG_FKEY 0x01 | 97 | #define APPLE_FLAG_FKEY 0x01 |
98 | |||
99 | static struct hidinput_key_translation apple_fn_keys[] = { | ||
100 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | ||
101 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | ||
102 | { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */ | ||
103 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | ||
104 | { KEY_F5, KEY_FN_F5 }, | ||
105 | { KEY_F6, KEY_FN_F6 }, | ||
106 | { KEY_F7, KEY_BACK, APPLE_FLAG_FKEY }, | ||
107 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | ||
108 | { KEY_F9, KEY_FORWARD, APPLE_FLAG_FKEY }, | ||
109 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, | ||
110 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | ||
111 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | ||
112 | { } | ||
113 | }; | ||
102 | 114 | ||
103 | static struct hidinput_key_translation powerbook_fn_keys[] = { | 115 | static struct hidinput_key_translation powerbook_fn_keys[] = { |
104 | { KEY_BACKSPACE, KEY_DELETE }, | 116 | { KEY_BACKSPACE, KEY_DELETE }, |
105 | { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, | 117 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
106 | { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, | 118 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
107 | { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, | 119 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, |
108 | { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, | 120 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
109 | { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, | 121 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
110 | { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, | 122 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
111 | { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, | 123 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, |
112 | { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, | 124 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, |
113 | { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, | 125 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
114 | { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, | 126 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
115 | { KEY_UP, KEY_PAGEUP }, | 127 | { KEY_UP, KEY_PAGEUP }, |
116 | { KEY_DOWN, KEY_PAGEDOWN }, | 128 | { KEY_DOWN, KEY_PAGEDOWN }, |
117 | { KEY_LEFT, KEY_HOME }, | 129 | { KEY_LEFT, KEY_HOME }, |
@@ -142,7 +154,7 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { | |||
142 | { } | 154 | { } |
143 | }; | 155 | }; |
144 | 156 | ||
145 | static struct hidinput_key_translation powerbook_iso_keyboard[] = { | 157 | static struct hidinput_key_translation apple_iso_keyboard[] = { |
146 | { KEY_GRAVE, KEY_102ND }, | 158 | { KEY_GRAVE, KEY_102ND }, |
147 | { KEY_102ND, KEY_GRAVE }, | 159 | { KEY_102ND, KEY_GRAVE }, |
148 | { } | 160 | { } |
@@ -160,39 +172,42 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra | |||
160 | return NULL; | 172 | return NULL; |
161 | } | 173 | } |
162 | 174 | ||
163 | static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 175 | int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
164 | struct hid_usage *usage, __s32 value) | 176 | struct hid_usage *usage, __s32 value) |
165 | { | 177 | { |
166 | struct hidinput_key_translation *trans; | 178 | struct hidinput_key_translation *trans; |
167 | 179 | ||
168 | if (usage->code == KEY_FN) { | 180 | if (usage->code == KEY_FN) { |
169 | if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; | 181 | if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON; |
170 | else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; | 182 | else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON; |
171 | 183 | ||
172 | input_event(input, usage->type, usage->code, value); | 184 | input_event(input, usage->type, usage->code, value); |
173 | 185 | ||
174 | return 1; | 186 | return 1; |
175 | } | 187 | } |
176 | 188 | ||
177 | if (hid_pb_fnmode) { | 189 | if (hid_apple_fnmode) { |
178 | int do_translate; | 190 | int do_translate; |
179 | 191 | ||
180 | trans = find_translation(powerbook_fn_keys, usage->code); | 192 | trans = find_translation((hid->product < 0x220 || |
193 | hid->product >= 0x300) ? | ||
194 | powerbook_fn_keys : apple_fn_keys, | ||
195 | usage->code); | ||
181 | if (trans) { | 196 | if (trans) { |
182 | if (test_bit(usage->code, hid->pb_pressed_fn)) | 197 | if (test_bit(usage->code, hid->apple_pressed_fn)) |
183 | do_translate = 1; | 198 | do_translate = 1; |
184 | else if (trans->flags & POWERBOOK_FLAG_FKEY) | 199 | else if (trans->flags & APPLE_FLAG_FKEY) |
185 | do_translate = | 200 | do_translate = |
186 | (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || | 201 | (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) || |
187 | (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); | 202 | (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON)); |
188 | else | 203 | else |
189 | do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); | 204 | do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON); |
190 | 205 | ||
191 | if (do_translate) { | 206 | if (do_translate) { |
192 | if (value) | 207 | if (value) |
193 | set_bit(usage->code, hid->pb_pressed_fn); | 208 | set_bit(usage->code, hid->apple_pressed_fn); |
194 | else | 209 | else |
195 | clear_bit(usage->code, hid->pb_pressed_fn); | 210 | clear_bit(usage->code, hid->apple_pressed_fn); |
196 | 211 | ||
197 | input_event(input, usage->type, trans->to, value); | 212 | input_event(input, usage->type, trans->to, value); |
198 | 213 | ||
@@ -217,8 +232,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
217 | } | 232 | } |
218 | } | 233 | } |
219 | 234 | ||
220 | if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { | 235 | if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) { |
221 | trans = find_translation(powerbook_iso_keyboard, usage->code); | 236 | trans = find_translation(apple_iso_keyboard, usage->code); |
222 | if (trans) { | 237 | if (trans) { |
223 | input_event(input, usage->type, trans->to, value); | 238 | input_event(input, usage->type, trans->to, value); |
224 | return 1; | 239 | return 1; |
@@ -228,31 +243,35 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
228 | return 0; | 243 | return 0; |
229 | } | 244 | } |
230 | 245 | ||
231 | static void hidinput_pb_setup(struct input_dev *input) | 246 | static void hidinput_apple_setup(struct input_dev *input) |
232 | { | 247 | { |
233 | struct hidinput_key_translation *trans; | 248 | struct hidinput_key_translation *trans; |
234 | 249 | ||
235 | set_bit(KEY_NUMLOCK, input->keybit); | 250 | set_bit(KEY_NUMLOCK, input->keybit); |
236 | 251 | ||
237 | /* Enable all needed keys */ | 252 | /* Enable all needed keys */ |
253 | for (trans = apple_fn_keys; trans->from; trans++) | ||
254 | set_bit(trans->to, input->keybit); | ||
255 | |||
238 | for (trans = powerbook_fn_keys; trans->from; trans++) | 256 | for (trans = powerbook_fn_keys; trans->from; trans++) |
239 | set_bit(trans->to, input->keybit); | 257 | set_bit(trans->to, input->keybit); |
240 | 258 | ||
241 | for (trans = powerbook_numlock_keys; trans->from; trans++) | 259 | for (trans = powerbook_numlock_keys; trans->from; trans++) |
242 | set_bit(trans->to, input->keybit); | 260 | set_bit(trans->to, input->keybit); |
243 | 261 | ||
244 | for (trans = powerbook_iso_keyboard; trans->from; trans++) | 262 | for (trans = apple_iso_keyboard; trans->from; trans++) |
245 | set_bit(trans->to, input->keybit); | 263 | set_bit(trans->to, input->keybit); |
246 | 264 | ||
247 | } | 265 | } |
248 | #else | 266 | #else |
249 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 267 | inline int hidinput_apple_event(struct hid_device *hid, |
250 | struct hid_usage *usage, __s32 value) | 268 | struct input_dev *input, |
269 | struct hid_usage *usage, __s32 value) | ||
251 | { | 270 | { |
252 | return 0; | 271 | return 0; |
253 | } | 272 | } |
254 | 273 | ||
255 | static inline void hidinput_pb_setup(struct input_dev *input) | 274 | static inline void hidinput_apple_setup(struct input_dev *input) |
256 | { | 275 | { |
257 | } | 276 | } |
258 | #endif | 277 | #endif |
@@ -343,7 +362,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
343 | { | 362 | { |
344 | struct input_dev *input = hidinput->input; | 363 | struct input_dev *input = hidinput->input; |
345 | struct hid_device *device = input_get_drvdata(input); | 364 | struct hid_device *device = input_get_drvdata(input); |
346 | int max = 0, code; | 365 | int max = 0, code, ret; |
347 | unsigned long *bit = NULL; | 366 | unsigned long *bit = NULL; |
348 | 367 | ||
349 | field->hidinput = hidinput; | 368 | field->hidinput = hidinput; |
@@ -362,6 +381,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
362 | goto ignore; | 381 | goto ignore; |
363 | } | 382 | } |
364 | 383 | ||
384 | /* handle input mappings for quirky devices */ | ||
385 | ret = hidinput_mapping_quirks(usage, input, &bit, &max); | ||
386 | if (ret) | ||
387 | goto mapped; | ||
388 | |||
365 | switch (usage->hid & HID_USAGE_PAGE) { | 389 | switch (usage->hid & HID_USAGE_PAGE) { |
366 | 390 | ||
367 | case HID_UP_UNDEFINED: | 391 | case HID_UP_UNDEFINED: |
@@ -549,14 +573,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
549 | case 0x000: goto ignore; | 573 | case 0x000: goto ignore; |
550 | case 0x034: map_key_clear(KEY_SLEEP); break; | 574 | case 0x034: map_key_clear(KEY_SLEEP); break; |
551 | case 0x036: map_key_clear(BTN_MISC); break; | 575 | case 0x036: map_key_clear(BTN_MISC); break; |
552 | /* | ||
553 | * The next three are reported by Belkin wireless | ||
554 | * keyboard (1020:0006). These values are "reserved" | ||
555 | * in HUT 1.12. | ||
556 | */ | ||
557 | case 0x03a: map_key_clear(KEY_SOUND); break; | ||
558 | case 0x03b: map_key_clear(KEY_CAMERA); break; | ||
559 | case 0x03c: map_key_clear(KEY_DOCUMENTS); break; | ||
560 | 576 | ||
561 | case 0x040: map_key_clear(KEY_MENU); break; | 577 | case 0x040: map_key_clear(KEY_MENU); break; |
562 | case 0x045: map_key_clear(KEY_RADIO); break; | 578 | case 0x045: map_key_clear(KEY_RADIO); break; |
@@ -602,10 +618,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
602 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 618 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
603 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 619 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
604 | 620 | ||
605 | /* reserved in HUT 1.12. Reported on Petalynx remote */ | ||
606 | case 0x0f6: map_key_clear(KEY_NEXT); break; | ||
607 | case 0x0fa: map_key_clear(KEY_BACK); break; | ||
608 | |||
609 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; | 621 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; |
610 | case 0x183: map_key_clear(KEY_CONFIG); break; | 622 | case 0x183: map_key_clear(KEY_CONFIG); break; |
611 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; | 623 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; |
@@ -665,51 +677,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
665 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 677 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
666 | case 0x28c: map_key_clear(KEY_SEND); break; | 678 | case 0x28c: map_key_clear(KEY_SEND); break; |
667 | 679 | ||
668 | /* Reported on a Cherry Cymotion keyboard */ | ||
669 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
670 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
671 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
672 | |||
673 | /* Reported on certain Logitech wireless keyboards */ | ||
674 | case 0x1001: map_key_clear(KEY_MESSENGER); break; | ||
675 | case 0x1003: map_key_clear(KEY_SOUND); break; | ||
676 | case 0x1004: map_key_clear(KEY_VIDEO); break; | ||
677 | case 0x1005: map_key_clear(KEY_AUDIO); break; | ||
678 | case 0x100a: map_key_clear(KEY_DOCUMENTS); break; | ||
679 | case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; | ||
680 | case 0x1012: map_key_clear(KEY_NEXTSONG); break; | ||
681 | case 0x1013: map_key_clear(KEY_CAMERA); break; | ||
682 | case 0x1014: map_key_clear(KEY_MESSENGER); break; | ||
683 | case 0x1015: map_key_clear(KEY_RECORD); break; | ||
684 | case 0x1016: map_key_clear(KEY_PLAYER); break; | ||
685 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | ||
686 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
687 | case 0x1019: map_key_clear(KEY_PROG1); break; | ||
688 | case 0x101a: map_key_clear(KEY_PROG2); break; | ||
689 | case 0x101b: map_key_clear(KEY_PROG3); break; | ||
690 | case 0x101f: map_key_clear(KEY_ZOOMIN); break; | ||
691 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | ||
692 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | ||
693 | case 0x1023: map_key_clear(KEY_CLOSE); break; | ||
694 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
695 | /* this one is marked as 'Rotate' */ | ||
696 | case 0x1028: map_key_clear(KEY_ANGLE); break; | ||
697 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | ||
698 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
699 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
700 | case 0x1041: map_key_clear(KEY_BATTERY); break; | ||
701 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | ||
702 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | ||
703 | case 0x1044: map_key_clear(KEY_PRESENTATION); break; | ||
704 | case 0x1045: map_key_clear(KEY_UNDO); break; | ||
705 | case 0x1046: map_key_clear(KEY_REDO); break; | ||
706 | case 0x1047: map_key_clear(KEY_PRINT); break; | ||
707 | case 0x1048: map_key_clear(KEY_SAVE); break; | ||
708 | case 0x1049: map_key_clear(KEY_PROG1); break; | ||
709 | case 0x104a: map_key_clear(KEY_PROG2); break; | ||
710 | case 0x104b: map_key_clear(KEY_PROG3); break; | ||
711 | case 0x104c: map_key_clear(KEY_PROG4); break; | ||
712 | |||
713 | default: goto ignore; | 680 | default: goto ignore; |
714 | } | 681 | } |
715 | break; | 682 | break; |
@@ -736,63 +703,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
736 | 703 | ||
737 | case HID_UP_MSVENDOR: | 704 | case HID_UP_MSVENDOR: |
738 | 705 | ||
739 | /* Unfortunately, there are multiple devices which | 706 | goto ignore; |
740 | * emit usages from MSVENDOR page that require different | ||
741 | * handling. If this list grows too much in the future, | ||
742 | * more general handling will have to be introduced here | ||
743 | * (i.e. another blacklist). | ||
744 | */ | ||
745 | |||
746 | /* Chicony Chicony KU-0418 tactical pad */ | ||
747 | if (IS_CHICONY_TACTICAL_PAD(device)) { | ||
748 | set_bit(EV_REP, input->evbit); | ||
749 | switch(usage->hid & HID_USAGE) { | ||
750 | case 0xff01: map_key_clear(BTN_1); break; | ||
751 | case 0xff02: map_key_clear(BTN_2); break; | ||
752 | case 0xff03: map_key_clear(BTN_3); break; | ||
753 | case 0xff04: map_key_clear(BTN_4); break; | ||
754 | case 0xff05: map_key_clear(BTN_5); break; | ||
755 | case 0xff06: map_key_clear(BTN_6); break; | ||
756 | case 0xff07: map_key_clear(BTN_7); break; | ||
757 | case 0xff08: map_key_clear(BTN_8); break; | ||
758 | case 0xff09: map_key_clear(BTN_9); break; | ||
759 | case 0xff0a: map_key_clear(BTN_A); break; | ||
760 | case 0xff0b: map_key_clear(BTN_B); break; | ||
761 | default: goto ignore; | ||
762 | } | ||
763 | |||
764 | /* Microsoft Natural Ergonomic Keyboard 4000 */ | ||
765 | } else if (IS_MS_KB(device)) { | ||
766 | switch(usage->hid & HID_USAGE) { | ||
767 | case 0xfd06: | ||
768 | map_key_clear(KEY_CHAT); | ||
769 | break; | ||
770 | case 0xfd07: | ||
771 | map_key_clear(KEY_PHONE); | ||
772 | break; | ||
773 | case 0xff05: | ||
774 | set_bit(EV_REP, input->evbit); | ||
775 | map_key_clear(KEY_F13); | ||
776 | set_bit(KEY_F14, input->keybit); | ||
777 | set_bit(KEY_F15, input->keybit); | ||
778 | set_bit(KEY_F16, input->keybit); | ||
779 | set_bit(KEY_F17, input->keybit); | ||
780 | set_bit(KEY_F18, input->keybit); | ||
781 | default: goto ignore; | ||
782 | } | ||
783 | } else { | ||
784 | goto ignore; | ||
785 | } | ||
786 | break; | ||
787 | 707 | ||
788 | case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ | 708 | case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ |
789 | 709 | ||
790 | set_bit(EV_REP, input->evbit); | 710 | set_bit(EV_REP, input->evbit); |
791 | switch(usage->hid & HID_USAGE) { | 711 | switch(usage->hid & HID_USAGE) { |
792 | case 0x003: | 712 | case 0x003: |
793 | /* The fn key on Apple PowerBooks */ | 713 | /* The fn key on Apple USB keyboards */ |
794 | map_key_clear(KEY_FN); | 714 | map_key_clear(KEY_FN); |
795 | hidinput_pb_setup(input); | 715 | hidinput_apple_setup(input); |
796 | break; | 716 | break; |
797 | 717 | ||
798 | default: goto ignore; | 718 | default: goto ignore; |
@@ -800,38 +720,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
800 | break; | 720 | break; |
801 | 721 | ||
802 | case HID_UP_LOGIVENDOR: | 722 | case HID_UP_LOGIVENDOR: |
803 | set_bit(EV_REP, input->evbit); | ||
804 | switch(usage->hid & HID_USAGE) { | ||
805 | /* Reported on Logitech Ultra X Media Remote */ | ||
806 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
807 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
808 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
809 | case 0x025: map_key_clear(KEY_TV); break; | ||
810 | case 0x026: map_key_clear(KEY_MENU); break; | ||
811 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
812 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
813 | case 0x033: map_key_clear(KEY_LAST); break; | ||
814 | case 0x047: map_key_clear(KEY_MP3); break; | ||
815 | case 0x048: map_key_clear(KEY_DVD); break; | ||
816 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
817 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
818 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
819 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
820 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
821 | case 0x051: map_key_clear(KEY_RED); break; | ||
822 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
823 | |||
824 | /* Reported on Petalynx Maxter remote */ | ||
825 | case 0x05a: map_key_clear(KEY_TEXT); break; | ||
826 | case 0x05b: map_key_clear(KEY_RED); break; | ||
827 | case 0x05c: map_key_clear(KEY_GREEN); break; | ||
828 | case 0x05d: map_key_clear(KEY_YELLOW); break; | ||
829 | case 0x05e: map_key_clear(KEY_BLUE); break; | ||
830 | |||
831 | default: goto ignore; | ||
832 | } | ||
833 | break; | ||
834 | 723 | ||
724 | goto ignore; | ||
725 | |||
835 | case HID_UP_PID: | 726 | case HID_UP_PID: |
836 | 727 | ||
837 | switch(usage->hid & HID_USAGE) { | 728 | switch(usage->hid & HID_USAGE) { |
@@ -858,6 +749,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
858 | break; | 749 | break; |
859 | } | 750 | } |
860 | 751 | ||
752 | mapped: | ||
861 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { | 753 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { |
862 | if (usage->hid == HID_GD_Z) | 754 | if (usage->hid == HID_GD_Z) |
863 | map_rel(REL_HWHEEL); | 755 | map_rel(REL_HWHEEL); |
@@ -867,9 +759,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
867 | map_key(BTN_1); | 759 | map_key(BTN_1); |
868 | } | 760 | } |
869 | 761 | ||
870 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | 762 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | |
871 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | 763 | HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && |
872 | set_bit(REL_HWHEEL, bit); | 764 | (usage->code == REL_WHEEL)) |
765 | set_bit(REL_HWHEEL, bit); | ||
873 | 766 | ||
874 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 767 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) |
875 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) | 768 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) |
@@ -960,25 +853,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
960 | if (!usage->type) | 853 | if (!usage->type) |
961 | return; | 854 | return; |
962 | 855 | ||
963 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 856 | /* handle input events for quirky devices */ |
964 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | 857 | hidinput_event_quirks(hid, field, usage, value); |
965 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
966 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
967 | return; | ||
968 | } | ||
969 | |||
970 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
971 | input_event(input, usage->type, usage->code, -value); | ||
972 | return; | ||
973 | } | ||
974 | |||
975 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
976 | input_event(input, usage->type, REL_HWHEEL, value); | ||
977 | return; | ||
978 | } | ||
979 | |||
980 | if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) | ||
981 | return; | ||
982 | 858 | ||
983 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 859 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
984 | int hat_dir = usage->hat_dir; | 860 | int hat_dir = usage->hat_dir; |
@@ -1039,25 +915,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1039 | return; | 915 | return; |
1040 | } | 916 | } |
1041 | 917 | ||
1042 | /* Handling MS keyboards special buttons */ | ||
1043 | if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
1044 | int key = 0; | ||
1045 | static int last_key = 0; | ||
1046 | switch (value) { | ||
1047 | case 0x01: key = KEY_F14; break; | ||
1048 | case 0x02: key = KEY_F15; break; | ||
1049 | case 0x04: key = KEY_F16; break; | ||
1050 | case 0x08: key = KEY_F17; break; | ||
1051 | case 0x10: key = KEY_F18; break; | ||
1052 | default: break; | ||
1053 | } | ||
1054 | if (key) { | ||
1055 | input_event(input, usage->type, key, 1); | ||
1056 | last_key = key; | ||
1057 | } else { | ||
1058 | input_event(input, usage->type, last_key, 0); | ||
1059 | } | ||
1060 | } | ||
1061 | /* report the usage code as scancode if the key status has changed */ | 918 | /* report the usage code as scancode if the key status has changed */ |
1062 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 919 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
1063 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 920 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index c557d7040a69..7160fa65d79b 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig | |||
@@ -25,12 +25,13 @@ comment "Input core support is needed for USB HID input layer or HIDBP support" | |||
25 | depends on USB_HID && INPUT=n | 25 | depends on USB_HID && INPUT=n |
26 | 26 | ||
27 | config USB_HIDINPUT_POWERBOOK | 27 | config USB_HIDINPUT_POWERBOOK |
28 | bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys" | 28 | bool "Enable support for Apple laptop/aluminum USB special keys" |
29 | default n | 29 | default n |
30 | depends on USB_HID | 30 | depends on USB_HID |
31 | help | 31 | help |
32 | Say Y here if you want support for the special keys (Fn, Numlock) on | 32 | Say Y here if you want support for the special keys (Fn, Numlock) on |
33 | Apple iBooks, PowerBooks, MacBooks and MacBook Pros. | 33 | Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB |
34 | keyboards. | ||
34 | 35 | ||
35 | If unsure, say N. | 36 | If unsure, say N. |
36 | 37 | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a2552856476b..b77b61e0cd7b 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #define USB_VENDOR_ID_A4TECH 0x09da | 20 | #define USB_VENDOR_ID_A4TECH 0x09da |
21 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 21 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
22 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a | ||
22 | 23 | ||
23 | #define USB_VENDOR_ID_AASHIMA 0x06d6 | 24 | #define USB_VENDOR_ID_AASHIMA 0x06d6 |
24 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | 25 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 |
@@ -28,6 +29,9 @@ | |||
28 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | 29 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 |
29 | #define USB_DEVICE_ID_ACECAD_302 0x0008 | 30 | #define USB_DEVICE_ID_ACECAD_302 0x0008 |
30 | 31 | ||
32 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | ||
33 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | ||
34 | |||
31 | #define USB_VENDOR_ID_AIPTEK 0x08ca | 35 | #define USB_VENDOR_ID_AIPTEK 0x08ca |
32 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 | 36 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 |
33 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 | 37 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 |
@@ -59,6 +63,9 @@ | |||
59 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a | 63 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a |
60 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b | 64 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b |
61 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c | 65 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c |
66 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 | ||
67 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 | ||
68 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 | ||
62 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 69 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
63 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 70 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
64 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 | 71 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 |
@@ -94,6 +101,9 @@ | |||
94 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 | 101 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 |
95 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff | 102 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff |
96 | 103 | ||
104 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | ||
105 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | ||
106 | |||
97 | #define USB_VENDOR_ID_CYPRESS 0x04b4 | 107 | #define USB_VENDOR_ID_CYPRESS 0x04b4 |
98 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 | 108 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 |
99 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 109 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
@@ -114,6 +124,9 @@ | |||
114 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f | 124 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
115 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 | 125 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
116 | 126 | ||
127 | #define USB_VENDOR_ID_EZKEY 0x0518 | ||
128 | #define USB_DEVICE_ID_BTC_8193 0x0002 | ||
129 | |||
117 | #define USB_VENDOR_ID_GAMERON 0x0810 | 130 | #define USB_VENDOR_ID_GAMERON 0x0810 |
118 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 131 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
119 | 132 | ||
@@ -134,6 +147,9 @@ | |||
134 | #define USB_DEVICE_ID_GOGOPEN 0x00ce | 147 | #define USB_DEVICE_ID_GOGOPEN 0x00ce |
135 | #define USB_DEVICE_ID_PENPOWER 0x00f4 | 148 | #define USB_DEVICE_ID_PENPOWER 0x00f4 |
136 | 149 | ||
150 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 | ||
151 | #define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 | ||
152 | |||
137 | #define USB_VENDOR_ID_GRIFFIN 0x077d | 153 | #define USB_VENDOR_ID_GRIFFIN 0x077d |
138 | #define USB_DEVICE_ID_POWERMATE 0x0410 | 154 | #define USB_DEVICE_ID_POWERMATE 0x0410 |
139 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA | 155 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA |
@@ -278,7 +294,9 @@ | |||
278 | #define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d | 294 | #define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d |
279 | #define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e | 295 | #define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e |
280 | #define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f | 296 | #define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f |
297 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 | ||
281 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 | 298 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 |
299 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a | ||
282 | #define USB_DEVICE_ID_LOGITECH_KBD 0xc311 | 300 | #define USB_DEVICE_ID_LOGITECH_KBD 0xc311 |
283 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c | 301 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c |
284 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 | 302 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 |
@@ -296,6 +314,12 @@ | |||
296 | 314 | ||
297 | #define USB_VENDOR_ID_MICROSOFT 0x045e | 315 | #define USB_VENDOR_ID_MICROSOFT 0x045e |
298 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 316 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
317 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | ||
318 | #define USB_DEVICE_ID_MS_NE4K 0x00db | ||
319 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | ||
320 | |||
321 | #define USB_VENDOR_ID_MONTEREY 0x0566 | ||
322 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 | ||
299 | 323 | ||
300 | #define USB_VENDOR_ID_NCR 0x0404 | 324 | #define USB_VENDOR_ID_NCR 0x0404 |
301 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 | 325 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 |
@@ -324,6 +348,9 @@ | |||
324 | #define USB_VENDOR_ID_SAITEK 0x06a3 | 348 | #define USB_VENDOR_ID_SAITEK 0x06a3 |
325 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 | 349 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 |
326 | 350 | ||
351 | #define USB_VENDOR_ID_SAMSUNG 0x0419 | ||
352 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 | ||
353 | |||
327 | #define USB_VENDOR_ID_SONY 0x054c | 354 | #define USB_VENDOR_ID_SONY 0x054c |
328 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 355 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
329 | 356 | ||
@@ -368,6 +395,7 @@ static const struct hid_blacklist { | |||
368 | } hid_blacklist[] = { | 395 | } hid_blacklist[] = { |
369 | 396 | ||
370 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 397 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
398 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 }, | ||
371 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, | 399 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, |
372 | 400 | ||
373 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, | 401 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, |
@@ -390,6 +418,9 @@ static const struct hid_blacklist { | |||
390 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, | 418 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, |
391 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, | 419 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, |
392 | 420 | ||
421 | { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT }, | ||
422 | |||
423 | { USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X, HID_QUIRK_IGNORE }, | ||
393 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, | 424 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, |
394 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, | 425 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, |
395 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, | 426 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, |
@@ -402,6 +433,7 @@ static const struct hid_blacklist { | |||
402 | { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, | 433 | { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, |
403 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, | 434 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, |
404 | { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, | 435 | { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, |
436 | { USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X, HID_QUIRK_IGNORE }, | ||
405 | { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE }, | 437 | { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE }, |
406 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, | 438 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, |
407 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, | 439 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, |
@@ -423,6 +455,7 @@ static const struct hid_blacklist { | |||
423 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE }, | 455 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE }, |
424 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE }, | 456 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE }, |
425 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE }, | 457 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE }, |
458 | { USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY, HID_QUIRK_IGNORE }, | ||
426 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, | 459 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, |
427 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, | 460 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, |
428 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, | 461 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, |
@@ -516,14 +549,18 @@ static const struct hid_blacklist { | |||
516 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, | 549 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, |
517 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, | 550 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, |
518 | 551 | ||
552 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | ||
519 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 553 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
520 | 554 | ||
555 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, | ||
556 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, | ||
557 | |||
521 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, | 558 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, |
522 | 559 | ||
523 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 560 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
524 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 561 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
525 | 562 | ||
526 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, | 563 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV }, |
527 | 564 | ||
528 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 565 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
529 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 566 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
@@ -531,7 +568,9 @@ static const struct hid_blacklist { | |||
531 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, | 568 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, |
532 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, | 569 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, |
533 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 570 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
571 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET }, | ||
534 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, | 572 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, |
573 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET }, | ||
535 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, | 574 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, |
536 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 575 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
537 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 576 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
@@ -540,19 +579,22 @@ static const struct hid_blacklist { | |||
540 | 579 | ||
541 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 580 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
542 | 581 | ||
543 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 582 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
544 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 583 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
545 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 584 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
546 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 585 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
547 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 586 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
548 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 587 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
549 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 588 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
550 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 589 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
551 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 590 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
552 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 591 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
553 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 592 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
554 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 593 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, |
555 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 594 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
595 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, | ||
596 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | ||
597 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | ||
556 | 598 | ||
557 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, | 599 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, |
558 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, | 600 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, |
@@ -638,10 +680,14 @@ static const struct hid_rdesc_blacklist { | |||
638 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, | 680 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, |
639 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, | 681 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, |
640 | 682 | ||
683 | { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, | ||
684 | |||
641 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS }, | 685 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS }, |
642 | 686 | ||
643 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, | 687 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, |
644 | 688 | ||
689 | { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, | ||
690 | |||
645 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, | 691 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, |
646 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, | 692 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, |
647 | 693 | ||
@@ -884,6 +930,8 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) | |||
884 | return quirks; | 930 | return quirks; |
885 | } | 931 | } |
886 | 932 | ||
933 | EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); | ||
934 | |||
887 | /* | 935 | /* |
888 | * Cherry Cymotion keyboard have an invalid HID report descriptor, | 936 | * Cherry Cymotion keyboard have an invalid HID report descriptor, |
889 | * that needs fixing before we can parse it. | 937 | * that needs fixing before we can parse it. |
@@ -914,6 +962,33 @@ static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) | |||
914 | } | 962 | } |
915 | } | 963 | } |
916 | 964 | ||
965 | /* | ||
966 | * Samsung IrDA remote controller (reports as Cypress USB Mouse). | ||
967 | * | ||
968 | * Vendor specific report #4 has a size of 48 bit, | ||
969 | * and therefore is not accepted when inspecting the descriptors. | ||
970 | * As a workaround we reinterpret the report as: | ||
971 | * Variable type, count 6, size 8 bit, log. maximum 255 | ||
972 | * The burden to reconstruct the data is moved into user space. | ||
973 | */ | ||
974 | static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc, | ||
975 | int rsize) | ||
976 | { | ||
977 | if (rsize >= 182 && rdesc[175] == 0x25 | ||
978 | && rdesc[176] == 0x40 | ||
979 | && rdesc[177] == 0x75 | ||
980 | && rdesc[178] == 0x30 | ||
981 | && rdesc[179] == 0x95 | ||
982 | && rdesc[180] == 0x01 | ||
983 | && rdesc[182] == 0x40) { | ||
984 | printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n"); | ||
985 | rdesc[176] = 0xff; | ||
986 | rdesc[178] = 0x08; | ||
987 | rdesc[180] = 0x06; | ||
988 | rdesc[182] = 0x42; | ||
989 | } | ||
990 | } | ||
991 | |||
917 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ | 992 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ |
918 | static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) | 993 | static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) |
919 | { | 994 | { |
@@ -965,6 +1040,14 @@ static void usbhid_fixup_macbook_descriptor(unsigned char *rdesc, int rsize) | |||
965 | } | 1040 | } |
966 | } | 1041 | } |
967 | 1042 | ||
1043 | static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize) | ||
1044 | { | ||
1045 | if (rsize >= 30 && rdesc[29] == 0x05 | ||
1046 | && rdesc[30] == 0x09) { | ||
1047 | printk(KERN_INFO "Fixing up button/consumer in HID report descriptor\n"); | ||
1048 | rdesc[30] = 0x0c; | ||
1049 | } | ||
1050 | } | ||
968 | 1051 | ||
969 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) | 1052 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) |
970 | { | 1053 | { |
@@ -982,6 +1065,13 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned | |||
982 | 1065 | ||
983 | if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS) | 1066 | if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS) |
984 | usbhid_fixup_macbook_descriptor(rdesc, rsize); | 1067 | usbhid_fixup_macbook_descriptor(rdesc, rsize); |
1068 | |||
1069 | if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER) | ||
1070 | usbhid_fixup_button_consumer_descriptor(rdesc, rsize); | ||
1071 | |||
1072 | if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) | ||
1073 | usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); | ||
1074 | |||
985 | } | 1075 | } |
986 | 1076 | ||
987 | /** | 1077 | /** |
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c index 69882a726e99..144578b1a00c 100644 --- a/drivers/hid/usbhid/hid-tmff.c +++ b/drivers/hid/usbhid/hid-tmff.c | |||
@@ -137,7 +137,8 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef | |||
137 | int hid_tmff_init(struct hid_device *hid) | 137 | int hid_tmff_init(struct hid_device *hid) |
138 | { | 138 | { |
139 | struct tmff_device *tmff; | 139 | struct tmff_device *tmff; |
140 | struct list_head *pos; | 140 | struct hid_report *report; |
141 | struct list_head *report_list; | ||
141 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 142 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); |
142 | struct input_dev *input_dev = hidinput->input; | 143 | struct input_dev *input_dev = hidinput->input; |
143 | const signed short *ff_bits = ff_joystick; | 144 | const signed short *ff_bits = ff_joystick; |
@@ -149,8 +150,8 @@ int hid_tmff_init(struct hid_device *hid) | |||
149 | return -ENOMEM; | 150 | return -ENOMEM; |
150 | 151 | ||
151 | /* Find the report to use */ | 152 | /* Find the report to use */ |
152 | list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) { | 153 | report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
153 | struct hid_report *report = (struct hid_report *)pos; | 154 | list_for_each_entry(report, report_list, list) { |
154 | int fieldnum; | 155 | int fieldnum; |
155 | 156 | ||
156 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { | 157 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { |
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 775a1ef28a29..5d9dbb47e4a8 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c | |||
@@ -235,6 +235,14 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
235 | if (!usb_endpoint_is_int_in(endpoint)) | 235 | if (!usb_endpoint_is_int_in(endpoint)) |
236 | return -ENODEV; | 236 | return -ENODEV; |
237 | 237 | ||
238 | #ifdef CONFIG_USB_HID | ||
239 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
240 | le16_to_cpu(dev->descriptor.idProduct)) | ||
241 | & HID_QUIRK_IGNORE) { | ||
242 | return -ENODEV; | ||
243 | } | ||
244 | #endif | ||
245 | |||
238 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 246 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
239 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 247 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
240 | 248 | ||
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index f8ad6910d3d9..df0d96d989de 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c | |||
@@ -131,6 +131,14 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i | |||
131 | if (!usb_endpoint_is_int_in(endpoint)) | 131 | if (!usb_endpoint_is_int_in(endpoint)) |
132 | return -ENODEV; | 132 | return -ENODEV; |
133 | 133 | ||
134 | #ifdef CONFIG_USB_HID | ||
135 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
136 | le16_to_cpu(dev->descriptor.idProduct)) | ||
137 | & (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) { | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | #endif | ||
141 | |||
134 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 142 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
135 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 143 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
136 | 144 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 8d12b26bb6c6..b61f56b6f311 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -643,7 +643,7 @@ config I2C_PCA_ISA | |||
643 | 643 | ||
644 | config I2C_MV64XXX | 644 | config I2C_MV64XXX |
645 | tristate "Marvell mv64xxx I2C Controller" | 645 | tristate "Marvell mv64xxx I2C Controller" |
646 | depends on MV64X60 && EXPERIMENTAL | 646 | depends on (MV64X60 || ARCH_ORION) && EXPERIMENTAL |
647 | help | 647 | help |
648 | If you say yes to this option, support will be included for the | 648 | If you say yes to this option, support will be included for the |
649 | built-in I2C interface on the Marvell 64xxx line of host bridges. | 649 | built-in I2C interface on the Marvell 64xxx line of host bridges. |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index bb7bf68a7fb6..036e6a883e67 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for the i2c controller on the Marvell line of host bridges for MIPS | 2 | * Driver for the i2c controller on the Marvell line of host bridges |
3 | * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). | 3 | * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, and Orion SoC family). |
4 | * | 4 | * |
5 | * Author: Mark A. Greer <mgreer@mvista.com> | 5 | * Author: Mark A. Greer <mgreer@mvista.com> |
6 | * | 6 | * |
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/i2c.h> | 15 | #include <linux/i2c.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/mv643xx.h> | 17 | #include <linux/mv643xx_i2c.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
@@ -86,6 +86,7 @@ struct mv64xxx_i2c_data { | |||
86 | u32 cntl_bits; | 86 | u32 cntl_bits; |
87 | void __iomem *reg_base; | 87 | void __iomem *reg_base; |
88 | u32 reg_base_p; | 88 | u32 reg_base_p; |
89 | u32 reg_size; | ||
89 | u32 addr1; | 90 | u32 addr1; |
90 | u32 addr2; | 91 | u32 addr2; |
91 | u32 bytes_left; | 92 | u32 bytes_left; |
@@ -463,17 +464,20 @@ static int __devinit | |||
463 | mv64xxx_i2c_map_regs(struct platform_device *pd, | 464 | mv64xxx_i2c_map_regs(struct platform_device *pd, |
464 | struct mv64xxx_i2c_data *drv_data) | 465 | struct mv64xxx_i2c_data *drv_data) |
465 | { | 466 | { |
466 | struct resource *r; | 467 | int size; |
468 | struct resource *r = platform_get_resource(pd, IORESOURCE_MEM, 0); | ||
467 | 469 | ||
468 | if ((r = platform_get_resource(pd, IORESOURCE_MEM, 0)) && | 470 | if (!r) |
469 | request_mem_region(r->start, MV64XXX_I2C_REG_BLOCK_SIZE, | 471 | return -ENODEV; |
470 | drv_data->adapter.name)) { | ||
471 | 472 | ||
472 | drv_data->reg_base = ioremap(r->start, | 473 | size = r->end - r->start + 1; |
473 | MV64XXX_I2C_REG_BLOCK_SIZE); | 474 | |
474 | drv_data->reg_base_p = r->start; | 475 | if (!request_mem_region(r->start, size, drv_data->adapter.name)) |
475 | } else | 476 | return -EBUSY; |
476 | return -ENOMEM; | 477 | |
478 | drv_data->reg_base = ioremap(r->start, size); | ||
479 | drv_data->reg_base_p = r->start; | ||
480 | drv_data->reg_size = size; | ||
477 | 481 | ||
478 | return 0; | 482 | return 0; |
479 | } | 483 | } |
@@ -483,8 +487,7 @@ mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) | |||
483 | { | 487 | { |
484 | if (drv_data->reg_base) { | 488 | if (drv_data->reg_base) { |
485 | iounmap(drv_data->reg_base); | 489 | iounmap(drv_data->reg_base); |
486 | release_mem_region(drv_data->reg_base_p, | 490 | release_mem_region(drv_data->reg_base_p, drv_data->reg_size); |
487 | MV64XXX_I2C_REG_BLOCK_SIZE); | ||
488 | } | 491 | } |
489 | 492 | ||
490 | drv_data->reg_base = NULL; | 493 | drv_data->reg_base = NULL; |
@@ -529,7 +532,6 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
529 | drv_data->adapter.owner = THIS_MODULE; | 532 | drv_data->adapter.owner = THIS_MODULE; |
530 | drv_data->adapter.class = I2C_CLASS_HWMON; | 533 | drv_data->adapter.class = I2C_CLASS_HWMON; |
531 | drv_data->adapter.timeout = pdata->timeout; | 534 | drv_data->adapter.timeout = pdata->timeout; |
532 | drv_data->adapter.retries = pdata->retries; | ||
533 | drv_data->adapter.nr = pd->id; | 535 | drv_data->adapter.nr = pd->id; |
534 | platform_set_drvdata(pd, drv_data); | 536 | platform_set_drvdata(pd, drv_data); |
535 | i2c_set_adapdata(&drv_data->adapter, drv_data); | 537 | i2c_set_adapdata(&drv_data->adapter, drv_data); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 44b033ec0ab0..74c6087ada38 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -655,9 +655,9 @@ static void cdrom_end_request (ide_drive_t *drive, int uptodate) | |||
655 | BUG(); | 655 | BUG(); |
656 | } else { | 656 | } else { |
657 | spin_lock_irqsave(&ide_lock, flags); | 657 | spin_lock_irqsave(&ide_lock, flags); |
658 | end_that_request_chunk(failed, 0, | 658 | if (__blk_end_request(failed, -EIO, |
659 | failed->data_len); | 659 | failed->data_len)) |
660 | end_that_request_last(failed, 0); | 660 | BUG(); |
661 | spin_unlock_irqrestore(&ide_lock, flags); | 661 | spin_unlock_irqrestore(&ide_lock, flags); |
662 | } | 662 | } |
663 | } else | 663 | } else |
@@ -1647,6 +1647,17 @@ static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) | |||
1647 | return 1; | 1647 | return 1; |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | /* | ||
1651 | * Called from blk_end_request_callback() after the data of the request | ||
1652 | * is completed and before the request is completed. | ||
1653 | * By returning value '1', blk_end_request_callback() returns immediately | ||
1654 | * without completing the request. | ||
1655 | */ | ||
1656 | static int cdrom_newpc_intr_dummy_cb(struct request *rq) | ||
1657 | { | ||
1658 | return 1; | ||
1659 | } | ||
1660 | |||
1650 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); | 1661 | typedef void (xfer_func_t)(ide_drive_t *, void *, u32); |
1651 | 1662 | ||
1652 | /* | 1663 | /* |
@@ -1685,9 +1696,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1685 | return ide_error(drive, "dma error", stat); | 1696 | return ide_error(drive, "dma error", stat); |
1686 | } | 1697 | } |
1687 | 1698 | ||
1688 | end_that_request_chunk(rq, 1, rq->data_len); | 1699 | spin_lock_irqsave(&ide_lock, flags); |
1689 | rq->data_len = 0; | 1700 | if (__blk_end_request(rq, 0, rq->data_len)) |
1690 | goto end_request; | 1701 | BUG(); |
1702 | HWGROUP(drive)->rq = NULL; | ||
1703 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1704 | |||
1705 | return ide_stopped; | ||
1691 | } | 1706 | } |
1692 | 1707 | ||
1693 | /* | 1708 | /* |
@@ -1705,8 +1720,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1705 | /* | 1720 | /* |
1706 | * If DRQ is clear, the command has completed. | 1721 | * If DRQ is clear, the command has completed. |
1707 | */ | 1722 | */ |
1708 | if ((stat & DRQ_STAT) == 0) | 1723 | if ((stat & DRQ_STAT) == 0) { |
1709 | goto end_request; | 1724 | spin_lock_irqsave(&ide_lock, flags); |
1725 | if (__blk_end_request(rq, 0, 0)) | ||
1726 | BUG(); | ||
1727 | HWGROUP(drive)->rq = NULL; | ||
1728 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1729 | |||
1730 | return ide_stopped; | ||
1731 | } | ||
1710 | 1732 | ||
1711 | /* | 1733 | /* |
1712 | * check which way to transfer data | 1734 | * check which way to transfer data |
@@ -1759,7 +1781,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1759 | rq->data_len -= blen; | 1781 | rq->data_len -= blen; |
1760 | 1782 | ||
1761 | if (rq->bio) | 1783 | if (rq->bio) |
1762 | end_that_request_chunk(rq, 1, blen); | 1784 | /* |
1785 | * The request can't be completed until DRQ is cleared. | ||
1786 | * So complete the data, but don't complete the request | ||
1787 | * using the dummy function for the callback feature | ||
1788 | * of blk_end_request_callback(). | ||
1789 | */ | ||
1790 | blk_end_request_callback(rq, 0, blen, | ||
1791 | cdrom_newpc_intr_dummy_cb); | ||
1763 | else | 1792 | else |
1764 | rq->data += blen; | 1793 | rq->data += blen; |
1765 | } | 1794 | } |
@@ -1780,14 +1809,6 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
1780 | 1809 | ||
1781 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); | 1810 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); |
1782 | return ide_started; | 1811 | return ide_started; |
1783 | |||
1784 | end_request: | ||
1785 | spin_lock_irqsave(&ide_lock, flags); | ||
1786 | blkdev_dequeue_request(rq); | ||
1787 | end_that_request_last(rq, 1); | ||
1788 | HWGROUP(drive)->rq = NULL; | ||
1789 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1790 | return ide_stopped; | ||
1791 | } | 1812 | } |
1792 | 1813 | ||
1793 | static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) | 1814 | static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6f8f544392a8..e6bb9cf24e3d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -58,15 +58,19 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
58 | int uptodate, unsigned int nr_bytes, int dequeue) | 58 | int uptodate, unsigned int nr_bytes, int dequeue) |
59 | { | 59 | { |
60 | int ret = 1; | 60 | int ret = 1; |
61 | int error = 0; | ||
62 | |||
63 | if (uptodate <= 0) | ||
64 | error = uptodate ? uptodate : -EIO; | ||
61 | 65 | ||
62 | /* | 66 | /* |
63 | * if failfast is set on a request, override number of sectors and | 67 | * if failfast is set on a request, override number of sectors and |
64 | * complete the whole request right now | 68 | * complete the whole request right now |
65 | */ | 69 | */ |
66 | if (blk_noretry_request(rq) && end_io_error(uptodate)) | 70 | if (blk_noretry_request(rq) && error) |
67 | nr_bytes = rq->hard_nr_sectors << 9; | 71 | nr_bytes = rq->hard_nr_sectors << 9; |
68 | 72 | ||
69 | if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors) | 73 | if (!blk_fs_request(rq) && error && !rq->errors) |
70 | rq->errors = -EIO; | 74 | rq->errors = -EIO; |
71 | 75 | ||
72 | /* | 76 | /* |
@@ -78,14 +82,9 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
78 | ide_dma_on(drive); | 82 | ide_dma_on(drive); |
79 | } | 83 | } |
80 | 84 | ||
81 | if (!end_that_request_chunk(rq, uptodate, nr_bytes)) { | 85 | if (!__blk_end_request(rq, error, nr_bytes)) { |
82 | add_disk_randomness(rq->rq_disk); | 86 | if (dequeue) |
83 | if (dequeue) { | ||
84 | if (!list_empty(&rq->queuelist)) | ||
85 | blkdev_dequeue_request(rq); | ||
86 | HWGROUP(drive)->rq = NULL; | 87 | HWGROUP(drive)->rq = NULL; |
87 | } | ||
88 | end_that_request_last(rq, uptodate); | ||
89 | ret = 0; | 88 | ret = 0; |
90 | } | 89 | } |
91 | 90 | ||
@@ -290,9 +289,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | |||
290 | drive->blocked = 0; | 289 | drive->blocked = 0; |
291 | blk_start_queue(drive->queue); | 290 | blk_start_queue(drive->queue); |
292 | } | 291 | } |
293 | blkdev_dequeue_request(rq); | ||
294 | HWGROUP(drive)->rq = NULL; | 292 | HWGROUP(drive)->rq = NULL; |
295 | end_that_request_last(rq, 1); | 293 | if (__blk_end_request(rq, 0, 0)) |
294 | BUG(); | ||
296 | spin_unlock_irqrestore(&ide_lock, flags); | 295 | spin_unlock_irqrestore(&ide_lock, flags); |
297 | } | 296 | } |
298 | 297 | ||
@@ -387,10 +386,10 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
387 | } | 386 | } |
388 | 387 | ||
389 | spin_lock_irqsave(&ide_lock, flags); | 388 | spin_lock_irqsave(&ide_lock, flags); |
390 | blkdev_dequeue_request(rq); | ||
391 | HWGROUP(drive)->rq = NULL; | 389 | HWGROUP(drive)->rq = NULL; |
392 | rq->errors = err; | 390 | rq->errors = err; |
393 | end_that_request_last(rq, !rq->errors); | 391 | if (__blk_end_request(rq, (rq->errors ? -EIO : 0), 0)) |
392 | BUG(); | ||
394 | spin_unlock_irqrestore(&ide_lock, flags); | 393 | spin_unlock_irqrestore(&ide_lock, flags); |
395 | } | 394 | } |
396 | 395 | ||
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index b1b2e07bf080..99d92f5c93d6 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -74,10 +74,10 @@ extern unsigned int get_clk_frequency_khz(int info); | |||
74 | 74 | ||
75 | static unsigned long calc_waittime(struct corgi_ts *corgi_ts) | 75 | static unsigned long calc_waittime(struct corgi_ts *corgi_ts) |
76 | { | 76 | { |
77 | unsigned long hsync_len = corgi_ts->machinfo->get_hsync_len(); | 77 | unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod(); |
78 | 78 | ||
79 | if (hsync_len) | 79 | if (hsync_invperiod) |
80 | return get_clk_frequency_khz(0)*1000/hsync_len; | 80 | return get_clk_frequency_khz(0)*1000/hsync_invperiod; |
81 | else | 81 | else |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
@@ -114,7 +114,7 @@ static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, i | |||
114 | if (timer2-timer1 > wait_time) { | 114 | if (timer2-timer1 > wait_time) { |
115 | /* too slow - timeout, try again */ | 115 | /* too slow - timeout, try again */ |
116 | corgi_ts->machinfo->wait_hsync(); | 116 | corgi_ts->machinfo->wait_hsync(); |
117 | /* get OSCR */ | 117 | /* get CCNT */ |
118 | CCNT(timer1); | 118 | CCNT(timer1); |
119 | /* Wait after HSync */ | 119 | /* Wait after HSync */ |
120 | CCNT(timer2); | 120 | CCNT(timer2); |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index e4ad7a1c4fbd..a95314897402 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -412,13 +412,13 @@ static void i2o_block_delayed_request_fn(struct work_struct *work) | |||
412 | /** | 412 | /** |
413 | * i2o_block_end_request - Post-processing of completed commands | 413 | * i2o_block_end_request - Post-processing of completed commands |
414 | * @req: request which should be completed | 414 | * @req: request which should be completed |
415 | * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error | 415 | * @error: 0 for success, < 0 for error |
416 | * @nr_bytes: number of bytes to complete | 416 | * @nr_bytes: number of bytes to complete |
417 | * | 417 | * |
418 | * Mark the request as complete. The lock must not be held when entering. | 418 | * Mark the request as complete. The lock must not be held when entering. |
419 | * | 419 | * |
420 | */ | 420 | */ |
421 | static void i2o_block_end_request(struct request *req, int uptodate, | 421 | static void i2o_block_end_request(struct request *req, int error, |
422 | int nr_bytes) | 422 | int nr_bytes) |
423 | { | 423 | { |
424 | struct i2o_block_request *ireq = req->special; | 424 | struct i2o_block_request *ireq = req->special; |
@@ -426,22 +426,18 @@ static void i2o_block_end_request(struct request *req, int uptodate, | |||
426 | struct request_queue *q = req->q; | 426 | struct request_queue *q = req->q; |
427 | unsigned long flags; | 427 | unsigned long flags; |
428 | 428 | ||
429 | if (end_that_request_chunk(req, uptodate, nr_bytes)) { | 429 | if (blk_end_request(req, error, nr_bytes)) { |
430 | int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT); | 430 | int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT); |
431 | 431 | ||
432 | if (blk_pc_request(req)) | 432 | if (blk_pc_request(req)) |
433 | leftover = req->data_len; | 433 | leftover = req->data_len; |
434 | 434 | ||
435 | if (end_io_error(uptodate)) | 435 | if (error) |
436 | end_that_request_chunk(req, 0, leftover); | 436 | blk_end_request(req, -EIO, leftover); |
437 | } | 437 | } |
438 | 438 | ||
439 | add_disk_randomness(req->rq_disk); | ||
440 | |||
441 | spin_lock_irqsave(q->queue_lock, flags); | 439 | spin_lock_irqsave(q->queue_lock, flags); |
442 | 440 | ||
443 | end_that_request_last(req, uptodate); | ||
444 | |||
445 | if (likely(dev)) { | 441 | if (likely(dev)) { |
446 | dev->open_queue_depth--; | 442 | dev->open_queue_depth--; |
447 | list_del(&ireq->queue); | 443 | list_del(&ireq->queue); |
@@ -468,7 +464,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, | |||
468 | struct i2o_message *msg) | 464 | struct i2o_message *msg) |
469 | { | 465 | { |
470 | struct request *req; | 466 | struct request *req; |
471 | int uptodate = 1; | 467 | int error = 0; |
472 | 468 | ||
473 | req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); | 469 | req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); |
474 | if (unlikely(!req)) { | 470 | if (unlikely(!req)) { |
@@ -501,10 +497,10 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, | |||
501 | 497 | ||
502 | req->errors++; | 498 | req->errors++; |
503 | 499 | ||
504 | uptodate = 0; | 500 | error = -EIO; |
505 | } | 501 | } |
506 | 502 | ||
507 | i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1])); | 503 | i2o_block_end_request(req, error, le32_to_cpu(msg->body[1])); |
508 | 504 | ||
509 | return 1; | 505 | return 1; |
510 | }; | 506 | }; |
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index b7c8e7813865..61aeaf79640d 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "ucb1x00.h" | 20 | #include "ucb1x00.h" |
21 | 21 | ||
22 | #define UCB1X00_ATTR(name,input)\ | 22 | #define UCB1X00_ATTR(name,input)\ |
23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, | 23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ |
24 | char *buf) \ | 24 | char *buf) \ |
25 | { \ | 25 | { \ |
26 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ | 26 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ |
@@ -38,17 +38,17 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); | |||
38 | 38 | ||
39 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) | 39 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) |
40 | { | 40 | { |
41 | device_create_file(&dev->ucb->dev, &device_attr_vbatt); | 41 | device_create_file(&dev->ucb->dev, &dev_attr_vbatt); |
42 | device_create_file(&dev->ucb->dev, &device_attr_vcharger); | 42 | device_create_file(&dev->ucb->dev, &dev_attr_vcharger); |
43 | device_create_file(&dev->ucb->dev, &device_attr_batt_temp); | 43 | device_create_file(&dev->ucb->dev, &dev_attr_batt_temp); |
44 | return 0; | 44 | return 0; |
45 | } | 45 | } |
46 | 46 | ||
47 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) | 47 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) |
48 | { | 48 | { |
49 | device_remove_file(&dev->ucb->cdev, &device_attr_batt_temp); | 49 | device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); |
50 | device_remove_file(&dev->ucb->cdev, &device_attr_vcharger); | 50 | device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); |
51 | device_remove_file(&dev->ucb->cdev, &device_attr_vbatt); | 51 | device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); |
52 | } | 52 | } |
53 | 53 | ||
54 | static struct ucb1x00_driver ucb1x00_assabet_driver = { | 54 | static struct ucb1x00_driver ucb1x00_assabet_driver = { |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index aeb32a93f6a0..91ded3e82401 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -348,15 +348,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
348 | * A block was successfully transferred. | 348 | * A block was successfully transferred. |
349 | */ | 349 | */ |
350 | spin_lock_irq(&md->lock); | 350 | spin_lock_irq(&md->lock); |
351 | ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); | 351 | ret = __blk_end_request(req, 0, brq.data.bytes_xfered); |
352 | if (!ret) { | ||
353 | /* | ||
354 | * The whole request completed successfully. | ||
355 | */ | ||
356 | add_disk_randomness(req->rq_disk); | ||
357 | blkdev_dequeue_request(req); | ||
358 | end_that_request_last(req, 1); | ||
359 | } | ||
360 | spin_unlock_irq(&md->lock); | 352 | spin_unlock_irq(&md->lock); |
361 | } while (ret); | 353 | } while (ret); |
362 | 354 | ||
@@ -386,27 +378,21 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
386 | else | 378 | else |
387 | bytes = blocks << 9; | 379 | bytes = blocks << 9; |
388 | spin_lock_irq(&md->lock); | 380 | spin_lock_irq(&md->lock); |
389 | ret = end_that_request_chunk(req, 1, bytes); | 381 | ret = __blk_end_request(req, 0, bytes); |
390 | spin_unlock_irq(&md->lock); | 382 | spin_unlock_irq(&md->lock); |
391 | } | 383 | } |
392 | } else if (rq_data_dir(req) != READ && | 384 | } else if (rq_data_dir(req) != READ && |
393 | (card->host->caps & MMC_CAP_MULTIWRITE)) { | 385 | (card->host->caps & MMC_CAP_MULTIWRITE)) { |
394 | spin_lock_irq(&md->lock); | 386 | spin_lock_irq(&md->lock); |
395 | ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered); | 387 | ret = __blk_end_request(req, 0, brq.data.bytes_xfered); |
396 | spin_unlock_irq(&md->lock); | 388 | spin_unlock_irq(&md->lock); |
397 | } | 389 | } |
398 | 390 | ||
399 | mmc_release_host(card->host); | 391 | mmc_release_host(card->host); |
400 | 392 | ||
401 | spin_lock_irq(&md->lock); | 393 | spin_lock_irq(&md->lock); |
402 | while (ret) { | 394 | while (ret) |
403 | ret = end_that_request_chunk(req, 0, | 395 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); |
404 | req->current_nr_sectors << 9); | ||
405 | } | ||
406 | |||
407 | add_disk_randomness(req->rq_disk); | ||
408 | blkdev_dequeue_request(req); | ||
409 | end_that_request_last(req, 0); | ||
410 | spin_unlock_irq(&md->lock); | 396 | spin_unlock_irq(&md->lock); |
411 | 397 | ||
412 | return 0; | 398 | return 0; |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 30cd13b13ac3..7731ddefdc1b 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -94,8 +94,8 @@ static void mmc_request(struct request_queue *q) | |||
94 | printk(KERN_ERR "MMC: killing requests for dead queue\n"); | 94 | printk(KERN_ERR "MMC: killing requests for dead queue\n"); |
95 | while ((req = elv_next_request(q)) != NULL) { | 95 | while ((req = elv_next_request(q)) != NULL) { |
96 | do { | 96 | do { |
97 | ret = end_that_request_chunk(req, 0, | 97 | ret = __blk_end_request(req, -EIO, |
98 | req->current_nr_sectors << 9); | 98 | blk_rq_cur_bytes(req)); |
99 | } while (ret); | 99 | } while (ret); |
100 | } | 100 | } |
101 | return; | 101 | return; |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 1654a3330340..1ea8482037bb 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -65,6 +65,8 @@ struct pxamci_host { | |||
65 | unsigned int dma_len; | 65 | unsigned int dma_len; |
66 | 66 | ||
67 | unsigned int dma_dir; | 67 | unsigned int dma_dir; |
68 | unsigned int dma_drcmrrx; | ||
69 | unsigned int dma_drcmrtx; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | static void pxamci_stop_clock(struct pxamci_host *host) | 72 | static void pxamci_stop_clock(struct pxamci_host *host) |
@@ -131,13 +133,13 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | |||
131 | if (data->flags & MMC_DATA_READ) { | 133 | if (data->flags & MMC_DATA_READ) { |
132 | host->dma_dir = DMA_FROM_DEVICE; | 134 | host->dma_dir = DMA_FROM_DEVICE; |
133 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; | 135 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; |
134 | DRCMRTXMMC = 0; | 136 | DRCMR(host->dma_drcmrtx) = 0; |
135 | DRCMRRXMMC = host->dma | DRCMR_MAPVLD; | 137 | DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; |
136 | } else { | 138 | } else { |
137 | host->dma_dir = DMA_TO_DEVICE; | 139 | host->dma_dir = DMA_TO_DEVICE; |
138 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; | 140 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; |
139 | DRCMRRXMMC = 0; | 141 | DRCMR(host->dma_drcmrrx) = 0; |
140 | DRCMRTXMMC = host->dma | DRCMR_MAPVLD; | 142 | DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; |
141 | } | 143 | } |
142 | 144 | ||
143 | dcmd |= DCMD_BURST32 | DCMD_WIDTH1; | 145 | dcmd |= DCMD_BURST32 | DCMD_WIDTH1; |
@@ -375,14 +377,23 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
375 | if (host->clkrt == CLKRT_OFF) | 377 | if (host->clkrt == CLKRT_OFF) |
376 | clk_enable(host->clk); | 378 | clk_enable(host->clk); |
377 | 379 | ||
378 | /* | 380 | if (ios->clock == 26000000) { |
379 | * clk might result in a lower divisor than we | 381 | /* to support 26MHz on pxa300/pxa310 */ |
380 | * desire. check for that condition and adjust | 382 | host->clkrt = 7; |
381 | * as appropriate. | 383 | } else { |
382 | */ | 384 | /* to handle (19.5MHz, 26MHz) */ |
383 | if (rate / clk > ios->clock) | 385 | if (!clk) |
384 | clk <<= 1; | 386 | clk = 1; |
385 | host->clkrt = fls(clk) - 1; | 387 | |
388 | /* | ||
389 | * clk might result in a lower divisor than we | ||
390 | * desire. check for that condition and adjust | ||
391 | * as appropriate. | ||
392 | */ | ||
393 | if (rate / clk > ios->clock) | ||
394 | clk <<= 1; | ||
395 | host->clkrt = fls(clk) - 1; | ||
396 | } | ||
386 | 397 | ||
387 | /* | 398 | /* |
388 | * we write clkrt on the next command | 399 | * we write clkrt on the next command |
@@ -459,7 +470,7 @@ static int pxamci_probe(struct platform_device *pdev) | |||
459 | { | 470 | { |
460 | struct mmc_host *mmc; | 471 | struct mmc_host *mmc; |
461 | struct pxamci_host *host = NULL; | 472 | struct pxamci_host *host = NULL; |
462 | struct resource *r; | 473 | struct resource *r, *dmarx, *dmatx; |
463 | int ret, irq; | 474 | int ret, irq; |
464 | 475 | ||
465 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 476 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -519,7 +530,8 @@ static int pxamci_probe(struct platform_device *pdev) | |||
519 | * Calculate minimum clock rate, rounding up. | 530 | * Calculate minimum clock rate, rounding up. |
520 | */ | 531 | */ |
521 | mmc->f_min = (host->clkrate + 63) / 64; | 532 | mmc->f_min = (host->clkrate + 63) / 64; |
522 | mmc->f_max = host->clkrate; | 533 | mmc->f_max = (cpu_is_pxa300() || cpu_is_pxa310()) ? 26000000 |
534 | : host->clkrate; | ||
523 | 535 | ||
524 | mmc->ocr_avail = host->pdata ? | 536 | mmc->ocr_avail = host->pdata ? |
525 | host->pdata->ocr_mask : | 537 | host->pdata->ocr_mask : |
@@ -529,6 +541,9 @@ static int pxamci_probe(struct platform_device *pdev) | |||
529 | if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) { | 541 | if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) { |
530 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 542 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
531 | host->cmdat |= CMDAT_SDIO_INT_EN; | 543 | host->cmdat |= CMDAT_SDIO_INT_EN; |
544 | if (cpu_is_pxa300() || cpu_is_pxa310()) | ||
545 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | | ||
546 | MMC_CAP_SD_HIGHSPEED; | ||
532 | } | 547 | } |
533 | 548 | ||
534 | host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); | 549 | host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); |
@@ -570,6 +585,20 @@ static int pxamci_probe(struct platform_device *pdev) | |||
570 | 585 | ||
571 | platform_set_drvdata(pdev, mmc); | 586 | platform_set_drvdata(pdev, mmc); |
572 | 587 | ||
588 | dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
589 | if (!dmarx) { | ||
590 | ret = -ENXIO; | ||
591 | goto out; | ||
592 | } | ||
593 | host->dma_drcmrrx = dmarx->start; | ||
594 | |||
595 | dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
596 | if (!dmatx) { | ||
597 | ret = -ENXIO; | ||
598 | goto out; | ||
599 | } | ||
600 | host->dma_drcmrtx = dmatx->start; | ||
601 | |||
573 | if (host->pdata && host->pdata->init) | 602 | if (host->pdata && host->pdata->init) |
574 | host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc); | 603 | host->pdata->init(&pdev->dev, pxamci_detect_irq, mmc); |
575 | 604 | ||
@@ -613,8 +642,8 @@ static int pxamci_remove(struct platform_device *pdev) | |||
613 | END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, | 642 | END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, |
614 | host->base + MMC_I_MASK); | 643 | host->base + MMC_I_MASK); |
615 | 644 | ||
616 | DRCMRRXMMC = 0; | 645 | DRCMR(host->dma_drcmrrx) = 0; |
617 | DRCMRTXMMC = 0; | 646 | DRCMR(host->dma_drcmrtx) = 0; |
618 | 647 | ||
619 | free_irq(host->irq, host); | 648 | free_irq(host->irq, host); |
620 | pxa_free_dma(host->dma); | 649 | pxa_free_dma(host->dma); |
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h index 748c7706f237..f6c2e2fcce37 100644 --- a/drivers/mmc/host/pxamci.h +++ b/drivers/mmc/host/pxamci.h | |||
@@ -68,7 +68,7 @@ | |||
68 | #define PRG_DONE (1 << 1) | 68 | #define PRG_DONE (1 << 1) |
69 | #define DATA_TRAN_DONE (1 << 0) | 69 | #define DATA_TRAN_DONE (1 << 0) |
70 | 70 | ||
71 | #ifdef CONFIG_PXA27x | 71 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) |
72 | #define MMC_I_MASK_ALL 0x00001fff | 72 | #define MMC_I_MASK_ALL 0x00001fff |
73 | #else | 73 | #else |
74 | #define MMC_I_MASK_ALL 0x0000007f | 74 | #define MMC_I_MASK_ALL 0x0000007f |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9af05a2f4af3..a6728661c416 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -212,7 +212,7 @@ config MII | |||
212 | 212 | ||
213 | config MACB | 213 | config MACB |
214 | tristate "Atmel MACB support" | 214 | tristate "Atmel MACB support" |
215 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 | 215 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91CAP9 |
216 | select PHYLIB | 216 | select PHYLIB |
217 | help | 217 | help |
218 | The Atmel MACB ethernet interface is found on many AT32 and AT91 | 218 | The Atmel MACB ethernet interface is found on many AT32 and AT91 |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 3286d2a0a870..6a20a5491a96 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/dm9000.h> | 66 | #include <linux/dm9000.h> |
67 | #include <linux/delay.h> | 67 | #include <linux/delay.h> |
68 | #include <linux/platform_device.h> | 68 | #include <linux/platform_device.h> |
69 | #include <linux/irq.h> | ||
69 | 70 | ||
70 | #include <asm/delay.h> | 71 | #include <asm/delay.h> |
71 | #include <asm/irq.h> | 72 | #include <asm/irq.h> |
@@ -113,7 +114,7 @@ | |||
113 | #define writesl outsl | 114 | #define writesl outsl |
114 | #define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH) | 115 | #define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH) |
115 | #else | 116 | #else |
116 | #define DM9000_IRQ_FLAGS IRQF_SHARED | 117 | #define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQT_RISING) |
117 | #endif | 118 | #endif |
118 | 119 | ||
119 | /* | 120 | /* |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 7da7589d45dd..4020e9e955b3 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1775,7 +1775,8 @@ static int __init smc_findirq(void __iomem *ioaddr) | |||
1775 | * o actually GRAB the irq. | 1775 | * o actually GRAB the irq. |
1776 | * o GRAB the region | 1776 | * o GRAB the region |
1777 | */ | 1777 | */ |
1778 | static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) | 1778 | static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, |
1779 | unsigned long irq_flags) | ||
1779 | { | 1780 | { |
1780 | struct smc_local *lp = netdev_priv(dev); | 1781 | struct smc_local *lp = netdev_priv(dev); |
1781 | static int version_printed = 0; | 1782 | static int version_printed = 0; |
@@ -1941,7 +1942,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) | |||
1941 | } | 1942 | } |
1942 | 1943 | ||
1943 | /* Grab the IRQ */ | 1944 | /* Grab the IRQ */ |
1944 | retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev); | 1945 | retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev); |
1945 | if (retval) | 1946 | if (retval) |
1946 | goto err_out; | 1947 | goto err_out; |
1947 | 1948 | ||
@@ -2123,8 +2124,9 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
2123 | static int smc_drv_probe(struct platform_device *pdev) | 2124 | static int smc_drv_probe(struct platform_device *pdev) |
2124 | { | 2125 | { |
2125 | struct net_device *ndev; | 2126 | struct net_device *ndev; |
2126 | struct resource *res; | 2127 | struct resource *res, *ires; |
2127 | unsigned int __iomem *addr; | 2128 | unsigned int __iomem *addr; |
2129 | unsigned long irq_flags = SMC_IRQ_FLAGS; | ||
2128 | int ret; | 2130 | int ret; |
2129 | 2131 | ||
2130 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); | 2132 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs"); |
@@ -2150,12 +2152,17 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
2150 | SET_NETDEV_DEV(ndev, &pdev->dev); | 2152 | SET_NETDEV_DEV(ndev, &pdev->dev); |
2151 | 2153 | ||
2152 | ndev->dma = (unsigned char)-1; | 2154 | ndev->dma = (unsigned char)-1; |
2153 | ndev->irq = platform_get_irq(pdev, 0); | 2155 | |
2154 | if (ndev->irq < 0) { | 2156 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
2157 | if (!ires) { | ||
2155 | ret = -ENODEV; | 2158 | ret = -ENODEV; |
2156 | goto out_free_netdev; | 2159 | goto out_free_netdev; |
2157 | } | 2160 | } |
2158 | 2161 | ||
2162 | ndev->irq = ires->start; | ||
2163 | if (SMC_IRQ_FLAGS == -1) | ||
2164 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | ||
2165 | |||
2159 | ret = smc_request_attrib(pdev); | 2166 | ret = smc_request_attrib(pdev); |
2160 | if (ret) | 2167 | if (ret) |
2161 | goto out_free_netdev; | 2168 | goto out_free_netdev; |
@@ -2181,7 +2188,7 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
2181 | #endif | 2188 | #endif |
2182 | 2189 | ||
2183 | platform_set_drvdata(pdev, ndev); | 2190 | platform_set_drvdata(pdev, ndev); |
2184 | ret = smc_probe(ndev, addr); | 2191 | ret = smc_probe(ndev, addr, irq_flags); |
2185 | if (ret != 0) | 2192 | if (ret != 0) |
2186 | goto out_iounmap; | 2193 | goto out_iounmap; |
2187 | 2194 | ||
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 07b7f7120e37..271c28dc9baa 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 54 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
55 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 55 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
56 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 56 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
57 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | ||
57 | 58 | ||
58 | #elif defined(CONFIG_BLACKFIN) | 59 | #elif defined(CONFIG_BLACKFIN) |
59 | 60 | ||
@@ -158,7 +159,7 @@ | |||
158 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 159 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
159 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 160 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
160 | 161 | ||
161 | #define SMC_IRQ_FLAGS (0) | 162 | #define SMC_IRQ_FLAGS (-1) |
162 | 163 | ||
163 | #elif defined(CONFIG_SA1100_ASSABET) | 164 | #elif defined(CONFIG_SA1100_ASSABET) |
164 | 165 | ||
@@ -177,6 +178,7 @@ | |||
177 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 178 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
178 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) | 179 | #define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l)) |
179 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) | 180 | #define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l)) |
181 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | ||
180 | 182 | ||
181 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) | 183 | #elif defined(CONFIG_MACH_LOGICPD_PXA270) |
182 | 184 | ||
@@ -194,7 +196,8 @@ | |||
194 | #elif defined(CONFIG_ARCH_INNOKOM) || \ | 196 | #elif defined(CONFIG_ARCH_INNOKOM) || \ |
195 | defined(CONFIG_MACH_MAINSTONE) || \ | 197 | defined(CONFIG_MACH_MAINSTONE) || \ |
196 | defined(CONFIG_ARCH_PXA_IDP) || \ | 198 | defined(CONFIG_ARCH_PXA_IDP) || \ |
197 | defined(CONFIG_ARCH_RAMSES) | 199 | defined(CONFIG_ARCH_RAMSES) || \ |
200 | defined(CONFIG_ARCH_PCM027) | ||
198 | 201 | ||
199 | #define SMC_CAN_USE_8BIT 1 | 202 | #define SMC_CAN_USE_8BIT 1 |
200 | #define SMC_CAN_USE_16BIT 1 | 203 | #define SMC_CAN_USE_16BIT 1 |
@@ -210,6 +213,7 @@ | |||
210 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 213 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
211 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 214 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
212 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 215 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
216 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | ||
213 | 217 | ||
214 | /* We actually can't write halfwords properly if not word aligned */ | 218 | /* We actually can't write halfwords properly if not word aligned */ |
215 | static inline void | 219 | static inline void |
@@ -238,6 +242,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
238 | #define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) | 242 | #define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) |
239 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) | 243 | #define SMC_outb(v, a, r) writeb(v, (a) + (r)) |
240 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 244 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
245 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | ||
241 | 246 | ||
242 | #elif defined(CONFIG_ARCH_OMAP) | 247 | #elif defined(CONFIG_ARCH_OMAP) |
243 | 248 | ||
@@ -252,17 +257,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
252 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) | 257 | #define SMC_outw(v, a, r) writew(v, (a) + (r)) |
253 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) | 258 | #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) |
254 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) | 259 | #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) |
255 | 260 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | |
256 | #include <asm/mach-types.h> | ||
257 | #include <asm/arch/cpu.h> | ||
258 | |||
259 | #define SMC_IRQ_FLAGS (( \ | ||
260 | machine_is_omap_h2() \ | ||
261 | || machine_is_omap_h3() \ | ||
262 | || machine_is_omap_h4() \ | ||
263 | || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ | ||
264 | ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING) | ||
265 | |||
266 | 261 | ||
267 | #elif defined(CONFIG_SH_SH4202_MICRODEV) | 262 | #elif defined(CONFIG_SH_SH4202_MICRODEV) |
268 | 263 | ||
@@ -453,8 +448,7 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, | |||
453 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) | 448 | #define SMC_outl(v, a, r) writel(v, (a) + (r)) |
454 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) | 449 | #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) |
455 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) | 450 | #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) |
456 | 451 | #define SMC_IRQ_FLAGS (-1) /* from resource */ | |
457 | #define SMC_IRQ_FLAGS (0) | ||
458 | 452 | ||
459 | #else | 453 | #else |
460 | 454 | ||
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 874923fcb2f9..e439044d88f2 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/arch/pxa-regs.h> | 31 | #include <asm/arch/pxa-regs.h> |
32 | #include <asm/arch/pxa2xx-regs.h> | ||
32 | 33 | ||
33 | #include <pcmcia/cs_types.h> | 34 | #include <pcmcia/cs_types.h> |
34 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 6f1e9a9804bc..2eb38520f0c8 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -337,6 +337,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
337 | if (IS_ERR(rtc)) | 337 | if (IS_ERR(rtc)) |
338 | return PTR_ERR(rtc); | 338 | return PTR_ERR(rtc); |
339 | 339 | ||
340 | device_init_wakeup(&pdev->dev, 1); | ||
341 | |||
340 | platform_set_drvdata(pdev, rtc); | 342 | platform_set_drvdata(pdev, rtc); |
341 | 343 | ||
342 | return 0; | 344 | return 0; |
@@ -352,9 +354,38 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
352 | return 0; | 354 | return 0; |
353 | } | 355 | } |
354 | 356 | ||
357 | #ifdef CONFIG_PM | ||
358 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
359 | { | ||
360 | if (pdev->dev.power.power_state.event != state.event) { | ||
361 | if (state.event == PM_EVENT_SUSPEND && | ||
362 | device_may_wakeup(&pdev->dev)) | ||
363 | enable_irq_wake(IRQ_RTCAlrm); | ||
364 | |||
365 | pdev->dev.power.power_state = state; | ||
366 | } | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int sa1100_rtc_resume(struct platform_device *pdev) | ||
371 | { | ||
372 | if (pdev->dev.power.power_state.event != PM_EVENT_ON) { | ||
373 | if (device_may_wakeup(&pdev->dev)) | ||
374 | disable_irq_wake(IRQ_RTCAlrm); | ||
375 | pdev->dev.power.power_state = PMSG_ON; | ||
376 | } | ||
377 | return 0; | ||
378 | } | ||
379 | #else | ||
380 | #define sa1100_rtc_suspend NULL | ||
381 | #define sa1100_rtc_resume NULL | ||
382 | #endif | ||
383 | |||
355 | static struct platform_driver sa1100_rtc_driver = { | 384 | static struct platform_driver sa1100_rtc_driver = { |
356 | .probe = sa1100_rtc_probe, | 385 | .probe = sa1100_rtc_probe, |
357 | .remove = sa1100_rtc_remove, | 386 | .remove = sa1100_rtc_remove, |
387 | .suspend = sa1100_rtc_suspend, | ||
388 | .resume = sa1100_rtc_resume, | ||
358 | .driver = { | 389 | .driver = { |
359 | .name = "sa1100-rtc", | 390 | .name = "sa1100-rtc", |
360 | }, | 391 | }, |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 1db15f3e5d20..d640427c74c8 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -1595,12 +1595,10 @@ void dasd_block_clear_timer(struct dasd_block *block) | |||
1595 | /* | 1595 | /* |
1596 | * posts the buffer_cache about a finalized request | 1596 | * posts the buffer_cache about a finalized request |
1597 | */ | 1597 | */ |
1598 | static inline void dasd_end_request(struct request *req, int uptodate) | 1598 | static inline void dasd_end_request(struct request *req, int error) |
1599 | { | 1599 | { |
1600 | if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) | 1600 | if (__blk_end_request(req, error, blk_rq_bytes(req))) |
1601 | BUG(); | 1601 | BUG(); |
1602 | add_disk_randomness(req->rq_disk); | ||
1603 | end_that_request_last(req, uptodate); | ||
1604 | } | 1602 | } |
1605 | 1603 | ||
1606 | /* | 1604 | /* |
@@ -1657,7 +1655,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) | |||
1657 | "Rejecting write request %p", | 1655 | "Rejecting write request %p", |
1658 | req); | 1656 | req); |
1659 | blkdev_dequeue_request(req); | 1657 | blkdev_dequeue_request(req); |
1660 | dasd_end_request(req, 0); | 1658 | dasd_end_request(req, -EIO); |
1661 | continue; | 1659 | continue; |
1662 | } | 1660 | } |
1663 | cqr = basedev->discipline->build_cp(basedev, block, req); | 1661 | cqr = basedev->discipline->build_cp(basedev, block, req); |
@@ -1686,7 +1684,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) | |||
1686 | "on request %p", | 1684 | "on request %p", |
1687 | PTR_ERR(cqr), req); | 1685 | PTR_ERR(cqr), req); |
1688 | blkdev_dequeue_request(req); | 1686 | blkdev_dequeue_request(req); |
1689 | dasd_end_request(req, 0); | 1687 | dasd_end_request(req, -EIO); |
1690 | continue; | 1688 | continue; |
1691 | } | 1689 | } |
1692 | /* | 1690 | /* |
@@ -1705,11 +1703,14 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) | |||
1705 | { | 1703 | { |
1706 | struct request *req; | 1704 | struct request *req; |
1707 | int status; | 1705 | int status; |
1706 | int error = 0; | ||
1708 | 1707 | ||
1709 | req = (struct request *) cqr->callback_data; | 1708 | req = (struct request *) cqr->callback_data; |
1710 | dasd_profile_end(cqr->block, cqr, req); | 1709 | dasd_profile_end(cqr->block, cqr, req); |
1711 | status = cqr->memdev->discipline->free_cp(cqr, req); | 1710 | status = cqr->memdev->discipline->free_cp(cqr, req); |
1712 | dasd_end_request(req, status); | 1711 | if (status <= 0) |
1712 | error = status ? status : -EIO; | ||
1713 | dasd_end_request(req, error); | ||
1713 | } | 1714 | } |
1714 | 1715 | ||
1715 | /* | 1716 | /* |
@@ -2009,7 +2010,7 @@ static void dasd_flush_request_queue(struct dasd_block *block) | |||
2009 | spin_lock_irq(&block->request_queue_lock); | 2010 | spin_lock_irq(&block->request_queue_lock); |
2010 | while ((req = elv_next_request(block->request_queue))) { | 2011 | while ((req = elv_next_request(block->request_queue))) { |
2011 | blkdev_dequeue_request(req); | 2012 | blkdev_dequeue_request(req); |
2012 | dasd_end_request(req, 0); | 2013 | dasd_end_request(req, -EIO); |
2013 | } | 2014 | } |
2014 | spin_unlock_irq(&block->request_queue_lock); | 2015 | spin_unlock_irq(&block->request_queue_lock); |
2015 | } | 2016 | } |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index eeb92e2ed0cc..ddc4a114e7f4 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -74,11 +74,10 @@ tapeblock_trigger_requeue(struct tape_device *device) | |||
74 | * Post finished request. | 74 | * Post finished request. |
75 | */ | 75 | */ |
76 | static void | 76 | static void |
77 | tapeblock_end_request(struct request *req, int uptodate) | 77 | tapeblock_end_request(struct request *req, int error) |
78 | { | 78 | { |
79 | if (end_that_request_first(req, uptodate, req->hard_nr_sectors)) | 79 | if (__blk_end_request(req, error, blk_rq_bytes(req))) |
80 | BUG(); | 80 | BUG(); |
81 | end_that_request_last(req, uptodate); | ||
82 | } | 81 | } |
83 | 82 | ||
84 | static void | 83 | static void |
@@ -91,7 +90,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data) | |||
91 | 90 | ||
92 | device = ccw_req->device; | 91 | device = ccw_req->device; |
93 | req = (struct request *) data; | 92 | req = (struct request *) data; |
94 | tapeblock_end_request(req, ccw_req->rc == 0); | 93 | tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO); |
95 | if (ccw_req->rc == 0) | 94 | if (ccw_req->rc == 0) |
96 | /* Update position. */ | 95 | /* Update position. */ |
97 | device->blk_data.block_position = | 96 | device->blk_data.block_position = |
@@ -119,7 +118,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) | |||
119 | ccw_req = device->discipline->bread(device, req); | 118 | ccw_req = device->discipline->bread(device, req); |
120 | if (IS_ERR(ccw_req)) { | 119 | if (IS_ERR(ccw_req)) { |
121 | DBF_EVENT(1, "TBLOCK: bread failed\n"); | 120 | DBF_EVENT(1, "TBLOCK: bread failed\n"); |
122 | tapeblock_end_request(req, 0); | 121 | tapeblock_end_request(req, -EIO); |
123 | return PTR_ERR(ccw_req); | 122 | return PTR_ERR(ccw_req); |
124 | } | 123 | } |
125 | ccw_req->callback = __tapeblock_end_request; | 124 | ccw_req->callback = __tapeblock_end_request; |
@@ -132,7 +131,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) | |||
132 | * Start/enqueueing failed. No retries in | 131 | * Start/enqueueing failed. No retries in |
133 | * this case. | 132 | * this case. |
134 | */ | 133 | */ |
135 | tapeblock_end_request(req, 0); | 134 | tapeblock_end_request(req, -EIO); |
136 | device->discipline->free_bread(ccw_req); | 135 | device->discipline->free_bread(ccw_req); |
137 | } | 136 | } |
138 | 137 | ||
@@ -177,7 +176,7 @@ tapeblock_requeue(struct work_struct *work) { | |||
177 | if (rq_data_dir(req) == WRITE) { | 176 | if (rq_data_dir(req) == WRITE) { |
178 | DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); | 177 | DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); |
179 | blkdev_dequeue_request(req); | 178 | blkdev_dequeue_request(req); |
180 | tapeblock_end_request(req, 0); | 179 | tapeblock_end_request(req, -EIO); |
181 | continue; | 180 | continue; |
182 | } | 181 | } |
183 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 182 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 02e91893064d..db8bc20539e1 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -919,8 +919,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) | |||
919 | } | 919 | } |
920 | 920 | ||
921 | /* kill current request */ | 921 | /* kill current request */ |
922 | blkdev_dequeue_request(req); | 922 | if (__blk_end_request(req, -EIO, 0)) |
923 | end_that_request_last(req, 0); | 923 | BUG(); |
924 | if (blk_sense_request(req)) | 924 | if (blk_sense_request(req)) |
925 | kfree(scsi->pc->buffer); | 925 | kfree(scsi->pc->buffer); |
926 | kfree(scsi->pc); | 926 | kfree(scsi->pc); |
@@ -929,8 +929,8 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) | |||
929 | 929 | ||
930 | /* now nuke the drive queue */ | 930 | /* now nuke the drive queue */ |
931 | while ((req = elv_next_request(drive->queue))) { | 931 | while ((req = elv_next_request(drive->queue))) { |
932 | blkdev_dequeue_request(req); | 932 | if (__blk_end_request(req, -EIO, 0)) |
933 | end_that_request_last(req, 0); | 933 | BUG(); |
934 | } | 934 | } |
935 | 935 | ||
936 | HWGROUP(drive)->rq = NULL; | 936 | HWGROUP(drive)->rq = NULL; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4cf902efbdbf..7c4c889c5221 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -634,7 +634,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) | |||
634 | * of upper level post-processing and scsi_io_completion). | 634 | * of upper level post-processing and scsi_io_completion). |
635 | * | 635 | * |
636 | * Arguments: cmd - command that is complete. | 636 | * Arguments: cmd - command that is complete. |
637 | * uptodate - 1 if I/O indicates success, <= 0 for I/O error. | 637 | * error - 0 if I/O indicates success, < 0 for I/O error. |
638 | * bytes - number of bytes of completed I/O | 638 | * bytes - number of bytes of completed I/O |
639 | * requeue - indicates whether we should requeue leftovers. | 639 | * requeue - indicates whether we should requeue leftovers. |
640 | * | 640 | * |
@@ -649,26 +649,25 @@ void scsi_run_host_queues(struct Scsi_Host *shost) | |||
649 | * at some point during this call. | 649 | * at some point during this call. |
650 | * Notes: If cmd was requeued, upon return it will be a stale pointer. | 650 | * Notes: If cmd was requeued, upon return it will be a stale pointer. |
651 | */ | 651 | */ |
652 | static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, | 652 | static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error, |
653 | int bytes, int requeue) | 653 | int bytes, int requeue) |
654 | { | 654 | { |
655 | struct request_queue *q = cmd->device->request_queue; | 655 | struct request_queue *q = cmd->device->request_queue; |
656 | struct request *req = cmd->request; | 656 | struct request *req = cmd->request; |
657 | unsigned long flags; | ||
658 | 657 | ||
659 | /* | 658 | /* |
660 | * If there are blocks left over at the end, set up the command | 659 | * If there are blocks left over at the end, set up the command |
661 | * to queue the remainder of them. | 660 | * to queue the remainder of them. |
662 | */ | 661 | */ |
663 | if (end_that_request_chunk(req, uptodate, bytes)) { | 662 | if (blk_end_request(req, error, bytes)) { |
664 | int leftover = (req->hard_nr_sectors << 9); | 663 | int leftover = (req->hard_nr_sectors << 9); |
665 | 664 | ||
666 | if (blk_pc_request(req)) | 665 | if (blk_pc_request(req)) |
667 | leftover = req->data_len; | 666 | leftover = req->data_len; |
668 | 667 | ||
669 | /* kill remainder if no retrys */ | 668 | /* kill remainder if no retrys */ |
670 | if (!uptodate && blk_noretry_request(req)) | 669 | if (error && blk_noretry_request(req)) |
671 | end_that_request_chunk(req, 0, leftover); | 670 | blk_end_request(req, error, leftover); |
672 | else { | 671 | else { |
673 | if (requeue) { | 672 | if (requeue) { |
674 | /* | 673 | /* |
@@ -683,14 +682,6 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, | |||
683 | } | 682 | } |
684 | } | 683 | } |
685 | 684 | ||
686 | add_disk_randomness(req->rq_disk); | ||
687 | |||
688 | spin_lock_irqsave(q->queue_lock, flags); | ||
689 | if (blk_rq_tagged(req)) | ||
690 | blk_queue_end_tag(q, req); | ||
691 | end_that_request_last(req, uptodate); | ||
692 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
693 | |||
694 | /* | 685 | /* |
695 | * This will goose the queue request function at the end, so we don't | 686 | * This will goose the queue request function at the end, so we don't |
696 | * need to worry about launching another command. | 687 | * need to worry about launching another command. |
@@ -739,138 +730,43 @@ static inline unsigned int scsi_sgtable_index(unsigned short nents) | |||
739 | return index; | 730 | return index; |
740 | } | 731 | } |
741 | 732 | ||
742 | struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) | 733 | static void scsi_sg_free(struct scatterlist *sgl, unsigned int nents) |
743 | { | 734 | { |
744 | struct scsi_host_sg_pool *sgp; | 735 | struct scsi_host_sg_pool *sgp; |
745 | struct scatterlist *sgl, *prev, *ret; | ||
746 | unsigned int index; | ||
747 | int this, left; | ||
748 | |||
749 | BUG_ON(!cmd->use_sg); | ||
750 | |||
751 | left = cmd->use_sg; | ||
752 | ret = prev = NULL; | ||
753 | do { | ||
754 | this = left; | ||
755 | if (this > SCSI_MAX_SG_SEGMENTS) { | ||
756 | this = SCSI_MAX_SG_SEGMENTS - 1; | ||
757 | index = SG_MEMPOOL_NR - 1; | ||
758 | } else | ||
759 | index = scsi_sgtable_index(this); | ||
760 | |||
761 | left -= this; | ||
762 | 736 | ||
763 | sgp = scsi_sg_pools + index; | 737 | sgp = scsi_sg_pools + scsi_sgtable_index(nents); |
764 | 738 | mempool_free(sgl, sgp->pool); | |
765 | sgl = mempool_alloc(sgp->pool, gfp_mask); | 739 | } |
766 | if (unlikely(!sgl)) | ||
767 | goto enomem; | ||
768 | 740 | ||
769 | sg_init_table(sgl, sgp->size); | 741 | static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask) |
742 | { | ||
743 | struct scsi_host_sg_pool *sgp; | ||
770 | 744 | ||
771 | /* | 745 | sgp = scsi_sg_pools + scsi_sgtable_index(nents); |
772 | * first loop through, set initial index and return value | 746 | return mempool_alloc(sgp->pool, gfp_mask); |
773 | */ | 747 | } |
774 | if (!ret) | ||
775 | ret = sgl; | ||
776 | 748 | ||
777 | /* | 749 | int scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) |
778 | * chain previous sglist, if any. we know the previous | 750 | { |
779 | * sglist must be the biggest one, or we would not have | 751 | int ret; |
780 | * ended up doing another loop. | ||
781 | */ | ||
782 | if (prev) | ||
783 | sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl); | ||
784 | 752 | ||
785 | /* | 753 | BUG_ON(!cmd->use_sg); |
786 | * if we have nothing left, mark the last segment as | ||
787 | * end-of-list | ||
788 | */ | ||
789 | if (!left) | ||
790 | sg_mark_end(&sgl[this - 1]); | ||
791 | 754 | ||
792 | /* | 755 | ret = __sg_alloc_table(&cmd->sg_table, cmd->use_sg, |
793 | * don't allow subsequent mempool allocs to sleep, it would | 756 | SCSI_MAX_SG_SEGMENTS, gfp_mask, scsi_sg_alloc); |
794 | * violate the mempool principle. | 757 | if (unlikely(ret)) |
795 | */ | 758 | __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, |
796 | gfp_mask &= ~__GFP_WAIT; | 759 | scsi_sg_free); |
797 | gfp_mask |= __GFP_HIGH; | ||
798 | prev = sgl; | ||
799 | } while (left); | ||
800 | 760 | ||
801 | /* | 761 | cmd->request_buffer = cmd->sg_table.sgl; |
802 | * ->use_sg may get modified after dma mapping has potentially | ||
803 | * shrunk the number of segments, so keep a copy of it for free. | ||
804 | */ | ||
805 | cmd->__use_sg = cmd->use_sg; | ||
806 | return ret; | 762 | return ret; |
807 | enomem: | ||
808 | if (ret) { | ||
809 | /* | ||
810 | * Free entries chained off ret. Since we were trying to | ||
811 | * allocate another sglist, we know that all entries are of | ||
812 | * the max size. | ||
813 | */ | ||
814 | sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1; | ||
815 | prev = ret; | ||
816 | ret = &ret[SCSI_MAX_SG_SEGMENTS - 1]; | ||
817 | |||
818 | while ((sgl = sg_chain_ptr(ret)) != NULL) { | ||
819 | ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1]; | ||
820 | mempool_free(sgl, sgp->pool); | ||
821 | } | ||
822 | |||
823 | mempool_free(prev, sgp->pool); | ||
824 | } | ||
825 | return NULL; | ||
826 | } | 763 | } |
827 | 764 | ||
828 | EXPORT_SYMBOL(scsi_alloc_sgtable); | 765 | EXPORT_SYMBOL(scsi_alloc_sgtable); |
829 | 766 | ||
830 | void scsi_free_sgtable(struct scsi_cmnd *cmd) | 767 | void scsi_free_sgtable(struct scsi_cmnd *cmd) |
831 | { | 768 | { |
832 | struct scatterlist *sgl = cmd->request_buffer; | 769 | __sg_free_table(&cmd->sg_table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free); |
833 | struct scsi_host_sg_pool *sgp; | ||
834 | |||
835 | /* | ||
836 | * if this is the biggest size sglist, check if we have | ||
837 | * chained parts we need to free | ||
838 | */ | ||
839 | if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) { | ||
840 | unsigned short this, left; | ||
841 | struct scatterlist *next; | ||
842 | unsigned int index; | ||
843 | |||
844 | left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1); | ||
845 | next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]); | ||
846 | while (left && next) { | ||
847 | sgl = next; | ||
848 | this = left; | ||
849 | if (this > SCSI_MAX_SG_SEGMENTS) { | ||
850 | this = SCSI_MAX_SG_SEGMENTS - 1; | ||
851 | index = SG_MEMPOOL_NR - 1; | ||
852 | } else | ||
853 | index = scsi_sgtable_index(this); | ||
854 | |||
855 | left -= this; | ||
856 | |||
857 | sgp = scsi_sg_pools + index; | ||
858 | |||
859 | if (left) | ||
860 | next = sg_chain_ptr(&sgl[sgp->size - 1]); | ||
861 | |||
862 | mempool_free(sgl, sgp->pool); | ||
863 | } | ||
864 | |||
865 | /* | ||
866 | * Restore original, will be freed below | ||
867 | */ | ||
868 | sgl = cmd->request_buffer; | ||
869 | sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1; | ||
870 | } else | ||
871 | sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg); | ||
872 | |||
873 | mempool_free(sgl, sgp->pool); | ||
874 | } | 770 | } |
875 | 771 | ||
876 | EXPORT_SYMBOL(scsi_free_sgtable); | 772 | EXPORT_SYMBOL(scsi_free_sgtable); |
@@ -987,7 +883,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
987 | * are leftovers and there is some kind of error | 883 | * are leftovers and there is some kind of error |
988 | * (result != 0), retry the rest. | 884 | * (result != 0), retry the rest. |
989 | */ | 885 | */ |
990 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) | 886 | if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL) |
991 | return; | 887 | return; |
992 | 888 | ||
993 | /* good_bytes = 0, or (inclusive) there were leftovers and | 889 | /* good_bytes = 0, or (inclusive) there were leftovers and |
@@ -1001,7 +897,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1001 | * and quietly refuse further access. | 897 | * and quietly refuse further access. |
1002 | */ | 898 | */ |
1003 | cmd->device->changed = 1; | 899 | cmd->device->changed = 1; |
1004 | scsi_end_request(cmd, 0, this_count, 1); | 900 | scsi_end_request(cmd, -EIO, this_count, 1); |
1005 | return; | 901 | return; |
1006 | } else { | 902 | } else { |
1007 | /* Must have been a power glitch, or a | 903 | /* Must have been a power glitch, or a |
@@ -1033,7 +929,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1033 | scsi_requeue_command(q, cmd); | 929 | scsi_requeue_command(q, cmd); |
1034 | return; | 930 | return; |
1035 | } else { | 931 | } else { |
1036 | scsi_end_request(cmd, 0, this_count, 1); | 932 | scsi_end_request(cmd, -EIO, this_count, 1); |
1037 | return; | 933 | return; |
1038 | } | 934 | } |
1039 | break; | 935 | break; |
@@ -1061,7 +957,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1061 | "Device not ready", | 957 | "Device not ready", |
1062 | &sshdr); | 958 | &sshdr); |
1063 | 959 | ||
1064 | scsi_end_request(cmd, 0, this_count, 1); | 960 | scsi_end_request(cmd, -EIO, this_count, 1); |
1065 | return; | 961 | return; |
1066 | case VOLUME_OVERFLOW: | 962 | case VOLUME_OVERFLOW: |
1067 | if (!(req->cmd_flags & REQ_QUIET)) { | 963 | if (!(req->cmd_flags & REQ_QUIET)) { |
@@ -1071,7 +967,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1071 | scsi_print_sense("", cmd); | 967 | scsi_print_sense("", cmd); |
1072 | } | 968 | } |
1073 | /* See SSC3rXX or current. */ | 969 | /* See SSC3rXX or current. */ |
1074 | scsi_end_request(cmd, 0, this_count, 1); | 970 | scsi_end_request(cmd, -EIO, this_count, 1); |
1075 | return; | 971 | return; |
1076 | default: | 972 | default: |
1077 | break; | 973 | break; |
@@ -1092,7 +988,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1092 | scsi_print_sense("", cmd); | 988 | scsi_print_sense("", cmd); |
1093 | } | 989 | } |
1094 | } | 990 | } |
1095 | scsi_end_request(cmd, 0, this_count, !result); | 991 | scsi_end_request(cmd, -EIO, this_count, !result); |
1096 | } | 992 | } |
1097 | 993 | ||
1098 | /* | 994 | /* |
@@ -1120,8 +1016,7 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
1120 | /* | 1016 | /* |
1121 | * If sg table allocation fails, requeue request later. | 1017 | * If sg table allocation fails, requeue request later. |
1122 | */ | 1018 | */ |
1123 | cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC); | 1019 | if (unlikely(scsi_alloc_sgtable(cmd, GFP_ATOMIC))) { |
1124 | if (unlikely(!cmd->request_buffer)) { | ||
1125 | scsi_unprep_request(req); | 1020 | scsi_unprep_request(req); |
1126 | return BLKPREP_DEFER; | 1021 | return BLKPREP_DEFER; |
1127 | } | 1022 | } |
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 93ece8f4e5de..01e03f3f6ffa 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -359,8 +359,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) | |||
359 | int count; | 359 | int count; |
360 | 360 | ||
361 | cmd->use_sg = rq->nr_phys_segments; | 361 | cmd->use_sg = rq->nr_phys_segments; |
362 | cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask); | 362 | if (scsi_alloc_sgtable(cmd, gfp_mask)) |
363 | if (!cmd->request_buffer) | ||
364 | return -ENOMEM; | 363 | return -ENOMEM; |
365 | 364 | ||
366 | cmd->request_bufflen = rq->data_len; | 365 | cmd->request_bufflen = rq->data_len; |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 17216b76efdc..aba28f335b88 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -48,6 +48,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
48 | #include <linux/blkdev.h> | 48 | #include <linux/blkdev.h> |
49 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
50 | #include <linux/scatterlist.h> | 50 | #include <linux/scatterlist.h> |
51 | #include <linux/blktrace_api.h> | ||
51 | 52 | ||
52 | #include "scsi.h" | 53 | #include "scsi.h" |
53 | #include <scsi/scsi_dbg.h> | 54 | #include <scsi/scsi_dbg.h> |
@@ -1067,6 +1068,17 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1067 | case BLKSECTGET: | 1068 | case BLKSECTGET: |
1068 | return put_user(sdp->device->request_queue->max_sectors * 512, | 1069 | return put_user(sdp->device->request_queue->max_sectors * 512, |
1069 | ip); | 1070 | ip); |
1071 | case BLKTRACESETUP: | ||
1072 | return blk_trace_setup(sdp->device->request_queue, | ||
1073 | sdp->disk->disk_name, | ||
1074 | sdp->device->sdev_gendev.devt, | ||
1075 | (char *)arg); | ||
1076 | case BLKTRACESTART: | ||
1077 | return blk_trace_startstop(sdp->device->request_queue, 1); | ||
1078 | case BLKTRACESTOP: | ||
1079 | return blk_trace_startstop(sdp->device->request_queue, 0); | ||
1080 | case BLKTRACETEARDOWN: | ||
1081 | return blk_trace_remove(sdp->device->request_queue); | ||
1070 | default: | 1082 | default: |
1071 | if (read_only) | 1083 | if (read_only) |
1072 | return -EPERM; /* don't know so take safe approach */ | 1084 | return -EPERM; /* don't know so take safe approach */ |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index facb67855619..6a48dfa1efe8 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -277,6 +277,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios, | |||
277 | if (termios->c_iflag & INPCK) | 277 | if (termios->c_iflag & INPCK) |
278 | port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY; | 278 | port->read_status_mask |= RXSTAT_FRAME | RXSTAT_PARITY; |
279 | 279 | ||
280 | tty_encode_baud_rate(tty, baud, baud); | ||
281 | |||
280 | /* | 282 | /* |
281 | * Which character status flags should we ignore? | 283 | * Which character status flags should we ignore? |
282 | */ | 284 | */ |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index abf05048c638..aaaea81e412a 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -153,6 +153,7 @@ config SPI_OMAP24XX | |||
153 | config SPI_PXA2XX | 153 | config SPI_PXA2XX |
154 | tristate "PXA2xx SSP SPI master" | 154 | tristate "PXA2xx SSP SPI master" |
155 | depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL | 155 | depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL |
156 | select PXA_SSP | ||
156 | help | 157 | help |
157 | This enables using a PXA2xx SSP port as a SPI master controller. | 158 | This enables using a PXA2xx SSP port as a SPI master controller. |
158 | The driver can be configured to use any SSP port and additional | 159 | The driver can be configured to use any SSP port and additional |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 1c2ab541d37d..eb817b8eb024 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/clk.h> | ||
30 | 31 | ||
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
@@ -36,6 +37,8 @@ | |||
36 | 37 | ||
37 | #include <asm/arch/hardware.h> | 38 | #include <asm/arch/hardware.h> |
38 | #include <asm/arch/pxa-regs.h> | 39 | #include <asm/arch/pxa-regs.h> |
40 | #include <asm/arch/regs-ssp.h> | ||
41 | #include <asm/arch/ssp.h> | ||
39 | #include <asm/arch/pxa2xx_spi.h> | 42 | #include <asm/arch/pxa2xx_spi.h> |
40 | 43 | ||
41 | MODULE_AUTHOR("Stephen Street"); | 44 | MODULE_AUTHOR("Stephen Street"); |
@@ -80,6 +83,9 @@ struct driver_data { | |||
80 | /* Driver model hookup */ | 83 | /* Driver model hookup */ |
81 | struct platform_device *pdev; | 84 | struct platform_device *pdev; |
82 | 85 | ||
86 | /* SSP Info */ | ||
87 | struct ssp_device *ssp; | ||
88 | |||
83 | /* SPI framework hookup */ | 89 | /* SPI framework hookup */ |
84 | enum pxa_ssp_type ssp_type; | 90 | enum pxa_ssp_type ssp_type; |
85 | struct spi_master *master; | 91 | struct spi_master *master; |
@@ -778,6 +784,16 @@ int set_dma_burst_and_threshold(struct chip_data *chip, struct spi_device *spi, | |||
778 | return retval; | 784 | return retval; |
779 | } | 785 | } |
780 | 786 | ||
787 | static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate) | ||
788 | { | ||
789 | unsigned long ssp_clk = clk_get_rate(ssp->clk); | ||
790 | |||
791 | if (ssp->type == PXA25x_SSP) | ||
792 | return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8; | ||
793 | else | ||
794 | return ((ssp_clk / rate - 1) & 0xfff) << 8; | ||
795 | } | ||
796 | |||
781 | static void pump_transfers(unsigned long data) | 797 | static void pump_transfers(unsigned long data) |
782 | { | 798 | { |
783 | struct driver_data *drv_data = (struct driver_data *)data; | 799 | struct driver_data *drv_data = (struct driver_data *)data; |
@@ -785,6 +801,7 @@ static void pump_transfers(unsigned long data) | |||
785 | struct spi_transfer *transfer = NULL; | 801 | struct spi_transfer *transfer = NULL; |
786 | struct spi_transfer *previous = NULL; | 802 | struct spi_transfer *previous = NULL; |
787 | struct chip_data *chip = NULL; | 803 | struct chip_data *chip = NULL; |
804 | struct ssp_device *ssp = drv_data->ssp; | ||
788 | void *reg = drv_data->ioaddr; | 805 | void *reg = drv_data->ioaddr; |
789 | u32 clk_div = 0; | 806 | u32 clk_div = 0; |
790 | u8 bits = 0; | 807 | u8 bits = 0; |
@@ -866,12 +883,7 @@ static void pump_transfers(unsigned long data) | |||
866 | if (transfer->bits_per_word) | 883 | if (transfer->bits_per_word) |
867 | bits = transfer->bits_per_word; | 884 | bits = transfer->bits_per_word; |
868 | 885 | ||
869 | if (reg == SSP1_VIRT) | 886 | clk_div = ssp_get_clk_div(ssp, speed); |
870 | clk_div = SSP1_SerClkDiv(speed); | ||
871 | else if (reg == SSP2_VIRT) | ||
872 | clk_div = SSP2_SerClkDiv(speed); | ||
873 | else if (reg == SSP3_VIRT) | ||
874 | clk_div = SSP3_SerClkDiv(speed); | ||
875 | 887 | ||
876 | if (bits <= 8) { | 888 | if (bits <= 8) { |
877 | drv_data->n_bytes = 1; | 889 | drv_data->n_bytes = 1; |
@@ -1074,6 +1086,7 @@ static int setup(struct spi_device *spi) | |||
1074 | struct pxa2xx_spi_chip *chip_info = NULL; | 1086 | struct pxa2xx_spi_chip *chip_info = NULL; |
1075 | struct chip_data *chip; | 1087 | struct chip_data *chip; |
1076 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | 1088 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); |
1089 | struct ssp_device *ssp = drv_data->ssp; | ||
1077 | unsigned int clk_div; | 1090 | unsigned int clk_div; |
1078 | 1091 | ||
1079 | if (!spi->bits_per_word) | 1092 | if (!spi->bits_per_word) |
@@ -1157,18 +1170,7 @@ static int setup(struct spi_device *spi) | |||
1157 | } | 1170 | } |
1158 | } | 1171 | } |
1159 | 1172 | ||
1160 | if (drv_data->ioaddr == SSP1_VIRT) | 1173 | clk_div = ssp_get_clk_div(ssp, spi->max_speed_hz); |
1161 | clk_div = SSP1_SerClkDiv(spi->max_speed_hz); | ||
1162 | else if (drv_data->ioaddr == SSP2_VIRT) | ||
1163 | clk_div = SSP2_SerClkDiv(spi->max_speed_hz); | ||
1164 | else if (drv_data->ioaddr == SSP3_VIRT) | ||
1165 | clk_div = SSP3_SerClkDiv(spi->max_speed_hz); | ||
1166 | else | ||
1167 | { | ||
1168 | dev_err(&spi->dev, "failed setup: unknown IO address=0x%p\n", | ||
1169 | drv_data->ioaddr); | ||
1170 | return -ENODEV; | ||
1171 | } | ||
1172 | chip->speed_hz = spi->max_speed_hz; | 1174 | chip->speed_hz = spi->max_speed_hz; |
1173 | 1175 | ||
1174 | chip->cr0 = clk_div | 1176 | chip->cr0 = clk_div |
@@ -1183,15 +1185,15 @@ static int setup(struct spi_device *spi) | |||
1183 | 1185 | ||
1184 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ | 1186 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ |
1185 | if (drv_data->ssp_type != PXA25x_SSP) | 1187 | if (drv_data->ssp_type != PXA25x_SSP) |
1186 | dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", | 1188 | dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", |
1187 | spi->bits_per_word, | 1189 | spi->bits_per_word, |
1188 | (CLOCK_SPEED_HZ) | 1190 | clk_get_rate(ssp->clk) |
1189 | / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), | 1191 | / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), |
1190 | spi->mode & 0x3); | 1192 | spi->mode & 0x3); |
1191 | else | 1193 | else |
1192 | dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n", | 1194 | dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n", |
1193 | spi->bits_per_word, | 1195 | spi->bits_per_word, |
1194 | (CLOCK_SPEED_HZ/2) | 1196 | clk_get_rate(ssp->clk) |
1195 | / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), | 1197 | / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)), |
1196 | spi->mode & 0x3); | 1198 | spi->mode & 0x3); |
1197 | 1199 | ||
@@ -1323,14 +1325,14 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1323 | struct pxa2xx_spi_master *platform_info; | 1325 | struct pxa2xx_spi_master *platform_info; |
1324 | struct spi_master *master; | 1326 | struct spi_master *master; |
1325 | struct driver_data *drv_data = 0; | 1327 | struct driver_data *drv_data = 0; |
1326 | struct resource *memory_resource; | 1328 | struct ssp_device *ssp; |
1327 | int irq; | ||
1328 | int status = 0; | 1329 | int status = 0; |
1329 | 1330 | ||
1330 | platform_info = dev->platform_data; | 1331 | platform_info = dev->platform_data; |
1331 | 1332 | ||
1332 | if (platform_info->ssp_type == SSP_UNDEFINED) { | 1333 | ssp = ssp_request(pdev->id, pdev->name); |
1333 | dev_err(&pdev->dev, "undefined SSP\n"); | 1334 | if (ssp == NULL) { |
1335 | dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id); | ||
1334 | return -ENODEV; | 1336 | return -ENODEV; |
1335 | } | 1337 | } |
1336 | 1338 | ||
@@ -1338,12 +1340,14 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1338 | master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); | 1340 | master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); |
1339 | if (!master) { | 1341 | if (!master) { |
1340 | dev_err(&pdev->dev, "can not alloc spi_master\n"); | 1342 | dev_err(&pdev->dev, "can not alloc spi_master\n"); |
1343 | ssp_free(ssp); | ||
1341 | return -ENOMEM; | 1344 | return -ENOMEM; |
1342 | } | 1345 | } |
1343 | drv_data = spi_master_get_devdata(master); | 1346 | drv_data = spi_master_get_devdata(master); |
1344 | drv_data->master = master; | 1347 | drv_data->master = master; |
1345 | drv_data->master_info = platform_info; | 1348 | drv_data->master_info = platform_info; |
1346 | drv_data->pdev = pdev; | 1349 | drv_data->pdev = pdev; |
1350 | drv_data->ssp = ssp; | ||
1347 | 1351 | ||
1348 | master->bus_num = pdev->id; | 1352 | master->bus_num = pdev->id; |
1349 | master->num_chipselect = platform_info->num_chipselect; | 1353 | master->num_chipselect = platform_info->num_chipselect; |
@@ -1351,21 +1355,13 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1351 | master->setup = setup; | 1355 | master->setup = setup; |
1352 | master->transfer = transfer; | 1356 | master->transfer = transfer; |
1353 | 1357 | ||
1354 | drv_data->ssp_type = platform_info->ssp_type; | 1358 | drv_data->ssp_type = ssp->type; |
1355 | drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data + | 1359 | drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data + |
1356 | sizeof(struct driver_data)), 8); | 1360 | sizeof(struct driver_data)), 8); |
1357 | 1361 | ||
1358 | /* Setup register addresses */ | 1362 | drv_data->ioaddr = ssp->mmio_base; |
1359 | memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1363 | drv_data->ssdr_physical = ssp->phys_base + SSDR; |
1360 | if (!memory_resource) { | 1364 | if (ssp->type == PXA25x_SSP) { |
1361 | dev_err(&pdev->dev, "memory resources not defined\n"); | ||
1362 | status = -ENODEV; | ||
1363 | goto out_error_master_alloc; | ||
1364 | } | ||
1365 | |||
1366 | drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start)); | ||
1367 | drv_data->ssdr_physical = memory_resource->start + 0x00000010; | ||
1368 | if (platform_info->ssp_type == PXA25x_SSP) { | ||
1369 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; | 1365 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; |
1370 | drv_data->dma_cr1 = 0; | 1366 | drv_data->dma_cr1 = 0; |
1371 | drv_data->clear_sr = SSSR_ROR; | 1367 | drv_data->clear_sr = SSSR_ROR; |
@@ -1377,15 +1373,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1377 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; | 1373 | drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR; |
1378 | } | 1374 | } |
1379 | 1375 | ||
1380 | /* Attach to IRQ */ | 1376 | status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data); |
1381 | irq = platform_get_irq(pdev, 0); | ||
1382 | if (irq < 0) { | ||
1383 | dev_err(&pdev->dev, "irq resource not defined\n"); | ||
1384 | status = -ENODEV; | ||
1385 | goto out_error_master_alloc; | ||
1386 | } | ||
1387 | |||
1388 | status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data); | ||
1389 | if (status < 0) { | 1377 | if (status < 0) { |
1390 | dev_err(&pdev->dev, "can not get IRQ\n"); | 1378 | dev_err(&pdev->dev, "can not get IRQ\n"); |
1391 | goto out_error_master_alloc; | 1379 | goto out_error_master_alloc; |
@@ -1418,29 +1406,12 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev) | |||
1418 | goto out_error_dma_alloc; | 1406 | goto out_error_dma_alloc; |
1419 | } | 1407 | } |
1420 | 1408 | ||
1421 | if (drv_data->ioaddr == SSP1_VIRT) { | 1409 | DRCMR(ssp->drcmr_rx) = DRCMR_MAPVLD | drv_data->rx_channel; |
1422 | DRCMRRXSSDR = DRCMR_MAPVLD | 1410 | DRCMR(ssp->drcmr_tx) = DRCMR_MAPVLD | drv_data->tx_channel; |
1423 | | drv_data->rx_channel; | ||
1424 | DRCMRTXSSDR = DRCMR_MAPVLD | ||
1425 | | drv_data->tx_channel; | ||
1426 | } else if (drv_data->ioaddr == SSP2_VIRT) { | ||
1427 | DRCMRRXSS2DR = DRCMR_MAPVLD | ||
1428 | | drv_data->rx_channel; | ||
1429 | DRCMRTXSS2DR = DRCMR_MAPVLD | ||
1430 | | drv_data->tx_channel; | ||
1431 | } else if (drv_data->ioaddr == SSP3_VIRT) { | ||
1432 | DRCMRRXSS3DR = DRCMR_MAPVLD | ||
1433 | | drv_data->rx_channel; | ||
1434 | DRCMRTXSS3DR = DRCMR_MAPVLD | ||
1435 | | drv_data->tx_channel; | ||
1436 | } else { | ||
1437 | dev_err(dev, "bad SSP type\n"); | ||
1438 | goto out_error_dma_alloc; | ||
1439 | } | ||
1440 | } | 1411 | } |
1441 | 1412 | ||
1442 | /* Enable SOC clock */ | 1413 | /* Enable SOC clock */ |
1443 | pxa_set_cken(platform_info->clock_enable, 1); | 1414 | clk_enable(ssp->clk); |
1444 | 1415 | ||
1445 | /* Load default SSP configuration */ | 1416 | /* Load default SSP configuration */ |
1446 | write_SSCR0(0, drv_data->ioaddr); | 1417 | write_SSCR0(0, drv_data->ioaddr); |
@@ -1479,7 +1450,7 @@ out_error_queue_alloc: | |||
1479 | destroy_queue(drv_data); | 1450 | destroy_queue(drv_data); |
1480 | 1451 | ||
1481 | out_error_clock_enabled: | 1452 | out_error_clock_enabled: |
1482 | pxa_set_cken(platform_info->clock_enable, 0); | 1453 | clk_disable(ssp->clk); |
1483 | 1454 | ||
1484 | out_error_dma_alloc: | 1455 | out_error_dma_alloc: |
1485 | if (drv_data->tx_channel != -1) | 1456 | if (drv_data->tx_channel != -1) |
@@ -1488,17 +1459,18 @@ out_error_dma_alloc: | |||
1488 | pxa_free_dma(drv_data->rx_channel); | 1459 | pxa_free_dma(drv_data->rx_channel); |
1489 | 1460 | ||
1490 | out_error_irq_alloc: | 1461 | out_error_irq_alloc: |
1491 | free_irq(irq, drv_data); | 1462 | free_irq(ssp->irq, drv_data); |
1492 | 1463 | ||
1493 | out_error_master_alloc: | 1464 | out_error_master_alloc: |
1494 | spi_master_put(master); | 1465 | spi_master_put(master); |
1466 | ssp_free(ssp); | ||
1495 | return status; | 1467 | return status; |
1496 | } | 1468 | } |
1497 | 1469 | ||
1498 | static int pxa2xx_spi_remove(struct platform_device *pdev) | 1470 | static int pxa2xx_spi_remove(struct platform_device *pdev) |
1499 | { | 1471 | { |
1500 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1472 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1501 | int irq; | 1473 | struct ssp_device *ssp = drv_data->ssp; |
1502 | int status = 0; | 1474 | int status = 0; |
1503 | 1475 | ||
1504 | if (!drv_data) | 1476 | if (!drv_data) |
@@ -1520,28 +1492,21 @@ static int pxa2xx_spi_remove(struct platform_device *pdev) | |||
1520 | 1492 | ||
1521 | /* Disable the SSP at the peripheral and SOC level */ | 1493 | /* Disable the SSP at the peripheral and SOC level */ |
1522 | write_SSCR0(0, drv_data->ioaddr); | 1494 | write_SSCR0(0, drv_data->ioaddr); |
1523 | pxa_set_cken(drv_data->master_info->clock_enable, 0); | 1495 | clk_disable(ssp->clk); |
1524 | 1496 | ||
1525 | /* Release DMA */ | 1497 | /* Release DMA */ |
1526 | if (drv_data->master_info->enable_dma) { | 1498 | if (drv_data->master_info->enable_dma) { |
1527 | if (drv_data->ioaddr == SSP1_VIRT) { | 1499 | DRCMR(ssp->drcmr_rx) = 0; |
1528 | DRCMRRXSSDR = 0; | 1500 | DRCMR(ssp->drcmr_tx) = 0; |
1529 | DRCMRTXSSDR = 0; | ||
1530 | } else if (drv_data->ioaddr == SSP2_VIRT) { | ||
1531 | DRCMRRXSS2DR = 0; | ||
1532 | DRCMRTXSS2DR = 0; | ||
1533 | } else if (drv_data->ioaddr == SSP3_VIRT) { | ||
1534 | DRCMRRXSS3DR = 0; | ||
1535 | DRCMRTXSS3DR = 0; | ||
1536 | } | ||
1537 | pxa_free_dma(drv_data->tx_channel); | 1501 | pxa_free_dma(drv_data->tx_channel); |
1538 | pxa_free_dma(drv_data->rx_channel); | 1502 | pxa_free_dma(drv_data->rx_channel); |
1539 | } | 1503 | } |
1540 | 1504 | ||
1541 | /* Release IRQ */ | 1505 | /* Release IRQ */ |
1542 | irq = platform_get_irq(pdev, 0); | 1506 | free_irq(ssp->irq, drv_data); |
1543 | if (irq >= 0) | 1507 | |
1544 | free_irq(irq, drv_data); | 1508 | /* Release SSP */ |
1509 | ssp_free(ssp); | ||
1545 | 1510 | ||
1546 | /* Disconnect from the SPI framework */ | 1511 | /* Disconnect from the SPI framework */ |
1547 | spi_unregister_master(drv_data->master); | 1512 | spi_unregister_master(drv_data->master); |
@@ -1576,6 +1541,7 @@ static int suspend_devices(struct device *dev, void *pm_message) | |||
1576 | static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | 1541 | static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) |
1577 | { | 1542 | { |
1578 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1543 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1544 | struct ssp_device *ssp = drv_data->ssp; | ||
1579 | int status = 0; | 1545 | int status = 0; |
1580 | 1546 | ||
1581 | /* Check all childern for current power state */ | 1547 | /* Check all childern for current power state */ |
@@ -1588,7 +1554,7 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | |||
1588 | if (status != 0) | 1554 | if (status != 0) |
1589 | return status; | 1555 | return status; |
1590 | write_SSCR0(0, drv_data->ioaddr); | 1556 | write_SSCR0(0, drv_data->ioaddr); |
1591 | pxa_set_cken(drv_data->master_info->clock_enable, 0); | 1557 | clk_disable(ssp->clk); |
1592 | 1558 | ||
1593 | return 0; | 1559 | return 0; |
1594 | } | 1560 | } |
@@ -1596,10 +1562,11 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | |||
1596 | static int pxa2xx_spi_resume(struct platform_device *pdev) | 1562 | static int pxa2xx_spi_resume(struct platform_device *pdev) |
1597 | { | 1563 | { |
1598 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1564 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1565 | struct ssp_device *ssp = drv_data->ssp; | ||
1599 | int status = 0; | 1566 | int status = 0; |
1600 | 1567 | ||
1601 | /* Enable the SSP clock */ | 1568 | /* Enable the SSP clock */ |
1602 | pxa_set_cken(drv_data->master_info->clock_enable, 1); | 1569 | clk_disable(ssp->clk); |
1603 | 1570 | ||
1604 | /* Start the queue running */ | 1571 | /* Start the queue running */ |
1605 | status = start_queue(drv_data); | 1572 | status = start_queue(drv_data); |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7580aa5da0f8..7a6499008b89 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -33,6 +33,7 @@ config USB_ARCH_HAS_OHCI | |||
33 | default y if ARCH_LH7A404 | 33 | default y if ARCH_LH7A404 |
34 | default y if ARCH_S3C2410 | 34 | default y if ARCH_S3C2410 |
35 | default y if PXA27x | 35 | default y if PXA27x |
36 | default y if PXA3xx | ||
36 | default y if ARCH_EP93XX | 37 | default y if ARCH_EP93XX |
37 | default y if ARCH_AT91 | 38 | default y if ARCH_AT91 |
38 | default y if ARCH_PNX4008 | 39 | default y if ARCH_PNX4008 |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f81d08d6538b..77a3759d6fc7 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -308,7 +308,7 @@ config USB_S3C2410_DEBUG | |||
308 | 308 | ||
309 | config USB_GADGET_AT91 | 309 | config USB_GADGET_AT91 |
310 | boolean "AT91 USB Device Port" | 310 | boolean "AT91 USB Device Port" |
311 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL | 311 | depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 |
312 | select USB_GADGET_SELECTED | 312 | select USB_GADGET_SELECTED |
313 | help | 313 | help |
314 | Many Atmel AT91 processors (such as the AT91RM2000) have a | 314 | Many Atmel AT91 processors (such as the AT91RM2000) have a |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ecfe800fd720..ddd4ee1f2413 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -997,7 +997,7 @@ MODULE_LICENSE ("GPL"); | |||
997 | #define PLATFORM_DRIVER ohci_hcd_lh7a404_driver | 997 | #define PLATFORM_DRIVER ohci_hcd_lh7a404_driver |
998 | #endif | 998 | #endif |
999 | 999 | ||
1000 | #ifdef CONFIG_PXA27x | 1000 | #if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) |
1001 | #include "ohci-pxa27x.c" | 1001 | #include "ohci-pxa27x.c" |
1002 | #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver | 1002 | #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver |
1003 | #endif | 1003 | #endif |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 23d2fe5a62f4..ff9a79843471 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/signal.h> | 23 | #include <linux/signal.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/clk.h> | ||
25 | 26 | ||
26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
27 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
@@ -32,6 +33,8 @@ | |||
32 | 33 | ||
33 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) | 34 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) |
34 | 35 | ||
36 | static struct clk *usb_clk; | ||
37 | |||
35 | /* | 38 | /* |
36 | PMM_NPS_MODE -- PMM Non-power switching mode | 39 | PMM_NPS_MODE -- PMM Non-power switching mode |
37 | Ports are powered continuously. | 40 | Ports are powered continuously. |
@@ -80,7 +83,7 @@ static int pxa27x_start_hc(struct device *dev) | |||
80 | 83 | ||
81 | inf = dev->platform_data; | 84 | inf = dev->platform_data; |
82 | 85 | ||
83 | pxa_set_cken(CKEN_USBHOST, 1); | 86 | clk_enable(usb_clk); |
84 | 87 | ||
85 | UHCHR |= UHCHR_FHR; | 88 | UHCHR |= UHCHR_FHR; |
86 | udelay(11); | 89 | udelay(11); |
@@ -123,7 +126,7 @@ static void pxa27x_stop_hc(struct device *dev) | |||
123 | UHCCOMS |= 1; | 126 | UHCCOMS |= 1; |
124 | udelay(10); | 127 | udelay(10); |
125 | 128 | ||
126 | pxa_set_cken(CKEN_USBHOST, 0); | 129 | clk_disable(usb_clk); |
127 | } | 130 | } |
128 | 131 | ||
129 | 132 | ||
@@ -158,6 +161,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device | |||
158 | return -ENOMEM; | 161 | return -ENOMEM; |
159 | } | 162 | } |
160 | 163 | ||
164 | usb_clk = clk_get(&pdev->dev, "USBCLK"); | ||
165 | if (IS_ERR(usb_clk)) | ||
166 | return PTR_ERR(usb_clk); | ||
167 | |||
161 | hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); | 168 | hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); |
162 | if (!hcd) | 169 | if (!hcd) |
163 | return -ENOMEM; | 170 | return -ENOMEM; |
@@ -201,6 +208,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device | |||
201 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 208 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
202 | err1: | 209 | err1: |
203 | usb_put_hcd(hcd); | 210 | usb_put_hcd(hcd); |
211 | clk_put(usb_clk); | ||
204 | return retval; | 212 | return retval; |
205 | } | 213 | } |
206 | 214 | ||
@@ -225,6 +233,7 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev) | |||
225 | iounmap(hcd->regs); | 233 | iounmap(hcd->regs); |
226 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 234 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
227 | usb_put_hcd(hcd); | 235 | usb_put_hcd(hcd); |
236 | clk_put(usb_clk); | ||
228 | } | 237 | } |
229 | 238 | ||
230 | /*-------------------------------------------------------------------------*/ | 239 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5b3dbcfcda48..758435f8a6f8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -889,7 +889,7 @@ config FB_S1D13XXX | |||
889 | 889 | ||
890 | config FB_ATMEL | 890 | config FB_ATMEL |
891 | tristate "AT91/AT32 LCD Controller support" | 891 | tristate "AT91/AT32 LCD Controller support" |
892 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || AVR32) | 892 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) |
893 | select FB_CFB_FILLRECT | 893 | select FB_CFB_FILLRECT |
894 | select FB_CFB_COPYAREA | 894 | select FB_CFB_COPYAREA |
895 | select FB_CFB_IMAGEBLIT | 895 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 7c30cc8df71e..f8e711147501 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 | 30 | #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 |
31 | #define ATMEL_LCDC_DMA_BURST_LEN 8 | 31 | #define ATMEL_LCDC_DMA_BURST_LEN 8 |
32 | 32 | ||
33 | #if defined(CONFIG_ARCH_AT91SAM9263) | 33 | #if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) |
34 | #define ATMEL_LCDC_FIFO_SIZE 2048 | 34 | #define ATMEL_LCDC_FIFO_SIZE 2048 |
35 | #else | 35 | #else |
36 | #define ATMEL_LCDC_FIFO_SIZE 512 | 36 | #define ATMEL_LCDC_FIFO_SIZE 512 |