diff options
Diffstat (limited to 'drivers')
268 files changed, 5083 insertions, 3548 deletions
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 81e970adeab3..b0d4b147b19e 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -129,11 +129,15 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | |||
129 | struct acpi_memory_info *info, *n; | 129 | struct acpi_memory_info *info, *n; |
130 | 130 | ||
131 | 131 | ||
132 | if (!list_empty(&mem_device->res_list)) | ||
133 | return 0; | ||
134 | |||
132 | status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, | 135 | status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, |
133 | acpi_memory_get_resource, mem_device); | 136 | acpi_memory_get_resource, mem_device); |
134 | if (ACPI_FAILURE(status)) { | 137 | if (ACPI_FAILURE(status)) { |
135 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) | 138 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) |
136 | kfree(info); | 139 | kfree(info); |
140 | INIT_LIST_HEAD(&mem_device->res_list); | ||
137 | return -EINVAL; | 141 | return -EINVAL; |
138 | } | 142 | } |
139 | 143 | ||
@@ -230,17 +234,10 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
230 | * (i.e. memory-hot-remove function) | 234 | * (i.e. memory-hot-remove function) |
231 | */ | 235 | */ |
232 | list_for_each_entry(info, &mem_device->res_list, list) { | 236 | list_for_each_entry(info, &mem_device->res_list, list) { |
233 | u64 start_pfn, end_pfn; | 237 | if (info->enabled) { /* just sanity check...*/ |
234 | |||
235 | start_pfn = info->start_addr >> PAGE_SHIFT; | ||
236 | end_pfn = (info->start_addr + info->length - 1) >> PAGE_SHIFT; | ||
237 | |||
238 | if (pfn_valid(start_pfn) || pfn_valid(end_pfn)) { | ||
239 | /* already enabled. try next area */ | ||
240 | num_enabled++; | 238 | num_enabled++; |
241 | continue; | 239 | continue; |
242 | } | 240 | } |
243 | |||
244 | result = add_memory(node, info->start_addr, info->length); | 241 | result = add_memory(node, info->start_addr, info->length); |
245 | if (result) | 242 | if (result) |
246 | continue; | 243 | continue; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 1c0a39d8b04e..578b99b71d9c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -58,8 +58,8 @@ struct dock_dependent_device { | |||
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define DOCK_DOCKING 0x00000001 | 60 | #define DOCK_DOCKING 0x00000001 |
61 | #define DOCK_EVENT KOBJ_DOCK | 61 | #define DOCK_EVENT 3 |
62 | #define UNDOCK_EVENT KOBJ_UNDOCK | 62 | #define UNDOCK_EVENT 2 |
63 | 63 | ||
64 | static struct dock_station *dock_station; | 64 | static struct dock_station *dock_station; |
65 | 65 | ||
@@ -322,11 +322,10 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
322 | 322 | ||
323 | static void dock_event(struct dock_station *ds, u32 event, int num) | 323 | static void dock_event(struct dock_station *ds, u32 event, int num) |
324 | { | 324 | { |
325 | struct acpi_device *device; | 325 | /* |
326 | 326 | * we don't do events until someone tells me that | |
327 | device = dock_create_acpi_device(ds->handle); | 327 | * they would like to have them. |
328 | if (device) | 328 | */ |
329 | kobject_uevent(&device->kobj, num); | ||
330 | } | 329 | } |
331 | 330 | ||
332 | /** | 331 | /** |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index c2d621632383..3ef9d514b916 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -139,7 +139,7 @@ static int __cpuinit topology_sysfs_init(void) | |||
139 | (void *)(long)i); | 139 | (void *)(long)i); |
140 | } | 140 | } |
141 | 141 | ||
142 | register_cpu_notifier(&topology_cpu_notifier); | 142 | register_hotcpu_notifier(&topology_cpu_notifier); |
143 | 143 | ||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1c4df22dfd2a..7b0eca703a67 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1233,6 +1233,50 @@ static inline void complete_buffers(struct bio *bio, int status) | |||
1233 | } | 1233 | } |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | static void cciss_check_queues(ctlr_info_t *h) | ||
1237 | { | ||
1238 | int start_queue = h->next_to_run; | ||
1239 | int i; | ||
1240 | |||
1241 | /* check to see if we have maxed out the number of commands that can | ||
1242 | * be placed on the queue. If so then exit. We do this check here | ||
1243 | * in case the interrupt we serviced was from an ioctl and did not | ||
1244 | * free any new commands. | ||
1245 | */ | ||
1246 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) | ||
1247 | return; | ||
1248 | |||
1249 | /* We have room on the queue for more commands. Now we need to queue | ||
1250 | * them up. We will also keep track of the next queue to run so | ||
1251 | * that every queue gets a chance to be started first. | ||
1252 | */ | ||
1253 | for (i = 0; i < h->highest_lun + 1; i++) { | ||
1254 | int curr_queue = (start_queue + i) % (h->highest_lun + 1); | ||
1255 | /* make sure the disk has been added and the drive is real | ||
1256 | * because this can be called from the middle of init_one. | ||
1257 | */ | ||
1258 | if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) | ||
1259 | continue; | ||
1260 | blk_start_queue(h->gendisk[curr_queue]->queue); | ||
1261 | |||
1262 | /* check to see if we have maxed out the number of commands | ||
1263 | * that can be placed on the queue. | ||
1264 | */ | ||
1265 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { | ||
1266 | if (curr_queue == start_queue) { | ||
1267 | h->next_to_run = | ||
1268 | (start_queue + 1) % (h->highest_lun + 1); | ||
1269 | break; | ||
1270 | } else { | ||
1271 | h->next_to_run = curr_queue; | ||
1272 | break; | ||
1273 | } | ||
1274 | } else { | ||
1275 | curr_queue = (curr_queue + 1) % (h->highest_lun + 1); | ||
1276 | } | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1236 | static void cciss_softirq_done(struct request *rq) | 1280 | static void cciss_softirq_done(struct request *rq) |
1237 | { | 1281 | { |
1238 | CommandList_struct *cmd = rq->completion_data; | 1282 | CommandList_struct *cmd = rq->completion_data; |
@@ -1264,6 +1308,7 @@ static void cciss_softirq_done(struct request *rq) | |||
1264 | spin_lock_irqsave(&h->lock, flags); | 1308 | spin_lock_irqsave(&h->lock, flags); |
1265 | end_that_request_last(rq, rq->errors); | 1309 | end_that_request_last(rq, rq->errors); |
1266 | cmd_free(h, cmd, 1); | 1310 | cmd_free(h, cmd, 1); |
1311 | cciss_check_queues(h); | ||
1267 | spin_unlock_irqrestore(&h->lock, flags); | 1312 | spin_unlock_irqrestore(&h->lock, flags); |
1268 | } | 1313 | } |
1269 | 1314 | ||
@@ -2528,8 +2573,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2528 | CommandList_struct *c; | 2573 | CommandList_struct *c; |
2529 | unsigned long flags; | 2574 | unsigned long flags; |
2530 | __u32 a, a1, a2; | 2575 | __u32 a, a1, a2; |
2531 | int j; | ||
2532 | int start_queue = h->next_to_run; | ||
2533 | 2576 | ||
2534 | if (interrupt_not_for_us(h)) | 2577 | if (interrupt_not_for_us(h)) |
2535 | return IRQ_NONE; | 2578 | return IRQ_NONE; |
@@ -2588,45 +2631,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2588 | } | 2631 | } |
2589 | } | 2632 | } |
2590 | 2633 | ||
2591 | /* check to see if we have maxed out the number of commands that can | ||
2592 | * be placed on the queue. If so then exit. We do this check here | ||
2593 | * in case the interrupt we serviced was from an ioctl and did not | ||
2594 | * free any new commands. | ||
2595 | */ | ||
2596 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) | ||
2597 | goto cleanup; | ||
2598 | |||
2599 | /* We have room on the queue for more commands. Now we need to queue | ||
2600 | * them up. We will also keep track of the next queue to run so | ||
2601 | * that every queue gets a chance to be started first. | ||
2602 | */ | ||
2603 | for (j = 0; j < h->highest_lun + 1; j++) { | ||
2604 | int curr_queue = (start_queue + j) % (h->highest_lun + 1); | ||
2605 | /* make sure the disk has been added and the drive is real | ||
2606 | * because this can be called from the middle of init_one. | ||
2607 | */ | ||
2608 | if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) | ||
2609 | continue; | ||
2610 | blk_start_queue(h->gendisk[curr_queue]->queue); | ||
2611 | |||
2612 | /* check to see if we have maxed out the number of commands | ||
2613 | * that can be placed on the queue. | ||
2614 | */ | ||
2615 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { | ||
2616 | if (curr_queue == start_queue) { | ||
2617 | h->next_to_run = | ||
2618 | (start_queue + 1) % (h->highest_lun + 1); | ||
2619 | goto cleanup; | ||
2620 | } else { | ||
2621 | h->next_to_run = curr_queue; | ||
2622 | goto cleanup; | ||
2623 | } | ||
2624 | } else { | ||
2625 | curr_queue = (curr_queue + 1) % (h->highest_lun + 1); | ||
2626 | } | ||
2627 | } | ||
2628 | |||
2629 | cleanup: | ||
2630 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2634 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
2631 | return IRQ_HANDLED; | 2635 | return IRQ_HANDLED; |
2632 | } | 2636 | } |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 0a1b1ea36ddc..bdbade9a5cf5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -300,6 +300,15 @@ static struct request *nbd_read_stat(struct nbd_device *lo) | |||
300 | lo->disk->disk_name, result); | 300 | lo->disk->disk_name, result); |
301 | goto harderror; | 301 | goto harderror; |
302 | } | 302 | } |
303 | |||
304 | if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { | ||
305 | printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", | ||
306 | lo->disk->disk_name, | ||
307 | (unsigned long)ntohl(reply.magic)); | ||
308 | result = -EPROTO; | ||
309 | goto harderror; | ||
310 | } | ||
311 | |||
303 | req = nbd_find_request(lo, reply.handle); | 312 | req = nbd_find_request(lo, reply.handle); |
304 | if (unlikely(IS_ERR(req))) { | 313 | if (unlikely(IS_ERR(req))) { |
305 | result = PTR_ERR(req); | 314 | result = PTR_ERR(req); |
@@ -312,13 +321,6 @@ static struct request *nbd_read_stat(struct nbd_device *lo) | |||
312 | goto harderror; | 321 | goto harderror; |
313 | } | 322 | } |
314 | 323 | ||
315 | if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { | ||
316 | printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", | ||
317 | lo->disk->disk_name, | ||
318 | (unsigned long)ntohl(reply.magic)); | ||
319 | result = -EPROTO; | ||
320 | goto harderror; | ||
321 | } | ||
322 | if (ntohl(reply.error)) { | 324 | if (ntohl(reply.error)) { |
323 | printk(KERN_ERR "%s: Other side returned error (%d)\n", | 325 | printk(KERN_ERR "%s: Other side returned error (%d)\n", |
324 | lo->disk->disk_name, ntohl(reply.error)); | 326 | lo->disk->disk_name, ntohl(reply.error)); |
@@ -339,7 +341,8 @@ static struct request *nbd_read_stat(struct nbd_device *lo) | |||
339 | printk(KERN_ERR "%s: Receive data failed (result %d)\n", | 341 | printk(KERN_ERR "%s: Receive data failed (result %d)\n", |
340 | lo->disk->disk_name, | 342 | lo->disk->disk_name, |
341 | result); | 343 | result); |
342 | goto harderror; | 344 | req->errors++; |
345 | return req; | ||
343 | } | 346 | } |
344 | dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", | 347 | dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", |
345 | lo->disk->disk_name, req, bvec->bv_len); | 348 | lo->disk->disk_name, req, bvec->bv_len); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index bde2c64b6346..451b996bba91 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2577,19 +2577,19 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
2577 | case PKT_CTRL_CMD_SETUP: | 2577 | case PKT_CTRL_CMD_SETUP: |
2578 | if (!capable(CAP_SYS_ADMIN)) | 2578 | if (!capable(CAP_SYS_ADMIN)) |
2579 | return -EPERM; | 2579 | return -EPERM; |
2580 | mutex_lock(&ctl_mutex); | 2580 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); |
2581 | ret = pkt_setup_dev(&ctrl_cmd); | 2581 | ret = pkt_setup_dev(&ctrl_cmd); |
2582 | mutex_unlock(&ctl_mutex); | 2582 | mutex_unlock(&ctl_mutex); |
2583 | break; | 2583 | break; |
2584 | case PKT_CTRL_CMD_TEARDOWN: | 2584 | case PKT_CTRL_CMD_TEARDOWN: |
2585 | if (!capable(CAP_SYS_ADMIN)) | 2585 | if (!capable(CAP_SYS_ADMIN)) |
2586 | return -EPERM; | 2586 | return -EPERM; |
2587 | mutex_lock(&ctl_mutex); | 2587 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); |
2588 | ret = pkt_remove_dev(&ctrl_cmd); | 2588 | ret = pkt_remove_dev(&ctrl_cmd); |
2589 | mutex_unlock(&ctl_mutex); | 2589 | mutex_unlock(&ctl_mutex); |
2590 | break; | 2590 | break; |
2591 | case PKT_CTRL_CMD_STATUS: | 2591 | case PKT_CTRL_CMD_STATUS: |
2592 | mutex_lock(&ctl_mutex); | 2592 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); |
2593 | pkt_get_status(&ctrl_cmd); | 2593 | pkt_get_status(&ctrl_cmd); |
2594 | mutex_unlock(&ctl_mutex); | 2594 | mutex_unlock(&ctl_mutex); |
2595 | break; | 2595 | break; |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 6a0c2230f82f..e2d4beac7420 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -67,6 +67,8 @@ static int ignore = 0; | |||
67 | static int ignore_dga = 0; | 67 | static int ignore_dga = 0; |
68 | static int ignore_csr = 0; | 68 | static int ignore_csr = 0; |
69 | static int ignore_sniffer = 0; | 69 | static int ignore_sniffer = 0; |
70 | static int disable_scofix = 0; | ||
71 | static int force_scofix = 0; | ||
70 | static int reset = 0; | 72 | static int reset = 0; |
71 | 73 | ||
72 | #ifdef CONFIG_BT_HCIUSB_SCO | 74 | #ifdef CONFIG_BT_HCIUSB_SCO |
@@ -107,9 +109,12 @@ static struct usb_device_id blacklist_ids[] = { | |||
107 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, | 109 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, |
108 | 110 | ||
109 | /* Broadcom BCM2035 */ | 111 | /* Broadcom BCM2035 */ |
110 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC }, | 112 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, |
111 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, | 113 | { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, |
112 | 114 | ||
115 | /* IBM/Lenovo ThinkPad with Broadcom chip */ | ||
116 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, | ||
117 | |||
113 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ | 118 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ |
114 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, | 119 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, |
115 | 120 | ||
@@ -119,11 +124,13 @@ static struct usb_device_id blacklist_ids[] = { | |||
119 | /* ISSC Bluetooth Adapter v3.1 */ | 124 | /* ISSC Bluetooth Adapter v3.1 */ |
120 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, | 125 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, |
121 | 126 | ||
122 | /* RTX Telecom based adapter with buggy SCO support */ | 127 | /* RTX Telecom based adapters with buggy SCO support */ |
123 | { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, | 128 | { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, |
129 | { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, | ||
124 | 130 | ||
125 | /* Belkin F8T012 */ | 131 | /* Belkin F8T012 and F8T013 devices */ |
126 | { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, | 132 | { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, |
133 | { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU }, | ||
127 | 134 | ||
128 | /* Digianswer devices */ | 135 | /* Digianswer devices */ |
129 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, | 136 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, |
@@ -990,8 +997,10 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id | |||
990 | if (reset || id->driver_info & HCI_RESET) | 997 | if (reset || id->driver_info & HCI_RESET) |
991 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); | 998 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); |
992 | 999 | ||
993 | if (id->driver_info & HCI_WRONG_SCO_MTU) | 1000 | if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) { |
994 | set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); | 1001 | if (!disable_scofix) |
1002 | set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); | ||
1003 | } | ||
995 | 1004 | ||
996 | if (id->driver_info & HCI_SNIFFER) { | 1005 | if (id->driver_info & HCI_SNIFFER) { |
997 | if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) | 1006 | if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) |
@@ -1161,6 +1170,12 @@ MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); | |||
1161 | module_param(ignore_sniffer, bool, 0644); | 1170 | module_param(ignore_sniffer, bool, 0644); |
1162 | MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); | 1171 | MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); |
1163 | 1172 | ||
1173 | module_param(disable_scofix, bool, 0644); | ||
1174 | MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size"); | ||
1175 | |||
1176 | module_param(force_scofix, bool, 0644); | ||
1177 | MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size"); | ||
1178 | |||
1164 | module_param(reset, bool, 0644); | 1179 | module_param(reset, bool, 0644); |
1165 | MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); | 1180 | MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); |
1166 | 1181 | ||
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 41db8060e8f7..017f755632a3 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -311,7 +311,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, | |||
311 | /* CD went away; no more connection */ | 311 | /* CD went away; no more connection */ |
312 | pr_debug("hvsi%i: CD dropped\n", hp->index); | 312 | pr_debug("hvsi%i: CD dropped\n", hp->index); |
313 | hp->mctrl &= TIOCM_CD; | 313 | hp->mctrl &= TIOCM_CD; |
314 | if (!(hp->tty->flags & CLOCAL)) | 314 | /* If userland hasn't done an open(2) yet, hp->tty is NULL. */ |
315 | if (hp->tty && !(hp->tty->flags & CLOCAL)) | ||
315 | *to_hangup = hp->tty; | 316 | *to_hangup = hp->tty; |
316 | } | 317 | } |
317 | break; | 318 | break; |
@@ -986,10 +987,7 @@ static void hvsi_write_worker(void *arg) | |||
986 | start_j = 0; | 987 | start_j = 0; |
987 | #endif /* DEBUG */ | 988 | #endif /* DEBUG */ |
988 | wake_up_all(&hp->emptyq); | 989 | wake_up_all(&hp->emptyq); |
989 | if (test_bit(TTY_DO_WRITE_WAKEUP, &hp->tty->flags) | 990 | tty_wakeup(hp->tty); |
990 | && hp->tty->ldisc.write_wakeup) | ||
991 | hp->tty->ldisc.write_wakeup(hp->tty); | ||
992 | wake_up_interruptible(&hp->tty->write_wait); | ||
993 | } | 991 | } |
994 | 992 | ||
995 | out: | 993 | out: |
diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index be61f22ee7bb..d37ced0d132b 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c | |||
@@ -107,10 +107,14 @@ found: | |||
107 | if (err) { | 107 | if (err) { |
108 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 108 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
109 | err); | 109 | err); |
110 | goto out; | 110 | goto err_unmap; |
111 | } | 111 | } |
112 | out: | 112 | out: |
113 | return err; | 113 | return err; |
114 | |||
115 | err_unmap: | ||
116 | iounmap(mem); | ||
117 | goto out; | ||
114 | } | 118 | } |
115 | 119 | ||
116 | static void __exit mod_exit(void) | 120 | static void __exit mod_exit(void) |
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 6594bd5645f4..ccd7e7102234 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -164,7 +164,7 @@ static int __init mod_init(void) | |||
164 | if (err) { | 164 | if (err) { |
165 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 165 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
166 | err); | 166 | err); |
167 | goto out; | 167 | goto err_unmap; |
168 | } | 168 | } |
169 | out: | 169 | out: |
170 | return err; | 170 | return err; |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 819516b35a79..a01d796d1eeb 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -25,12 +25,12 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/random.h> | 27 | #include <linux/random.h> |
28 | #include <linux/clk.h> | ||
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/device.h> | 30 | #include <linux/platform_device.h> |
30 | #include <linux/hw_random.h> | 31 | #include <linux/hw_random.h> |
31 | 32 | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/hardware/clock.h> | ||
34 | 34 | ||
35 | #define RNG_OUT_REG 0x00 /* Output register */ | 35 | #define RNG_OUT_REG 0x00 /* Output register */ |
36 | #define RNG_STAT_REG 0x04 /* Status register | 36 | #define RNG_STAT_REG 0x04 /* Status register |
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | static void __iomem *rng_base; | 53 | static void __iomem *rng_base; |
54 | static struct clk *rng_ick; | 54 | static struct clk *rng_ick; |
55 | static struct device *rng_dev; | 55 | static struct platform_device *rng_dev; |
56 | 56 | ||
57 | static u32 omap_rng_read_reg(int reg) | 57 | static u32 omap_rng_read_reg(int reg) |
58 | { | 58 | { |
@@ -83,9 +83,8 @@ static struct hwrng omap_rng_ops = { | |||
83 | .data_read = omap_rng_data_read, | 83 | .data_read = omap_rng_data_read, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static int __init omap_rng_probe(struct device *dev) | 86 | static int __init omap_rng_probe(struct platform_device *pdev) |
87 | { | 87 | { |
88 | struct platform_device *pdev = to_platform_device(dev); | ||
89 | struct resource *res, *mem; | 88 | struct resource *res, *mem; |
90 | int ret; | 89 | int ret; |
91 | 90 | ||
@@ -95,16 +94,14 @@ static int __init omap_rng_probe(struct device *dev) | |||
95 | */ | 94 | */ |
96 | BUG_ON(rng_dev); | 95 | BUG_ON(rng_dev); |
97 | 96 | ||
98 | if (cpu_is_omap24xx()) { | 97 | if (cpu_is_omap24xx()) { |
99 | rng_ick = clk_get(NULL, "rng_ick"); | 98 | rng_ick = clk_get(NULL, "rng_ick"); |
100 | if (IS_ERR(rng_ick)) { | 99 | if (IS_ERR(rng_ick)) { |
101 | dev_err(dev, "Could not get rng_ick\n"); | 100 | dev_err(&pdev->dev, "Could not get rng_ick\n"); |
102 | ret = PTR_ERR(rng_ick); | 101 | ret = PTR_ERR(rng_ick); |
103 | return ret; | 102 | return ret; |
104 | } | 103 | } else |
105 | else { | 104 | clk_enable(rng_ick); |
106 | clk_use(rng_ick); | ||
107 | } | ||
108 | } | 105 | } |
109 | 106 | ||
110 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 107 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -117,7 +114,7 @@ static int __init omap_rng_probe(struct device *dev) | |||
117 | if (mem == NULL) | 114 | if (mem == NULL) |
118 | return -EBUSY; | 115 | return -EBUSY; |
119 | 116 | ||
120 | dev_set_drvdata(dev, mem); | 117 | dev_set_drvdata(&pdev->dev, mem); |
121 | rng_base = (u32 __iomem *)io_p2v(res->start); | 118 | rng_base = (u32 __iomem *)io_p2v(res->start); |
122 | 119 | ||
123 | ret = hwrng_register(&omap_rng_ops); | 120 | ret = hwrng_register(&omap_rng_ops); |
@@ -127,25 +124,25 @@ static int __init omap_rng_probe(struct device *dev) | |||
127 | return ret; | 124 | return ret; |
128 | } | 125 | } |
129 | 126 | ||
130 | dev_info(dev, "OMAP Random Number Generator ver. %02x\n", | 127 | dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", |
131 | omap_rng_read_reg(RNG_REV_REG)); | 128 | omap_rng_read_reg(RNG_REV_REG)); |
132 | omap_rng_write_reg(RNG_MASK_REG, 0x1); | 129 | omap_rng_write_reg(RNG_MASK_REG, 0x1); |
133 | 130 | ||
134 | rng_dev = dev; | 131 | rng_dev = pdev; |
135 | 132 | ||
136 | return 0; | 133 | return 0; |
137 | } | 134 | } |
138 | 135 | ||
139 | static int __exit omap_rng_remove(struct device *dev) | 136 | static int __exit omap_rng_remove(struct platform_device *pdev) |
140 | { | 137 | { |
141 | struct resource *mem = dev_get_drvdata(dev); | 138 | struct resource *mem = dev_get_drvdata(&pdev->dev); |
142 | 139 | ||
143 | hwrng_unregister(&omap_rng_ops); | 140 | hwrng_unregister(&omap_rng_ops); |
144 | 141 | ||
145 | omap_rng_write_reg(RNG_MASK_REG, 0x0); | 142 | omap_rng_write_reg(RNG_MASK_REG, 0x0); |
146 | 143 | ||
147 | if (cpu_is_omap24xx()) { | 144 | if (cpu_is_omap24xx()) { |
148 | clk_unuse(rng_ick); | 145 | clk_disable(rng_ick); |
149 | clk_put(rng_ick); | 146 | clk_put(rng_ick); |
150 | } | 147 | } |
151 | 148 | ||
@@ -157,18 +154,16 @@ static int __exit omap_rng_remove(struct device *dev) | |||
157 | 154 | ||
158 | #ifdef CONFIG_PM | 155 | #ifdef CONFIG_PM |
159 | 156 | ||
160 | static int omap_rng_suspend(struct device *dev, pm_message_t message, u32 level) | 157 | static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message) |
161 | { | 158 | { |
162 | omap_rng_write_reg(RNG_MASK_REG, 0x0); | 159 | omap_rng_write_reg(RNG_MASK_REG, 0x0); |
163 | |||
164 | return 0; | 160 | return 0; |
165 | } | 161 | } |
166 | 162 | ||
167 | static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level) | 163 | static int omap_rng_resume(struct platform_device *pdev) |
168 | { | 164 | { |
169 | omap_rng_write_reg(RNG_MASK_REG, 0x1); | 165 | omap_rng_write_reg(RNG_MASK_REG, 0x1); |
170 | 166 | return 0; | |
171 | return 1; | ||
172 | } | 167 | } |
173 | 168 | ||
174 | #else | 169 | #else |
@@ -179,9 +174,11 @@ static int omap_rng_resume(struct device *dev, pm_message_t message, u32 level) | |||
179 | #endif | 174 | #endif |
180 | 175 | ||
181 | 176 | ||
182 | static struct device_driver omap_rng_driver = { | 177 | static struct platform_driver omap_rng_driver = { |
183 | .name = "omap_rng", | 178 | .driver = { |
184 | .bus = &platform_bus_type, | 179 | .name = "omap_rng", |
180 | .owner = THIS_MODULE, | ||
181 | }, | ||
185 | .probe = omap_rng_probe, | 182 | .probe = omap_rng_probe, |
186 | .remove = __exit_p(omap_rng_remove), | 183 | .remove = __exit_p(omap_rng_remove), |
187 | .suspend = omap_rng_suspend, | 184 | .suspend = omap_rng_suspend, |
@@ -193,12 +190,12 @@ static int __init omap_rng_init(void) | |||
193 | if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) | 190 | if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) |
194 | return -ENODEV; | 191 | return -ENODEV; |
195 | 192 | ||
196 | return driver_register(&omap_rng_driver); | 193 | return platform_driver_register(&omap_rng_driver); |
197 | } | 194 | } |
198 | 195 | ||
199 | static void __exit omap_rng_exit(void) | 196 | static void __exit omap_rng_exit(void) |
200 | { | 197 | { |
201 | driver_unregister(&omap_rng_driver); | 198 | platform_driver_unregister(&omap_rng_driver); |
202 | } | 199 | } |
203 | 200 | ||
204 | module_init(omap_rng_init); | 201 | module_init(omap_rng_init); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 056ebe84b81d..3e90aac37510 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -107,7 +107,6 @@ const int NR_TYPES = ARRAY_SIZE(max_vals); | |||
107 | 107 | ||
108 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | 108 | struct kbd_struct kbd_table[MAX_NR_CONSOLES]; |
109 | static struct kbd_struct *kbd = kbd_table; | 109 | static struct kbd_struct *kbd = kbd_table; |
110 | static struct kbd_struct kbd0; | ||
111 | 110 | ||
112 | int spawnpid, spawnsig; | 111 | int spawnpid, spawnsig; |
113 | 112 | ||
@@ -223,13 +222,13 @@ static void kd_nosound(unsigned long ignored) | |||
223 | { | 222 | { |
224 | struct list_head *node; | 223 | struct list_head *node; |
225 | 224 | ||
226 | list_for_each(node,&kbd_handler.h_list) { | 225 | list_for_each(node, &kbd_handler.h_list) { |
227 | struct input_handle *handle = to_handle_h(node); | 226 | struct input_handle *handle = to_handle_h(node); |
228 | if (test_bit(EV_SND, handle->dev->evbit)) { | 227 | if (test_bit(EV_SND, handle->dev->evbit)) { |
229 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 228 | if (test_bit(SND_TONE, handle->dev->sndbit)) |
230 | input_event(handle->dev, EV_SND, SND_TONE, 0); | 229 | input_inject_event(handle, EV_SND, SND_TONE, 0); |
231 | if (test_bit(SND_BELL, handle->dev->sndbit)) | 230 | if (test_bit(SND_BELL, handle->dev->sndbit)) |
232 | input_event(handle->dev, EV_SND, SND_BELL, 0); | 231 | input_inject_event(handle, EV_SND, SND_BELL, 0); |
233 | } | 232 | } |
234 | } | 233 | } |
235 | } | 234 | } |
@@ -247,11 +246,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks) | |||
247 | struct input_handle *handle = to_handle_h(node); | 246 | struct input_handle *handle = to_handle_h(node); |
248 | if (test_bit(EV_SND, handle->dev->evbit)) { | 247 | if (test_bit(EV_SND, handle->dev->evbit)) { |
249 | if (test_bit(SND_TONE, handle->dev->sndbit)) { | 248 | if (test_bit(SND_TONE, handle->dev->sndbit)) { |
250 | input_event(handle->dev, EV_SND, SND_TONE, hz); | 249 | input_inject_event(handle, EV_SND, SND_TONE, hz); |
251 | break; | 250 | break; |
252 | } | 251 | } |
253 | if (test_bit(SND_BELL, handle->dev->sndbit)) { | 252 | if (test_bit(SND_BELL, handle->dev->sndbit)) { |
254 | input_event(handle->dev, EV_SND, SND_BELL, 1); | 253 | input_inject_event(handle, EV_SND, SND_BELL, 1); |
255 | break; | 254 | break; |
256 | } | 255 | } |
257 | } | 256 | } |
@@ -272,15 +271,15 @@ int kbd_rate(struct kbd_repeat *rep) | |||
272 | unsigned int d = 0; | 271 | unsigned int d = 0; |
273 | unsigned int p = 0; | 272 | unsigned int p = 0; |
274 | 273 | ||
275 | list_for_each(node,&kbd_handler.h_list) { | 274 | list_for_each(node, &kbd_handler.h_list) { |
276 | struct input_handle *handle = to_handle_h(node); | 275 | struct input_handle *handle = to_handle_h(node); |
277 | struct input_dev *dev = handle->dev; | 276 | struct input_dev *dev = handle->dev; |
278 | 277 | ||
279 | if (test_bit(EV_REP, dev->evbit)) { | 278 | if (test_bit(EV_REP, dev->evbit)) { |
280 | if (rep->delay > 0) | 279 | if (rep->delay > 0) |
281 | input_event(dev, EV_REP, REP_DELAY, rep->delay); | 280 | input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); |
282 | if (rep->period > 0) | 281 | if (rep->period > 0) |
283 | input_event(dev, EV_REP, REP_PERIOD, rep->period); | 282 | input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); |
284 | d = dev->rep[REP_DELAY]; | 283 | d = dev->rep[REP_DELAY]; |
285 | p = dev->rep[REP_PERIOD]; | 284 | p = dev->rep[REP_PERIOD]; |
286 | } | 285 | } |
@@ -988,7 +987,7 @@ static inline unsigned char getleds(void) | |||
988 | * interrupt routines for this thing allows us to easily mask | 987 | * interrupt routines for this thing allows us to easily mask |
989 | * this when we don't want any of the above to happen. | 988 | * this when we don't want any of the above to happen. |
990 | * This allows for easy and efficient race-condition prevention | 989 | * This allows for easy and efficient race-condition prevention |
991 | * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ... | 990 | * for kbd_start => input_inject_event(dev, EV_LED, ...) => ... |
992 | */ | 991 | */ |
993 | 992 | ||
994 | static void kbd_bh(unsigned long dummy) | 993 | static void kbd_bh(unsigned long dummy) |
@@ -998,11 +997,11 @@ static void kbd_bh(unsigned long dummy) | |||
998 | 997 | ||
999 | if (leds != ledstate) { | 998 | if (leds != ledstate) { |
1000 | list_for_each(node, &kbd_handler.h_list) { | 999 | list_for_each(node, &kbd_handler.h_list) { |
1001 | struct input_handle * handle = to_handle_h(node); | 1000 | struct input_handle *handle = to_handle_h(node); |
1002 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1001 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); |
1003 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | 1002 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); |
1004 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | 1003 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); |
1005 | input_sync(handle->dev); | 1004 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); |
1006 | } | 1005 | } |
1007 | } | 1006 | } |
1008 | 1007 | ||
@@ -1011,23 +1010,6 @@ static void kbd_bh(unsigned long dummy) | |||
1011 | 1010 | ||
1012 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); | 1011 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); |
1013 | 1012 | ||
1014 | /* | ||
1015 | * This allows a newly plugged keyboard to pick the LED state. | ||
1016 | */ | ||
1017 | static void kbd_refresh_leds(struct input_handle *handle) | ||
1018 | { | ||
1019 | unsigned char leds = ledstate; | ||
1020 | |||
1021 | tasklet_disable(&keyboard_tasklet); | ||
1022 | if (leds != 0xff) { | ||
1023 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1024 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1025 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1026 | input_sync(handle->dev); | ||
1027 | } | ||
1028 | tasklet_enable(&keyboard_tasklet); | ||
1029 | } | ||
1030 | |||
1031 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ | 1013 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ |
1032 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ | 1014 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ |
1033 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ | 1015 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ |
@@ -1043,7 +1025,7 @@ static const unsigned short x86_keycodes[256] = | |||
1043 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, | 1025 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
1044 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, | 1026 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
1045 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, | 1027 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, |
1046 | 284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, | 1028 | 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, |
1047 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, | 1029 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, |
1048 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, | 1030 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, |
1049 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, | 1031 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, |
@@ -1065,38 +1047,55 @@ extern void sun_do_break(void); | |||
1065 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, | 1047 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, |
1066 | unsigned char up_flag) | 1048 | unsigned char up_flag) |
1067 | { | 1049 | { |
1068 | if (keycode > 255 || !x86_keycodes[keycode]) | 1050 | int code; |
1069 | return -1; | ||
1070 | 1051 | ||
1071 | switch (keycode) { | 1052 | switch (keycode) { |
1072 | case KEY_PAUSE: | 1053 | case KEY_PAUSE: |
1073 | put_queue(vc, 0xe1); | 1054 | put_queue(vc, 0xe1); |
1074 | put_queue(vc, 0x1d | up_flag); | 1055 | put_queue(vc, 0x1d | up_flag); |
1075 | put_queue(vc, 0x45 | up_flag); | 1056 | put_queue(vc, 0x45 | up_flag); |
1076 | return 0; | 1057 | break; |
1058 | |||
1077 | case KEY_HANGEUL: | 1059 | case KEY_HANGEUL: |
1078 | if (!up_flag) | 1060 | if (!up_flag) |
1079 | put_queue(vc, 0xf2); | 1061 | put_queue(vc, 0xf2); |
1080 | return 0; | 1062 | break; |
1063 | |||
1081 | case KEY_HANJA: | 1064 | case KEY_HANJA: |
1082 | if (!up_flag) | 1065 | if (!up_flag) |
1083 | put_queue(vc, 0xf1); | 1066 | put_queue(vc, 0xf1); |
1084 | return 0; | 1067 | break; |
1085 | } | ||
1086 | 1068 | ||
1087 | if (keycode == KEY_SYSRQ && sysrq_alt) { | 1069 | case KEY_SYSRQ: |
1088 | put_queue(vc, 0x54 | up_flag); | 1070 | /* |
1089 | return 0; | 1071 | * Real AT keyboards (that's what we're trying |
1090 | } | 1072 | * to emulate here emit 0xe0 0x2a 0xe0 0x37 when |
1073 | * pressing PrtSc/SysRq alone, but simply 0x54 | ||
1074 | * when pressing Alt+PrtSc/SysRq. | ||
1075 | */ | ||
1076 | if (sysrq_alt) { | ||
1077 | put_queue(vc, 0x54 | up_flag); | ||
1078 | } else { | ||
1079 | put_queue(vc, 0xe0); | ||
1080 | put_queue(vc, 0x2a | up_flag); | ||
1081 | put_queue(vc, 0xe0); | ||
1082 | put_queue(vc, 0x37 | up_flag); | ||
1083 | } | ||
1084 | break; | ||
1085 | |||
1086 | default: | ||
1087 | if (keycode > 255) | ||
1088 | return -1; | ||
1091 | 1089 | ||
1092 | if (x86_keycodes[keycode] & 0x100) | 1090 | code = x86_keycodes[keycode]; |
1093 | put_queue(vc, 0xe0); | 1091 | if (!code) |
1092 | return -1; | ||
1094 | 1093 | ||
1095 | put_queue(vc, (x86_keycodes[keycode] & 0x7f) | up_flag); | 1094 | if (code & 0x100) |
1095 | put_queue(vc, 0xe0); | ||
1096 | put_queue(vc, (code & 0x7f) | up_flag); | ||
1096 | 1097 | ||
1097 | if (keycode == KEY_SYSRQ) { | 1098 | break; |
1098 | put_queue(vc, 0xe0); | ||
1099 | put_queue(vc, 0x37 | up_flag); | ||
1100 | } | 1099 | } |
1101 | 1100 | ||
1102 | return 0; | 1101 | return 0; |
@@ -1298,16 +1297,15 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1298 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) | 1297 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) |
1299 | return NULL; | 1298 | return NULL; |
1300 | 1299 | ||
1301 | if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) | 1300 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
1301 | if (!handle) | ||
1302 | return NULL; | 1302 | return NULL; |
1303 | memset(handle, 0, sizeof(struct input_handle)); | ||
1304 | 1303 | ||
1305 | handle->dev = dev; | 1304 | handle->dev = dev; |
1306 | handle->handler = handler; | 1305 | handle->handler = handler; |
1307 | handle->name = "kbd"; | 1306 | handle->name = "kbd"; |
1308 | 1307 | ||
1309 | input_open_device(handle); | 1308 | input_open_device(handle); |
1310 | kbd_refresh_leds(handle); | ||
1311 | 1309 | ||
1312 | return handle; | 1310 | return handle; |
1313 | } | 1311 | } |
@@ -1318,6 +1316,24 @@ static void kbd_disconnect(struct input_handle *handle) | |||
1318 | kfree(handle); | 1316 | kfree(handle); |
1319 | } | 1317 | } |
1320 | 1318 | ||
1319 | /* | ||
1320 | * Start keyboard handler on the new keyboard by refreshing LED state to | ||
1321 | * match the rest of the system. | ||
1322 | */ | ||
1323 | static void kbd_start(struct input_handle *handle) | ||
1324 | { | ||
1325 | unsigned char leds = ledstate; | ||
1326 | |||
1327 | tasklet_disable(&keyboard_tasklet); | ||
1328 | if (leds != 0xff) { | ||
1329 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1330 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1331 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1332 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1333 | } | ||
1334 | tasklet_enable(&keyboard_tasklet); | ||
1335 | } | ||
1336 | |||
1321 | static struct input_device_id kbd_ids[] = { | 1337 | static struct input_device_id kbd_ids[] = { |
1322 | { | 1338 | { |
1323 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1339 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
@@ -1338,6 +1354,7 @@ static struct input_handler kbd_handler = { | |||
1338 | .event = kbd_event, | 1354 | .event = kbd_event, |
1339 | .connect = kbd_connect, | 1355 | .connect = kbd_connect, |
1340 | .disconnect = kbd_disconnect, | 1356 | .disconnect = kbd_disconnect, |
1357 | .start = kbd_start, | ||
1341 | .name = "kbd", | 1358 | .name = "kbd", |
1342 | .id_table = kbd_ids, | 1359 | .id_table = kbd_ids, |
1343 | }; | 1360 | }; |
@@ -1346,15 +1363,15 @@ int __init kbd_init(void) | |||
1346 | { | 1363 | { |
1347 | int i; | 1364 | int i; |
1348 | 1365 | ||
1349 | kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; | 1366 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
1350 | kbd0.ledmode = LED_SHOW_FLAGS; | 1367 | kbd_table[i].ledflagstate = KBD_DEFLEDS; |
1351 | kbd0.lockstate = KBD_DEFLOCK; | 1368 | kbd_table[i].default_ledflagstate = KBD_DEFLEDS; |
1352 | kbd0.slockstate = 0; | 1369 | kbd_table[i].ledmode = LED_SHOW_FLAGS; |
1353 | kbd0.modeflags = KBD_DEFMODE; | 1370 | kbd_table[i].lockstate = KBD_DEFLOCK; |
1354 | kbd0.kbdmode = VC_XLATE; | 1371 | kbd_table[i].slockstate = 0; |
1355 | 1372 | kbd_table[i].modeflags = KBD_DEFMODE; | |
1356 | for (i = 0 ; i < MAX_NR_CONSOLES ; i++) | 1373 | kbd_table[i].kbdmode = VC_XLATE; |
1357 | kbd_table[i] = kbd0; | 1374 | } |
1358 | 1375 | ||
1359 | input_register_handler(&kbd_handler); | 1376 | input_register_handler(&kbd_handler); |
1360 | 1377 | ||
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 645eb81cb5a9..84e5a68635f1 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -221,7 +221,6 @@ static struct nsc_gpio_ops pc8736x_gpio_ops = { | |||
221 | .gpio_change = pc8736x_gpio_change, | 221 | .gpio_change = pc8736x_gpio_change, |
222 | .gpio_current = pc8736x_gpio_current | 222 | .gpio_current = pc8736x_gpio_current |
223 | }; | 223 | }; |
224 | EXPORT_SYMBOL(pc8736x_gpio_ops); | ||
225 | 224 | ||
226 | static int pc8736x_gpio_open(struct inode *inode, struct file *file) | 225 | static int pc8736x_gpio_open(struct inode *inode, struct file *file) |
227 | { | 226 | { |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 17bc8abd5df5..00f574cbb0d4 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1174,8 +1174,12 @@ static void dcd_change(MGSLPC_INFO *info) | |||
1174 | else | 1174 | else |
1175 | info->input_signal_events.dcd_down++; | 1175 | info->input_signal_events.dcd_down++; |
1176 | #ifdef CONFIG_HDLC | 1176 | #ifdef CONFIG_HDLC |
1177 | if (info->netcount) | 1177 | if (info->netcount) { |
1178 | hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, info->netdev); | 1178 | if (info->serial_signals & SerialSignal_DCD) |
1179 | netif_carrier_on(info->netdev); | ||
1180 | else | ||
1181 | netif_carrier_off(info->netdev); | ||
1182 | } | ||
1179 | #endif | 1183 | #endif |
1180 | wake_up_interruptible(&info->status_event_wait_q); | 1184 | wake_up_interruptible(&info->status_event_wait_q); |
1181 | wake_up_interruptible(&info->event_wait_q); | 1185 | wake_up_interruptible(&info->event_wait_q); |
@@ -4251,8 +4255,10 @@ static int hdlcdev_open(struct net_device *dev) | |||
4251 | spin_lock_irqsave(&info->lock, flags); | 4255 | spin_lock_irqsave(&info->lock, flags); |
4252 | get_signals(info); | 4256 | get_signals(info); |
4253 | spin_unlock_irqrestore(&info->lock, flags); | 4257 | spin_unlock_irqrestore(&info->lock, flags); |
4254 | hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); | 4258 | if (info->serial_signals & SerialSignal_DCD) |
4255 | 4259 | netif_carrier_on(dev); | |
4260 | else | ||
4261 | netif_carrier_off(dev); | ||
4256 | return 0; | 4262 | return 0; |
4257 | } | 4263 | } |
4258 | 4264 | ||
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index afc6eda602f7..07e0b75f2338 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -374,7 +374,12 @@ scdrv_init(void) | |||
374 | struct sysctl_data_s *scd; | 374 | struct sysctl_data_s *scd; |
375 | void *salbuf; | 375 | void *salbuf; |
376 | dev_t first_dev, dev; | 376 | dev_t first_dev, dev; |
377 | nasid_t event_nasid = ia64_sn_get_console_nasid(); | 377 | nasid_t event_nasid; |
378 | |||
379 | if (!ia64_platform_is("sn2")) | ||
380 | return -ENODEV; | ||
381 | |||
382 | event_nasid = ia64_sn_get_console_nasid(); | ||
378 | 383 | ||
379 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, | 384 | if (alloc_chrdev_region(&first_dev, 0, num_cnodes, |
380 | SYSCTL_BASENAME) < 0) { | 385 | SYSCTL_BASENAME) < 0) { |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index df782dd1098c..78b1b1a2732b 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -1344,8 +1344,12 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
1344 | } else | 1344 | } else |
1345 | info->input_signal_events.dcd_down++; | 1345 | info->input_signal_events.dcd_down++; |
1346 | #ifdef CONFIG_HDLC | 1346 | #ifdef CONFIG_HDLC |
1347 | if (info->netcount) | 1347 | if (info->netcount) { |
1348 | hdlc_set_carrier(status & MISCSTATUS_DCD, info->netdev); | 1348 | if (status & MISCSTATUS_DCD) |
1349 | netif_carrier_on(info->netdev); | ||
1350 | else | ||
1351 | netif_carrier_off(info->netdev); | ||
1352 | } | ||
1349 | #endif | 1353 | #endif |
1350 | } | 1354 | } |
1351 | if (status & MISCSTATUS_CTS_LATCHED) | 1355 | if (status & MISCSTATUS_CTS_LATCHED) |
@@ -7844,8 +7848,10 @@ static int hdlcdev_open(struct net_device *dev) | |||
7844 | spin_lock_irqsave(&info->irq_spinlock, flags); | 7848 | spin_lock_irqsave(&info->irq_spinlock, flags); |
7845 | usc_get_serial_signals(info); | 7849 | usc_get_serial_signals(info); |
7846 | spin_unlock_irqrestore(&info->irq_spinlock, flags); | 7850 | spin_unlock_irqrestore(&info->irq_spinlock, flags); |
7847 | hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); | 7851 | if (info->serial_signals & SerialSignal_DCD) |
7848 | 7852 | netif_carrier_on(dev); | |
7853 | else | ||
7854 | netif_carrier_off(dev); | ||
7849 | return 0; | 7855 | return 0; |
7850 | } | 7856 | } |
7851 | 7857 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index e829594195c1..b2dbbdb1bf81 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -1497,8 +1497,10 @@ static int hdlcdev_open(struct net_device *dev) | |||
1497 | spin_lock_irqsave(&info->lock, flags); | 1497 | spin_lock_irqsave(&info->lock, flags); |
1498 | get_signals(info); | 1498 | get_signals(info); |
1499 | spin_unlock_irqrestore(&info->lock, flags); | 1499 | spin_unlock_irqrestore(&info->lock, flags); |
1500 | hdlc_set_carrier(info->signals & SerialSignal_DCD, dev); | 1500 | if (info->signals & SerialSignal_DCD) |
1501 | 1501 | netif_carrier_on(dev); | |
1502 | else | ||
1503 | netif_carrier_off(dev); | ||
1502 | return 0; | 1504 | return 0; |
1503 | } | 1505 | } |
1504 | 1506 | ||
@@ -1997,8 +1999,12 @@ static void dcd_change(struct slgt_info *info) | |||
1997 | info->input_signal_events.dcd_down++; | 1999 | info->input_signal_events.dcd_down++; |
1998 | } | 2000 | } |
1999 | #ifdef CONFIG_HDLC | 2001 | #ifdef CONFIG_HDLC |
2000 | if (info->netcount) | 2002 | if (info->netcount) { |
2001 | hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev); | 2003 | if (info->signals & SerialSignal_DCD) |
2004 | netif_carrier_on(info->netdev); | ||
2005 | else | ||
2006 | netif_carrier_off(info->netdev); | ||
2007 | } | ||
2002 | #endif | 2008 | #endif |
2003 | wake_up_interruptible(&info->status_event_wait_q); | 2009 | wake_up_interruptible(&info->status_event_wait_q); |
2004 | wake_up_interruptible(&info->event_wait_q); | 2010 | wake_up_interruptible(&info->event_wait_q); |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 1e443a233f51..66f3754fbbdf 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -1752,8 +1752,10 @@ static int hdlcdev_open(struct net_device *dev) | |||
1752 | spin_lock_irqsave(&info->lock, flags); | 1752 | spin_lock_irqsave(&info->lock, flags); |
1753 | get_signals(info); | 1753 | get_signals(info); |
1754 | spin_unlock_irqrestore(&info->lock, flags); | 1754 | spin_unlock_irqrestore(&info->lock, flags); |
1755 | hdlc_set_carrier(info->serial_signals & SerialSignal_DCD, dev); | 1755 | if (info->serial_signals & SerialSignal_DCD) |
1756 | 1756 | netif_carrier_on(dev); | |
1757 | else | ||
1758 | netif_carrier_off(dev); | ||
1757 | return 0; | 1759 | return 0; |
1758 | } | 1760 | } |
1759 | 1761 | ||
@@ -2522,8 +2524,12 @@ void isr_io_pin( SLMP_INFO *info, u16 status ) | |||
2522 | } else | 2524 | } else |
2523 | info->input_signal_events.dcd_down++; | 2525 | info->input_signal_events.dcd_down++; |
2524 | #ifdef CONFIG_HDLC | 2526 | #ifdef CONFIG_HDLC |
2525 | if (info->netcount) | 2527 | if (info->netcount) { |
2526 | hdlc_set_carrier(status & SerialSignal_DCD, info->netdev); | 2528 | if (status & SerialSignal_DCD) |
2529 | netif_carrier_on(info->netdev); | ||
2530 | else | ||
2531 | netif_carrier_off(info->netdev); | ||
2532 | } | ||
2527 | #endif | 2533 | #endif |
2528 | } | 2534 | } |
2529 | if (status & MISCSTATUS_CTS_LATCHED) | 2535 | if (status & MISCSTATUS_CTS_LATCHED) |
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 498aa37bca22..3ece69231343 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c | |||
@@ -51,6 +51,7 @@ void proc_fork_connector(struct task_struct *task) | |||
51 | struct cn_msg *msg; | 51 | struct cn_msg *msg; |
52 | struct proc_event *ev; | 52 | struct proc_event *ev; |
53 | __u8 buffer[CN_PROC_MSG_SIZE]; | 53 | __u8 buffer[CN_PROC_MSG_SIZE]; |
54 | struct timespec ts; | ||
54 | 55 | ||
55 | if (atomic_read(&proc_event_num_listeners) < 1) | 56 | if (atomic_read(&proc_event_num_listeners) < 1) |
56 | return; | 57 | return; |
@@ -58,7 +59,8 @@ void proc_fork_connector(struct task_struct *task) | |||
58 | msg = (struct cn_msg*)buffer; | 59 | msg = (struct cn_msg*)buffer; |
59 | ev = (struct proc_event*)msg->data; | 60 | ev = (struct proc_event*)msg->data; |
60 | get_seq(&msg->seq, &ev->cpu); | 61 | get_seq(&msg->seq, &ev->cpu); |
61 | ktime_get_ts(&ev->timestamp); /* get high res monotonic timestamp */ | 62 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
63 | ev->timestamp_ns = timespec_to_ns(&ts); | ||
62 | ev->what = PROC_EVENT_FORK; | 64 | ev->what = PROC_EVENT_FORK; |
63 | ev->event_data.fork.parent_pid = task->real_parent->pid; | 65 | ev->event_data.fork.parent_pid = task->real_parent->pid; |
64 | ev->event_data.fork.parent_tgid = task->real_parent->tgid; | 66 | ev->event_data.fork.parent_tgid = task->real_parent->tgid; |
@@ -76,6 +78,7 @@ void proc_exec_connector(struct task_struct *task) | |||
76 | { | 78 | { |
77 | struct cn_msg *msg; | 79 | struct cn_msg *msg; |
78 | struct proc_event *ev; | 80 | struct proc_event *ev; |
81 | struct timespec ts; | ||
79 | __u8 buffer[CN_PROC_MSG_SIZE]; | 82 | __u8 buffer[CN_PROC_MSG_SIZE]; |
80 | 83 | ||
81 | if (atomic_read(&proc_event_num_listeners) < 1) | 84 | if (atomic_read(&proc_event_num_listeners) < 1) |
@@ -84,7 +87,8 @@ void proc_exec_connector(struct task_struct *task) | |||
84 | msg = (struct cn_msg*)buffer; | 87 | msg = (struct cn_msg*)buffer; |
85 | ev = (struct proc_event*)msg->data; | 88 | ev = (struct proc_event*)msg->data; |
86 | get_seq(&msg->seq, &ev->cpu); | 89 | get_seq(&msg->seq, &ev->cpu); |
87 | ktime_get_ts(&ev->timestamp); | 90 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
91 | ev->timestamp_ns = timespec_to_ns(&ts); | ||
88 | ev->what = PROC_EVENT_EXEC; | 92 | ev->what = PROC_EVENT_EXEC; |
89 | ev->event_data.exec.process_pid = task->pid; | 93 | ev->event_data.exec.process_pid = task->pid; |
90 | ev->event_data.exec.process_tgid = task->tgid; | 94 | ev->event_data.exec.process_tgid = task->tgid; |
@@ -100,6 +104,7 @@ void proc_id_connector(struct task_struct *task, int which_id) | |||
100 | struct cn_msg *msg; | 104 | struct cn_msg *msg; |
101 | struct proc_event *ev; | 105 | struct proc_event *ev; |
102 | __u8 buffer[CN_PROC_MSG_SIZE]; | 106 | __u8 buffer[CN_PROC_MSG_SIZE]; |
107 | struct timespec ts; | ||
103 | 108 | ||
104 | if (atomic_read(&proc_event_num_listeners) < 1) | 109 | if (atomic_read(&proc_event_num_listeners) < 1) |
105 | return; | 110 | return; |
@@ -118,7 +123,8 @@ void proc_id_connector(struct task_struct *task, int which_id) | |||
118 | } else | 123 | } else |
119 | return; | 124 | return; |
120 | get_seq(&msg->seq, &ev->cpu); | 125 | get_seq(&msg->seq, &ev->cpu); |
121 | ktime_get_ts(&ev->timestamp); | 126 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
127 | ev->timestamp_ns = timespec_to_ns(&ts); | ||
122 | 128 | ||
123 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); | 129 | memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); |
124 | msg->ack = 0; /* not used */ | 130 | msg->ack = 0; /* not used */ |
@@ -131,6 +137,7 @@ void proc_exit_connector(struct task_struct *task) | |||
131 | struct cn_msg *msg; | 137 | struct cn_msg *msg; |
132 | struct proc_event *ev; | 138 | struct proc_event *ev; |
133 | __u8 buffer[CN_PROC_MSG_SIZE]; | 139 | __u8 buffer[CN_PROC_MSG_SIZE]; |
140 | struct timespec ts; | ||
134 | 141 | ||
135 | if (atomic_read(&proc_event_num_listeners) < 1) | 142 | if (atomic_read(&proc_event_num_listeners) < 1) |
136 | return; | 143 | return; |
@@ -138,7 +145,8 @@ void proc_exit_connector(struct task_struct *task) | |||
138 | msg = (struct cn_msg*)buffer; | 145 | msg = (struct cn_msg*)buffer; |
139 | ev = (struct proc_event*)msg->data; | 146 | ev = (struct proc_event*)msg->data; |
140 | get_seq(&msg->seq, &ev->cpu); | 147 | get_seq(&msg->seq, &ev->cpu); |
141 | ktime_get_ts(&ev->timestamp); | 148 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
149 | ev->timestamp_ns = timespec_to_ns(&ts); | ||
142 | ev->what = PROC_EVENT_EXIT; | 150 | ev->what = PROC_EVENT_EXIT; |
143 | ev->event_data.exit.process_pid = task->pid; | 151 | ev->event_data.exit.process_pid = task->pid; |
144 | ev->event_data.exit.process_tgid = task->tgid; | 152 | ev->event_data.exit.process_tgid = task->tgid; |
@@ -164,6 +172,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) | |||
164 | struct cn_msg *msg; | 172 | struct cn_msg *msg; |
165 | struct proc_event *ev; | 173 | struct proc_event *ev; |
166 | __u8 buffer[CN_PROC_MSG_SIZE]; | 174 | __u8 buffer[CN_PROC_MSG_SIZE]; |
175 | struct timespec ts; | ||
167 | 176 | ||
168 | if (atomic_read(&proc_event_num_listeners) < 1) | 177 | if (atomic_read(&proc_event_num_listeners) < 1) |
169 | return; | 178 | return; |
@@ -171,7 +180,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) | |||
171 | msg = (struct cn_msg*)buffer; | 180 | msg = (struct cn_msg*)buffer; |
172 | ev = (struct proc_event*)msg->data; | 181 | ev = (struct proc_event*)msg->data; |
173 | msg->seq = rcvd_seq; | 182 | msg->seq = rcvd_seq; |
174 | ktime_get_ts(&ev->timestamp); | 183 | ktime_get_ts(&ts); /* get high res monotonic timestamp */ |
184 | ev->timestamp_ns = timespec_to_ns(&ts); | ||
175 | ev->cpu = -1; | 185 | ev->cpu = -1; |
176 | ev->what = PROC_EVENT_NONE; | 186 | ev->what = PROC_EVENT_NONE; |
177 | ev->event_data.ack.err = err; | 187 | ev->event_data.ack.err = err; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8d328186f774..b3df613ae4ec 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -284,39 +284,69 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_transition); | |||
284 | * SYSFS INTERFACE * | 284 | * SYSFS INTERFACE * |
285 | *********************************************************************/ | 285 | *********************************************************************/ |
286 | 286 | ||
287 | static struct cpufreq_governor *__find_governor(const char *str_governor) | ||
288 | { | ||
289 | struct cpufreq_governor *t; | ||
290 | |||
291 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) | ||
292 | if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) | ||
293 | return t; | ||
294 | |||
295 | return NULL; | ||
296 | } | ||
297 | |||
287 | /** | 298 | /** |
288 | * cpufreq_parse_governor - parse a governor string | 299 | * cpufreq_parse_governor - parse a governor string |
289 | */ | 300 | */ |
290 | static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, | 301 | static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, |
291 | struct cpufreq_governor **governor) | 302 | struct cpufreq_governor **governor) |
292 | { | 303 | { |
304 | int err = -EINVAL; | ||
305 | |||
293 | if (!cpufreq_driver) | 306 | if (!cpufreq_driver) |
294 | return -EINVAL; | 307 | goto out; |
308 | |||
295 | if (cpufreq_driver->setpolicy) { | 309 | if (cpufreq_driver->setpolicy) { |
296 | if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { | 310 | if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { |
297 | *policy = CPUFREQ_POLICY_PERFORMANCE; | 311 | *policy = CPUFREQ_POLICY_PERFORMANCE; |
298 | return 0; | 312 | err = 0; |
299 | } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { | 313 | } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { |
300 | *policy = CPUFREQ_POLICY_POWERSAVE; | 314 | *policy = CPUFREQ_POLICY_POWERSAVE; |
301 | return 0; | 315 | err = 0; |
302 | } | 316 | } |
303 | return -EINVAL; | 317 | } else if (cpufreq_driver->target) { |
304 | } else { | ||
305 | struct cpufreq_governor *t; | 318 | struct cpufreq_governor *t; |
319 | |||
306 | mutex_lock(&cpufreq_governor_mutex); | 320 | mutex_lock(&cpufreq_governor_mutex); |
307 | if (!cpufreq_driver || !cpufreq_driver->target) | 321 | |
308 | goto out; | 322 | t = __find_governor(str_governor); |
309 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) { | 323 | |
310 | if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) { | 324 | if (t == NULL) { |
311 | *governor = t; | 325 | char *name = kasprintf(GFP_KERNEL, "cpufreq_%s", str_governor); |
326 | |||
327 | if (name) { | ||
328 | int ret; | ||
329 | |||
312 | mutex_unlock(&cpufreq_governor_mutex); | 330 | mutex_unlock(&cpufreq_governor_mutex); |
313 | return 0; | 331 | ret = request_module(name); |
332 | mutex_lock(&cpufreq_governor_mutex); | ||
333 | |||
334 | if (ret == 0) | ||
335 | t = __find_governor(str_governor); | ||
314 | } | 336 | } |
337 | |||
338 | kfree(name); | ||
315 | } | 339 | } |
316 | out: | 340 | |
341 | if (t != NULL) { | ||
342 | *governor = t; | ||
343 | err = 0; | ||
344 | } | ||
345 | |||
317 | mutex_unlock(&cpufreq_governor_mutex); | 346 | mutex_unlock(&cpufreq_governor_mutex); |
318 | } | 347 | } |
319 | return -EINVAL; | 348 | out: |
349 | return err; | ||
320 | } | 350 | } |
321 | 351 | ||
322 | 352 | ||
@@ -364,10 +394,12 @@ static ssize_t store_##file_name \ | |||
364 | if (ret != 1) \ | 394 | if (ret != 1) \ |
365 | return -EINVAL; \ | 395 | return -EINVAL; \ |
366 | \ | 396 | \ |
397 | lock_cpu_hotplug(); \ | ||
367 | mutex_lock(&policy->lock); \ | 398 | mutex_lock(&policy->lock); \ |
368 | ret = __cpufreq_set_policy(policy, &new_policy); \ | 399 | ret = __cpufreq_set_policy(policy, &new_policy); \ |
369 | policy->user_policy.object = policy->object; \ | 400 | policy->user_policy.object = policy->object; \ |
370 | mutex_unlock(&policy->lock); \ | 401 | mutex_unlock(&policy->lock); \ |
402 | unlock_cpu_hotplug(); \ | ||
371 | \ | 403 | \ |
372 | return ret ? ret : count; \ | 404 | return ret ? ret : count; \ |
373 | } | 405 | } |
@@ -1197,20 +1229,18 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); | |||
1197 | *********************************************************************/ | 1229 | *********************************************************************/ |
1198 | 1230 | ||
1199 | 1231 | ||
1232 | /* Must be called with lock_cpu_hotplug held */ | ||
1200 | int __cpufreq_driver_target(struct cpufreq_policy *policy, | 1233 | int __cpufreq_driver_target(struct cpufreq_policy *policy, |
1201 | unsigned int target_freq, | 1234 | unsigned int target_freq, |
1202 | unsigned int relation) | 1235 | unsigned int relation) |
1203 | { | 1236 | { |
1204 | int retval = -EINVAL; | 1237 | int retval = -EINVAL; |
1205 | 1238 | ||
1206 | lock_cpu_hotplug(); | ||
1207 | dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, | 1239 | dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, |
1208 | target_freq, relation); | 1240 | target_freq, relation); |
1209 | if (cpu_online(policy->cpu) && cpufreq_driver->target) | 1241 | if (cpu_online(policy->cpu) && cpufreq_driver->target) |
1210 | retval = cpufreq_driver->target(policy, target_freq, relation); | 1242 | retval = cpufreq_driver->target(policy, target_freq, relation); |
1211 | 1243 | ||
1212 | unlock_cpu_hotplug(); | ||
1213 | |||
1214 | return retval; | 1244 | return retval; |
1215 | } | 1245 | } |
1216 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); | 1246 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); |
@@ -1225,17 +1255,23 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1225 | if (!policy) | 1255 | if (!policy) |
1226 | return -EINVAL; | 1256 | return -EINVAL; |
1227 | 1257 | ||
1258 | lock_cpu_hotplug(); | ||
1228 | mutex_lock(&policy->lock); | 1259 | mutex_lock(&policy->lock); |
1229 | 1260 | ||
1230 | ret = __cpufreq_driver_target(policy, target_freq, relation); | 1261 | ret = __cpufreq_driver_target(policy, target_freq, relation); |
1231 | 1262 | ||
1232 | mutex_unlock(&policy->lock); | 1263 | mutex_unlock(&policy->lock); |
1264 | unlock_cpu_hotplug(); | ||
1233 | 1265 | ||
1234 | cpufreq_cpu_put(policy); | 1266 | cpufreq_cpu_put(policy); |
1235 | return ret; | 1267 | return ret; |
1236 | } | 1268 | } |
1237 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1269 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
1238 | 1270 | ||
1271 | /* | ||
1272 | * Locking: Must be called with the lock_cpu_hotplug() lock held | ||
1273 | * when "event" is CPUFREQ_GOV_LIMITS | ||
1274 | */ | ||
1239 | 1275 | ||
1240 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) | 1276 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) |
1241 | { | 1277 | { |
@@ -1257,43 +1293,23 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) | |||
1257 | } | 1293 | } |
1258 | 1294 | ||
1259 | 1295 | ||
1260 | int cpufreq_governor(unsigned int cpu, unsigned int event) | ||
1261 | { | ||
1262 | int ret = 0; | ||
1263 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | ||
1264 | |||
1265 | if (!policy) | ||
1266 | return -EINVAL; | ||
1267 | |||
1268 | mutex_lock(&policy->lock); | ||
1269 | ret = __cpufreq_governor(policy, event); | ||
1270 | mutex_unlock(&policy->lock); | ||
1271 | |||
1272 | cpufreq_cpu_put(policy); | ||
1273 | return ret; | ||
1274 | } | ||
1275 | EXPORT_SYMBOL_GPL(cpufreq_governor); | ||
1276 | |||
1277 | |||
1278 | int cpufreq_register_governor(struct cpufreq_governor *governor) | 1296 | int cpufreq_register_governor(struct cpufreq_governor *governor) |
1279 | { | 1297 | { |
1280 | struct cpufreq_governor *t; | 1298 | int err; |
1281 | 1299 | ||
1282 | if (!governor) | 1300 | if (!governor) |
1283 | return -EINVAL; | 1301 | return -EINVAL; |
1284 | 1302 | ||
1285 | mutex_lock(&cpufreq_governor_mutex); | 1303 | mutex_lock(&cpufreq_governor_mutex); |
1286 | 1304 | ||
1287 | list_for_each_entry(t, &cpufreq_governor_list, governor_list) { | 1305 | err = -EBUSY; |
1288 | if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) { | 1306 | if (__find_governor(governor->name) == NULL) { |
1289 | mutex_unlock(&cpufreq_governor_mutex); | 1307 | err = 0; |
1290 | return -EBUSY; | 1308 | list_add(&governor->governor_list, &cpufreq_governor_list); |
1291 | } | ||
1292 | } | 1309 | } |
1293 | list_add(&governor->governor_list, &cpufreq_governor_list); | ||
1294 | 1310 | ||
1295 | mutex_unlock(&cpufreq_governor_mutex); | 1311 | mutex_unlock(&cpufreq_governor_mutex); |
1296 | return 0; | 1312 | return err; |
1297 | } | 1313 | } |
1298 | EXPORT_SYMBOL_GPL(cpufreq_register_governor); | 1314 | EXPORT_SYMBOL_GPL(cpufreq_register_governor); |
1299 | 1315 | ||
@@ -1342,6 +1358,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) | |||
1342 | EXPORT_SYMBOL(cpufreq_get_policy); | 1358 | EXPORT_SYMBOL(cpufreq_get_policy); |
1343 | 1359 | ||
1344 | 1360 | ||
1361 | /* | ||
1362 | * Locking: Must be called with the lock_cpu_hotplug() lock held | ||
1363 | */ | ||
1345 | static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy) | 1364 | static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy) |
1346 | { | 1365 | { |
1347 | int ret = 0; | 1366 | int ret = 0; |
@@ -1352,6 +1371,11 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli | |||
1352 | 1371 | ||
1353 | memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); | 1372 | memcpy(&policy->cpuinfo, &data->cpuinfo, sizeof(struct cpufreq_cpuinfo)); |
1354 | 1373 | ||
1374 | if (policy->min > data->min && policy->min > policy->max) { | ||
1375 | ret = -EINVAL; | ||
1376 | goto error_out; | ||
1377 | } | ||
1378 | |||
1355 | /* verify the cpu speed can be set within this limit */ | 1379 | /* verify the cpu speed can be set within this limit */ |
1356 | ret = cpufreq_driver->verify(policy); | 1380 | ret = cpufreq_driver->verify(policy); |
1357 | if (ret) | 1381 | if (ret) |
@@ -1436,6 +1460,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) | |||
1436 | if (!data) | 1460 | if (!data) |
1437 | return -EINVAL; | 1461 | return -EINVAL; |
1438 | 1462 | ||
1463 | lock_cpu_hotplug(); | ||
1464 | |||
1439 | /* lock this CPU */ | 1465 | /* lock this CPU */ |
1440 | mutex_lock(&data->lock); | 1466 | mutex_lock(&data->lock); |
1441 | 1467 | ||
@@ -1446,6 +1472,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) | |||
1446 | data->user_policy.governor = data->governor; | 1472 | data->user_policy.governor = data->governor; |
1447 | 1473 | ||
1448 | mutex_unlock(&data->lock); | 1474 | mutex_unlock(&data->lock); |
1475 | |||
1476 | unlock_cpu_hotplug(); | ||
1449 | cpufreq_cpu_put(data); | 1477 | cpufreq_cpu_put(data); |
1450 | 1478 | ||
1451 | return ret; | 1479 | return ret; |
@@ -1469,6 +1497,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1469 | if (!data) | 1497 | if (!data) |
1470 | return -ENODEV; | 1498 | return -ENODEV; |
1471 | 1499 | ||
1500 | lock_cpu_hotplug(); | ||
1472 | mutex_lock(&data->lock); | 1501 | mutex_lock(&data->lock); |
1473 | 1502 | ||
1474 | dprintk("updating policy for CPU %u\n", cpu); | 1503 | dprintk("updating policy for CPU %u\n", cpu); |
@@ -1494,7 +1523,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1494 | ret = __cpufreq_set_policy(data, &policy); | 1523 | ret = __cpufreq_set_policy(data, &policy); |
1495 | 1524 | ||
1496 | mutex_unlock(&data->lock); | 1525 | mutex_unlock(&data->lock); |
1497 | 1526 | unlock_cpu_hotplug(); | |
1498 | cpufreq_cpu_put(data); | 1527 | cpufreq_cpu_put(data); |
1499 | return ret; | 1528 | return ret; |
1500 | } | 1529 | } |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index b3ebc8f01975..c4c578defabf 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -525,7 +525,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
525 | break; | 525 | break; |
526 | 526 | ||
527 | case CPUFREQ_GOV_LIMITS: | 527 | case CPUFREQ_GOV_LIMITS: |
528 | lock_cpu_hotplug(); | ||
529 | mutex_lock(&dbs_mutex); | 528 | mutex_lock(&dbs_mutex); |
530 | if (policy->max < this_dbs_info->cur_policy->cur) | 529 | if (policy->max < this_dbs_info->cur_policy->cur) |
531 | __cpufreq_driver_target( | 530 | __cpufreq_driver_target( |
@@ -536,7 +535,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
536 | this_dbs_info->cur_policy, | 535 | this_dbs_info->cur_policy, |
537 | policy->min, CPUFREQ_RELATION_L); | 536 | policy->min, CPUFREQ_RELATION_L); |
538 | mutex_unlock(&dbs_mutex); | 537 | mutex_unlock(&dbs_mutex); |
539 | unlock_cpu_hotplug(); | ||
540 | break; | 538 | break; |
541 | } | 539 | } |
542 | return 0; | 540 | return 0; |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 87299924e735..52cf1f021825 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -239,6 +239,8 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
239 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, | 239 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, |
240 | this_dbs_info->prev_cpu_wall); | 240 | this_dbs_info->prev_cpu_wall); |
241 | this_dbs_info->prev_cpu_wall = cur_jiffies; | 241 | this_dbs_info->prev_cpu_wall = cur_jiffies; |
242 | if (!total_ticks) | ||
243 | return; | ||
242 | /* | 244 | /* |
243 | * Every sampling_rate, we check, if current idle time is less | 245 | * Every sampling_rate, we check, if current idle time is less |
244 | * than 20% (default), then we try to increase frequency | 246 | * than 20% (default), then we try to increase frequency |
@@ -304,7 +306,12 @@ static void do_dbs_timer(void *data) | |||
304 | unsigned int cpu = smp_processor_id(); | 306 | unsigned int cpu = smp_processor_id(); |
305 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 307 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); |
306 | 308 | ||
309 | if (!dbs_info->enable) | ||
310 | return; | ||
311 | |||
312 | lock_cpu_hotplug(); | ||
307 | dbs_check_cpu(dbs_info); | 313 | dbs_check_cpu(dbs_info); |
314 | unlock_cpu_hotplug(); | ||
308 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, | 315 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, |
309 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 316 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
310 | } | 317 | } |
@@ -319,11 +326,11 @@ static inline void dbs_timer_init(unsigned int cpu) | |||
319 | return; | 326 | return; |
320 | } | 327 | } |
321 | 328 | ||
322 | static inline void dbs_timer_exit(unsigned int cpu) | 329 | static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) |
323 | { | 330 | { |
324 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 331 | dbs_info->enable = 0; |
325 | 332 | cancel_delayed_work(&dbs_info->work); | |
326 | cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); | 333 | flush_workqueue(kondemand_wq); |
327 | } | 334 | } |
328 | 335 | ||
329 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | 336 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, |
@@ -396,8 +403,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
396 | 403 | ||
397 | case CPUFREQ_GOV_STOP: | 404 | case CPUFREQ_GOV_STOP: |
398 | mutex_lock(&dbs_mutex); | 405 | mutex_lock(&dbs_mutex); |
399 | dbs_timer_exit(policy->cpu); | 406 | dbs_timer_exit(this_dbs_info); |
400 | this_dbs_info->enable = 0; | ||
401 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 407 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); |
402 | dbs_enable--; | 408 | dbs_enable--; |
403 | if (dbs_enable == 0) | 409 | if (dbs_enable == 0) |
@@ -408,7 +414,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
408 | break; | 414 | break; |
409 | 415 | ||
410 | case CPUFREQ_GOV_LIMITS: | 416 | case CPUFREQ_GOV_LIMITS: |
411 | lock_cpu_hotplug(); | ||
412 | mutex_lock(&dbs_mutex); | 417 | mutex_lock(&dbs_mutex); |
413 | if (policy->max < this_dbs_info->cur_policy->cur) | 418 | if (policy->max < this_dbs_info->cur_policy->cur) |
414 | __cpufreq_driver_target(this_dbs_info->cur_policy, | 419 | __cpufreq_driver_target(this_dbs_info->cur_policy, |
@@ -419,7 +424,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
419 | policy->min, | 424 | policy->min, |
420 | CPUFREQ_RELATION_L); | 425 | CPUFREQ_RELATION_L); |
421 | mutex_unlock(&dbs_mutex); | 426 | mutex_unlock(&dbs_mutex); |
422 | unlock_cpu_hotplug(); | ||
423 | break; | 427 | break; |
424 | } | 428 | } |
425 | return 0; | 429 | return 0; |
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 44ae5e5b94cf..a06c204589cd 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/cpufreq.h> | 20 | #include <linux/cpufreq.h> |
21 | #include <linux/cpu.h> | ||
21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
22 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
23 | #include <linux/sysfs.h> | 24 | #include <linux/sysfs.h> |
@@ -70,6 +71,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) | |||
70 | 71 | ||
71 | dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); | 72 | dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); |
72 | 73 | ||
74 | lock_cpu_hotplug(); | ||
73 | mutex_lock(&userspace_mutex); | 75 | mutex_lock(&userspace_mutex); |
74 | if (!cpu_is_managed[policy->cpu]) | 76 | if (!cpu_is_managed[policy->cpu]) |
75 | goto err; | 77 | goto err; |
@@ -92,6 +94,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) | |||
92 | 94 | ||
93 | err: | 95 | err: |
94 | mutex_unlock(&userspace_mutex); | 96 | mutex_unlock(&userspace_mutex); |
97 | unlock_cpu_hotplug(); | ||
95 | return ret; | 98 | return ret; |
96 | } | 99 | } |
97 | 100 | ||
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 78bf46d917b7..dbd4d6c3698e 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c | |||
@@ -828,7 +828,7 @@ static int __init ioat_init_module(void) | |||
828 | /* if forced, worst case is that rmmod hangs */ | 828 | /* if forced, worst case is that rmmod hangs */ |
829 | __unsafe(THIS_MODULE); | 829 | __unsafe(THIS_MODULE); |
830 | 830 | ||
831 | return pci_module_init(&ioat_pci_drv); | 831 | return pci_register_driver(&ioat_pci_drv); |
832 | } | 832 | } |
833 | 833 | ||
834 | module_init(ioat_init_module); | 834 | module_init(ioat_init_module); |
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index bf6ab8a8d5ed..a1cfd4e3c97d 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/rcupdate.h> | 29 | #include <linux/rcupdate.h> |
30 | #include <linux/completion.h> | 30 | #include <linux/completion.h> |
31 | #include <linux/kobject.h> | 31 | #include <linux/kobject.h> |
32 | #include <linux/platform_device.h> | ||
32 | 33 | ||
33 | #define EDAC_MC_LABEL_LEN 31 | 34 | #define EDAC_MC_LABEL_LEN 31 |
34 | #define MC_PROC_NAME_MAX_LEN 7 | 35 | #define MC_PROC_NAME_MAX_LEN 7 |
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 66d03f242d3c..1a159e8843ca 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c | |||
@@ -429,7 +429,7 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd | |||
429 | 429 | ||
430 | if (fcmd->data) { | 430 | if (fcmd->data) { |
431 | if (SCpnt->use_sg) | 431 | if (SCpnt->use_sg) |
432 | dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, | 432 | dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->request_buffer, |
433 | SCpnt->use_sg, | 433 | SCpnt->use_sg, |
434 | SCpnt->sc_data_direction); | 434 | SCpnt->sc_data_direction); |
435 | else | 435 | else |
@@ -810,7 +810,7 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i | |||
810 | SCpnt->request_bufflen, | 810 | SCpnt->request_bufflen, |
811 | SCpnt->sc_data_direction); | 811 | SCpnt->sc_data_direction); |
812 | } else { | 812 | } else { |
813 | struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer; | 813 | struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer; |
814 | int nents; | 814 | int nents; |
815 | 815 | ||
816 | FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) | 816 | FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index ced309ff056f..eae9e81be375 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -232,7 +232,7 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) | |||
232 | unsigned long timeout; | 232 | unsigned long timeout; |
233 | 233 | ||
234 | timeout = jiffies + POLL_TIMEOUT; | 234 | timeout = jiffies + POLL_TIMEOUT; |
235 | while (time_before(jiffies, timeout)) { | 235 | while (1) { |
236 | status = inb(ACBST); | 236 | status = inb(ACBST); |
237 | 237 | ||
238 | /* Reset the status register to avoid the hang */ | 238 | /* Reset the status register to avoid the hang */ |
@@ -242,7 +242,10 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) | |||
242 | scx200_acb_machine(iface, status); | 242 | scx200_acb_machine(iface, status); |
243 | return; | 243 | return; |
244 | } | 244 | } |
245 | yield(); | 245 | if (time_after(jiffies, timeout)) |
246 | break; | ||
247 | cpu_relax(); | ||
248 | cond_resched(); | ||
246 | } | 249 | } |
247 | 250 | ||
248 | dev_err(&iface->adapter.dev, "timeout in state %s\n", | 251 | dev_err(&iface->adapter.dev, "timeout in state %s\n", |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index d1266fe2d1ab..b6fb167e20f6 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -682,6 +682,7 @@ config BLK_DEV_SVWKS | |||
682 | config BLK_DEV_SGIIOC4 | 682 | config BLK_DEV_SGIIOC4 |
683 | tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" | 683 | tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" |
684 | depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 | 684 | depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 |
685 | select IDEPCI_SHARE_IRQ | ||
685 | help | 686 | help |
686 | This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 | 687 | This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 |
687 | chipset, which has one channel and can support two devices. | 688 | chipset, which has one channel and can support two devices. |
@@ -773,20 +774,6 @@ config BLK_DEV_IDEDMA_PMAC | |||
773 | to transfer data to and from memory. Saying Y is safe and improves | 774 | to transfer data to and from memory. Saying Y is safe and improves |
774 | performance. | 775 | performance. |
775 | 776 | ||
776 | config BLK_DEV_IDE_PMAC_BLINK | ||
777 | bool "Blink laptop LED on drive activity (DEPRECATED)" | ||
778 | depends on BLK_DEV_IDE_PMAC && ADB_PMU | ||
779 | select ADB_PMU_LED | ||
780 | select LEDS_TRIGGERS | ||
781 | select LEDS_TRIGGER_IDE_DISK | ||
782 | help | ||
783 | This option enables the use of the sleep LED as a hard drive | ||
784 | activity LED. | ||
785 | This option is deprecated, it only selects ADB_PMU_LED and | ||
786 | LEDS_TRIGGER_IDE_DISK and changes the code in the new led class | ||
787 | device to default to the ide-disk trigger (which should be set | ||
788 | from userspace via sysfs). | ||
789 | |||
790 | config BLK_DEV_IDE_SWARM | 777 | config BLK_DEV_IDE_SWARM |
791 | tristate "IDE for Sibyte evaluation boards" | 778 | tristate "IDE for Sibyte evaluation boards" |
792 | depends on SIBYTE_SB1xxx_SOC | 779 | depends on SIBYTE_SB1xxx_SOC |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index f712e4cfd9dc..7cf3eb023521 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -776,7 +776,7 @@ static void update_ordered(ide_drive_t *drive) | |||
776 | * not available so we don't need to recheck that. | 776 | * not available so we don't need to recheck that. |
777 | */ | 777 | */ |
778 | capacity = idedisk_capacity(drive); | 778 | capacity = idedisk_capacity(drive); |
779 | barrier = ide_id_has_flush_cache(id) && | 779 | barrier = ide_id_has_flush_cache(id) && !drive->noflush && |
780 | (drive->addressing == 0 || capacity <= (1ULL << 28) || | 780 | (drive->addressing == 0 || capacity <= (1ULL << 28) || |
781 | ide_id_has_flush_cache_ext(id)); | 781 | ide_id_has_flush_cache_ext(id)); |
782 | 782 | ||
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 98918fb6b2ce..7c3a13e1cf64 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -750,7 +750,7 @@ void ide_dma_verbose(ide_drive_t *drive) | |||
750 | goto bug_dma_off; | 750 | goto bug_dma_off; |
751 | printk(", DMA"); | 751 | printk(", DMA"); |
752 | } else if (id->field_valid & 1) { | 752 | } else if (id->field_valid & 1) { |
753 | printk(", BUG"); | 753 | goto bug_dma_off; |
754 | } | 754 | } |
755 | return; | 755 | return; |
756 | bug_dma_off: | 756 | bug_dma_off: |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 657165297dc7..77703acaec17 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/hdreg.h> | 23 | #include <linux/hdreg.h> |
24 | #include <linux/ide.h> | 24 | #include <linux/ide.h> |
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | #include <linux/nmi.h> | ||
26 | 27 | ||
27 | #include <asm/byteorder.h> | 28 | #include <asm/byteorder.h> |
28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
@@ -1243,6 +1244,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
1243 | if (stat == 0xff) | 1244 | if (stat == 0xff) |
1244 | return -ENODEV; | 1245 | return -ENODEV; |
1245 | touch_softlockup_watchdog(); | 1246 | touch_softlockup_watchdog(); |
1247 | touch_nmi_watchdog(); | ||
1246 | } | 1248 | } |
1247 | return -EBUSY; | 1249 | return -EBUSY; |
1248 | } | 1250 | } |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 05fbd9298db7..defd4b4bd374 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -1539,7 +1539,7 @@ static int __init ide_setup(char *s) | |||
1539 | const char *hd_words[] = { | 1539 | const char *hd_words[] = { |
1540 | "none", "noprobe", "nowerr", "cdrom", "serialize", | 1540 | "none", "noprobe", "nowerr", "cdrom", "serialize", |
1541 | "autotune", "noautotune", "minus8", "swapdata", "bswap", | 1541 | "autotune", "noautotune", "minus8", "swapdata", "bswap", |
1542 | "minus11", "remap", "remap63", "scsi", NULL }; | 1542 | "noflush", "remap", "remap63", "scsi", NULL }; |
1543 | unit = s[2] - 'a'; | 1543 | unit = s[2] - 'a'; |
1544 | hw = unit / MAX_DRIVES; | 1544 | hw = unit / MAX_DRIVES; |
1545 | unit = unit % MAX_DRIVES; | 1545 | unit = unit % MAX_DRIVES; |
@@ -1578,6 +1578,9 @@ static int __init ide_setup(char *s) | |||
1578 | case -10: /* "bswap" */ | 1578 | case -10: /* "bswap" */ |
1579 | drive->bswap = 1; | 1579 | drive->bswap = 1; |
1580 | goto done; | 1580 | goto done; |
1581 | case -11: /* noflush */ | ||
1582 | drive->noflush = 1; | ||
1583 | goto done; | ||
1581 | case -12: /* "remap" */ | 1584 | case -12: /* "remap" */ |
1582 | drive->remap_0_to_1 = 1; | 1585 | drive->remap_0_to_1 = 1; |
1583 | goto done; | 1586 | goto done; |
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 3cb04424d351..e9bad185968a 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c | |||
@@ -498,9 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive) | |||
498 | { | 498 | { |
499 | u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); | 499 | u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); |
500 | 500 | ||
501 | config_it821x_chipset_for_pio(drive, !speed); | 501 | if (speed) { |
502 | it821x_tune_chipset(drive, speed); | 502 | config_it821x_chipset_for_pio(drive, 0); |
503 | return ide_dma_enable(drive); | 503 | it821x_tune_chipset(drive, speed); |
504 | |||
505 | return ide_dma_enable(drive); | ||
506 | } | ||
507 | |||
508 | return 0; | ||
504 | } | 509 | } |
505 | 510 | ||
506 | /** | 511 | /** |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index aaa74f293aaf..b08755e2e68f 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -2515,6 +2515,9 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev) | |||
2515 | sdev->skip_ms_page_8 = 1; | 2515 | sdev->skip_ms_page_8 = 1; |
2516 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) | 2516 | if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) |
2517 | sdev->fix_capacity = 1; | 2517 | sdev->fix_capacity = 1; |
2518 | if (scsi_id->ne->guid_vendor_id == 0x0010b9 && /* Maxtor's OUI */ | ||
2519 | (sdev->type == TYPE_DISK || sdev->type == TYPE_RBC)) | ||
2520 | sdev->allow_restart = 1; | ||
2518 | return 0; | 2521 | return 0; |
2519 | } | 2522 | } |
2520 | 2523 | ||
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index d294bbc42f09..1205e8027829 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <net/arp.h> | 35 | #include <net/arp.h> |
36 | #include <net/neighbour.h> | 36 | #include <net/neighbour.h> |
37 | #include <net/route.h> | 37 | #include <net/route.h> |
38 | #include <net/netevent.h> | ||
38 | #include <rdma/ib_addr.h> | 39 | #include <rdma/ib_addr.h> |
39 | 40 | ||
40 | MODULE_AUTHOR("Sean Hefty"); | 41 | MODULE_AUTHOR("Sean Hefty"); |
@@ -326,25 +327,22 @@ void rdma_addr_cancel(struct rdma_dev_addr *addr) | |||
326 | } | 327 | } |
327 | EXPORT_SYMBOL(rdma_addr_cancel); | 328 | EXPORT_SYMBOL(rdma_addr_cancel); |
328 | 329 | ||
329 | static int addr_arp_recv(struct sk_buff *skb, struct net_device *dev, | 330 | static int netevent_callback(struct notifier_block *self, unsigned long event, |
330 | struct packet_type *pkt, struct net_device *orig_dev) | 331 | void *ctx) |
331 | { | 332 | { |
332 | struct arphdr *arp_hdr; | 333 | if (event == NETEVENT_NEIGH_UPDATE) { |
334 | struct neighbour *neigh = ctx; | ||
333 | 335 | ||
334 | arp_hdr = (struct arphdr *) skb->nh.raw; | 336 | if (neigh->dev->type == ARPHRD_INFINIBAND && |
335 | 337 | (neigh->nud_state & NUD_VALID)) { | |
336 | if (arp_hdr->ar_op == htons(ARPOP_REQUEST) || | 338 | set_timeout(jiffies); |
337 | arp_hdr->ar_op == htons(ARPOP_REPLY)) | 339 | } |
338 | set_timeout(jiffies); | 340 | } |
339 | |||
340 | kfree_skb(skb); | ||
341 | return 0; | 341 | return 0; |
342 | } | 342 | } |
343 | 343 | ||
344 | static struct packet_type addr_arp = { | 344 | static struct notifier_block nb = { |
345 | .type = __constant_htons(ETH_P_ARP), | 345 | .notifier_call = netevent_callback |
346 | .func = addr_arp_recv, | ||
347 | .af_packet_priv = (void*) 1, | ||
348 | }; | 346 | }; |
349 | 347 | ||
350 | static int addr_init(void) | 348 | static int addr_init(void) |
@@ -353,13 +351,13 @@ static int addr_init(void) | |||
353 | if (!addr_wq) | 351 | if (!addr_wq) |
354 | return -ENOMEM; | 352 | return -ENOMEM; |
355 | 353 | ||
356 | dev_add_pack(&addr_arp); | 354 | register_netevent_notifier(&nb); |
357 | return 0; | 355 | return 0; |
358 | } | 356 | } |
359 | 357 | ||
360 | static void addr_cleanup(void) | 358 | static void addr_cleanup(void) |
361 | { | 359 | { |
362 | dev_remove_pack(&addr_arp); | 360 | unregister_netevent_notifier(&nb); |
363 | destroy_workqueue(addr_wq); | 361 | destroy_workqueue(addr_wq); |
364 | } | 362 | } |
365 | 363 | ||
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index f85c97f7500a..0de335b7bfc2 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -975,8 +975,10 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, | |||
975 | 975 | ||
976 | cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv-> | 976 | cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv-> |
977 | id.local_id); | 977 | id.local_id); |
978 | if (IS_ERR(cm_id_priv->timewait_info)) | 978 | if (IS_ERR(cm_id_priv->timewait_info)) { |
979 | ret = PTR_ERR(cm_id_priv->timewait_info); | ||
979 | goto out; | 980 | goto out; |
981 | } | ||
980 | 982 | ||
981 | ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av); | 983 | ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av); |
982 | if (ret) | 984 | if (ret) |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 5ed4dab52a6f..1c3cfbbe6a97 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -167,6 +167,15 @@ static int is_vendor_method_in_use( | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | 169 | ||
170 | int ib_response_mad(struct ib_mad *mad) | ||
171 | { | ||
172 | return ((mad->mad_hdr.method & IB_MGMT_METHOD_RESP) || | ||
173 | (mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) || | ||
174 | ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_BM) && | ||
175 | (mad->mad_hdr.attr_mod & IB_BM_ATTR_MOD_RESP))); | ||
176 | } | ||
177 | EXPORT_SYMBOL(ib_response_mad); | ||
178 | |||
170 | /* | 179 | /* |
171 | * ib_register_mad_agent - Register to send/receive MADs | 180 | * ib_register_mad_agent - Register to send/receive MADs |
172 | */ | 181 | */ |
@@ -570,13 +579,6 @@ int ib_unregister_mad_agent(struct ib_mad_agent *mad_agent) | |||
570 | } | 579 | } |
571 | EXPORT_SYMBOL(ib_unregister_mad_agent); | 580 | EXPORT_SYMBOL(ib_unregister_mad_agent); |
572 | 581 | ||
573 | static inline int response_mad(struct ib_mad *mad) | ||
574 | { | ||
575 | /* Trap represses are responses although response bit is reset */ | ||
576 | return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) || | ||
577 | (mad->mad_hdr.method & IB_MGMT_METHOD_RESP)); | ||
578 | } | ||
579 | |||
580 | static void dequeue_mad(struct ib_mad_list_head *mad_list) | 582 | static void dequeue_mad(struct ib_mad_list_head *mad_list) |
581 | { | 583 | { |
582 | struct ib_mad_queue *mad_queue; | 584 | struct ib_mad_queue *mad_queue; |
@@ -723,7 +725,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
723 | switch (ret) | 725 | switch (ret) |
724 | { | 726 | { |
725 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY: | 727 | case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY: |
726 | if (response_mad(&mad_priv->mad.mad) && | 728 | if (ib_response_mad(&mad_priv->mad.mad) && |
727 | mad_agent_priv->agent.recv_handler) { | 729 | mad_agent_priv->agent.recv_handler) { |
728 | local->mad_priv = mad_priv; | 730 | local->mad_priv = mad_priv; |
729 | local->recv_mad_agent = mad_agent_priv; | 731 | local->recv_mad_agent = mad_agent_priv; |
@@ -1551,7 +1553,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv, | |||
1551 | unsigned long flags; | 1553 | unsigned long flags; |
1552 | 1554 | ||
1553 | spin_lock_irqsave(&port_priv->reg_lock, flags); | 1555 | spin_lock_irqsave(&port_priv->reg_lock, flags); |
1554 | if (response_mad(mad)) { | 1556 | if (ib_response_mad(mad)) { |
1555 | u32 hi_tid; | 1557 | u32 hi_tid; |
1556 | struct ib_mad_agent_private *entry; | 1558 | struct ib_mad_agent_private *entry; |
1557 | 1559 | ||
@@ -1799,7 +1801,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1799 | } | 1801 | } |
1800 | 1802 | ||
1801 | /* Complete corresponding request */ | 1803 | /* Complete corresponding request */ |
1802 | if (response_mad(mad_recv_wc->recv_buf.mad)) { | 1804 | if (ib_response_mad(mad_recv_wc->recv_buf.mad)) { |
1803 | spin_lock_irqsave(&mad_agent_priv->lock, flags); | 1805 | spin_lock_irqsave(&mad_agent_priv->lock, flags); |
1804 | mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); | 1806 | mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); |
1805 | if (!mad_send_wr) { | 1807 | if (!mad_send_wr) { |
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index afe70a549c2f..1273f8807e84 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -112,8 +112,10 @@ struct ib_umad_device { | |||
112 | struct ib_umad_file { | 112 | struct ib_umad_file { |
113 | struct ib_umad_port *port; | 113 | struct ib_umad_port *port; |
114 | struct list_head recv_list; | 114 | struct list_head recv_list; |
115 | struct list_head send_list; | ||
115 | struct list_head port_list; | 116 | struct list_head port_list; |
116 | spinlock_t recv_lock; | 117 | spinlock_t recv_lock; |
118 | spinlock_t send_lock; | ||
117 | wait_queue_head_t recv_wait; | 119 | wait_queue_head_t recv_wait; |
118 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; | 120 | struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; |
119 | int agents_dead; | 121 | int agents_dead; |
@@ -177,12 +179,21 @@ static int queue_packet(struct ib_umad_file *file, | |||
177 | return ret; | 179 | return ret; |
178 | } | 180 | } |
179 | 181 | ||
182 | static void dequeue_send(struct ib_umad_file *file, | ||
183 | struct ib_umad_packet *packet) | ||
184 | { | ||
185 | spin_lock_irq(&file->send_lock); | ||
186 | list_del(&packet->list); | ||
187 | spin_unlock_irq(&file->send_lock); | ||
188 | } | ||
189 | |||
180 | static void send_handler(struct ib_mad_agent *agent, | 190 | static void send_handler(struct ib_mad_agent *agent, |
181 | struct ib_mad_send_wc *send_wc) | 191 | struct ib_mad_send_wc *send_wc) |
182 | { | 192 | { |
183 | struct ib_umad_file *file = agent->context; | 193 | struct ib_umad_file *file = agent->context; |
184 | struct ib_umad_packet *packet = send_wc->send_buf->context[0]; | 194 | struct ib_umad_packet *packet = send_wc->send_buf->context[0]; |
185 | 195 | ||
196 | dequeue_send(file, packet); | ||
186 | ib_destroy_ah(packet->msg->ah); | 197 | ib_destroy_ah(packet->msg->ah); |
187 | ib_free_send_mad(packet->msg); | 198 | ib_free_send_mad(packet->msg); |
188 | 199 | ||
@@ -370,6 +381,51 @@ static int copy_rmpp_mad(struct ib_mad_send_buf *msg, const char __user *buf) | |||
370 | return 0; | 381 | return 0; |
371 | } | 382 | } |
372 | 383 | ||
384 | static int same_destination(struct ib_user_mad_hdr *hdr1, | ||
385 | struct ib_user_mad_hdr *hdr2) | ||
386 | { | ||
387 | if (!hdr1->grh_present && !hdr2->grh_present) | ||
388 | return (hdr1->lid == hdr2->lid); | ||
389 | |||
390 | if (hdr1->grh_present && hdr2->grh_present) | ||
391 | return !memcmp(hdr1->gid, hdr2->gid, 16); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static int is_duplicate(struct ib_umad_file *file, | ||
397 | struct ib_umad_packet *packet) | ||
398 | { | ||
399 | struct ib_umad_packet *sent_packet; | ||
400 | struct ib_mad_hdr *sent_hdr, *hdr; | ||
401 | |||
402 | hdr = (struct ib_mad_hdr *) packet->mad.data; | ||
403 | list_for_each_entry(sent_packet, &file->send_list, list) { | ||
404 | sent_hdr = (struct ib_mad_hdr *) sent_packet->mad.data; | ||
405 | |||
406 | if ((hdr->tid != sent_hdr->tid) || | ||
407 | (hdr->mgmt_class != sent_hdr->mgmt_class)) | ||
408 | continue; | ||
409 | |||
410 | /* | ||
411 | * No need to be overly clever here. If two new operations have | ||
412 | * the same TID, reject the second as a duplicate. This is more | ||
413 | * restrictive than required by the spec. | ||
414 | */ | ||
415 | if (!ib_response_mad((struct ib_mad *) hdr)) { | ||
416 | if (!ib_response_mad((struct ib_mad *) sent_hdr)) | ||
417 | return 1; | ||
418 | continue; | ||
419 | } else if (!ib_response_mad((struct ib_mad *) sent_hdr)) | ||
420 | continue; | ||
421 | |||
422 | if (same_destination(&packet->mad.hdr, &sent_packet->mad.hdr)) | ||
423 | return 1; | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
373 | static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | 429 | static ssize_t ib_umad_write(struct file *filp, const char __user *buf, |
374 | size_t count, loff_t *pos) | 430 | size_t count, loff_t *pos) |
375 | { | 431 | { |
@@ -379,7 +435,6 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
379 | struct ib_ah_attr ah_attr; | 435 | struct ib_ah_attr ah_attr; |
380 | struct ib_ah *ah; | 436 | struct ib_ah *ah; |
381 | struct ib_rmpp_mad *rmpp_mad; | 437 | struct ib_rmpp_mad *rmpp_mad; |
382 | u8 method; | ||
383 | __be64 *tid; | 438 | __be64 *tid; |
384 | int ret, data_len, hdr_len, copy_offset, rmpp_active; | 439 | int ret, data_len, hdr_len, copy_offset, rmpp_active; |
385 | 440 | ||
@@ -473,28 +528,36 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
473 | } | 528 | } |
474 | 529 | ||
475 | /* | 530 | /* |
476 | * If userspace is generating a request that will generate a | 531 | * Set the high-order part of the transaction ID to make MADs from |
477 | * response, we need to make sure the high-order part of the | 532 | * different agents unique, and allow routing responses back to the |
478 | * transaction ID matches the agent being used to send the | 533 | * original requestor. |
479 | * MAD. | ||
480 | */ | 534 | */ |
481 | method = ((struct ib_mad_hdr *) packet->msg->mad)->method; | 535 | if (!ib_response_mad(packet->msg->mad)) { |
482 | |||
483 | if (!(method & IB_MGMT_METHOD_RESP) && | ||
484 | method != IB_MGMT_METHOD_TRAP_REPRESS && | ||
485 | method != IB_MGMT_METHOD_SEND) { | ||
486 | tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; | 536 | tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; |
487 | *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | | 537 | *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | |
488 | (be64_to_cpup(tid) & 0xffffffff)); | 538 | (be64_to_cpup(tid) & 0xffffffff)); |
539 | rmpp_mad->mad_hdr.tid = *tid; | ||
540 | } | ||
541 | |||
542 | spin_lock_irq(&file->send_lock); | ||
543 | ret = is_duplicate(file, packet); | ||
544 | if (!ret) | ||
545 | list_add_tail(&packet->list, &file->send_list); | ||
546 | spin_unlock_irq(&file->send_lock); | ||
547 | if (ret) { | ||
548 | ret = -EINVAL; | ||
549 | goto err_msg; | ||
489 | } | 550 | } |
490 | 551 | ||
491 | ret = ib_post_send_mad(packet->msg, NULL); | 552 | ret = ib_post_send_mad(packet->msg, NULL); |
492 | if (ret) | 553 | if (ret) |
493 | goto err_msg; | 554 | goto err_send; |
494 | 555 | ||
495 | up_read(&file->port->mutex); | 556 | up_read(&file->port->mutex); |
496 | return count; | 557 | return count; |
497 | 558 | ||
559 | err_send: | ||
560 | dequeue_send(file, packet); | ||
498 | err_msg: | 561 | err_msg: |
499 | ib_free_send_mad(packet->msg); | 562 | ib_free_send_mad(packet->msg); |
500 | err_ah: | 563 | err_ah: |
@@ -657,7 +720,9 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
657 | } | 720 | } |
658 | 721 | ||
659 | spin_lock_init(&file->recv_lock); | 722 | spin_lock_init(&file->recv_lock); |
723 | spin_lock_init(&file->send_lock); | ||
660 | INIT_LIST_HEAD(&file->recv_list); | 724 | INIT_LIST_HEAD(&file->recv_list); |
725 | INIT_LIST_HEAD(&file->send_list); | ||
661 | init_waitqueue_head(&file->recv_wait); | 726 | init_waitqueue_head(&file->recv_wait); |
662 | 727 | ||
663 | file->port = port; | 728 | file->port = port; |
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index bb9bee56a824..102a59c033ff 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/kref.h> | 42 | #include <linux/kref.h> |
43 | #include <linux/idr.h> | 43 | #include <linux/idr.h> |
44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
45 | #include <linux/completion.h> | ||
45 | 46 | ||
46 | #include <rdma/ib_verbs.h> | 47 | #include <rdma/ib_verbs.h> |
47 | #include <rdma/ib_user_verbs.h> | 48 | #include <rdma/ib_user_verbs.h> |
@@ -69,6 +70,7 @@ | |||
69 | 70 | ||
70 | struct ib_uverbs_device { | 71 | struct ib_uverbs_device { |
71 | struct kref ref; | 72 | struct kref ref; |
73 | struct completion comp; | ||
72 | int devnum; | 74 | int devnum; |
73 | struct cdev *dev; | 75 | struct cdev *dev; |
74 | struct class_device *class_dev; | 76 | struct class_device *class_dev; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index bdf5d5098190..30923eb68ec7 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -42,6 +42,13 @@ | |||
42 | 42 | ||
43 | #include "uverbs.h" | 43 | #include "uverbs.h" |
44 | 44 | ||
45 | static struct lock_class_key pd_lock_key; | ||
46 | static struct lock_class_key mr_lock_key; | ||
47 | static struct lock_class_key cq_lock_key; | ||
48 | static struct lock_class_key qp_lock_key; | ||
49 | static struct lock_class_key ah_lock_key; | ||
50 | static struct lock_class_key srq_lock_key; | ||
51 | |||
45 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ | 52 | #define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ |
46 | do { \ | 53 | do { \ |
47 | (udata)->inbuf = (void __user *) (ibuf); \ | 54 | (udata)->inbuf = (void __user *) (ibuf); \ |
@@ -76,12 +83,13 @@ | |||
76 | */ | 83 | */ |
77 | 84 | ||
78 | static void init_uobj(struct ib_uobject *uobj, u64 user_handle, | 85 | static void init_uobj(struct ib_uobject *uobj, u64 user_handle, |
79 | struct ib_ucontext *context) | 86 | struct ib_ucontext *context, struct lock_class_key *key) |
80 | { | 87 | { |
81 | uobj->user_handle = user_handle; | 88 | uobj->user_handle = user_handle; |
82 | uobj->context = context; | 89 | uobj->context = context; |
83 | kref_init(&uobj->ref); | 90 | kref_init(&uobj->ref); |
84 | init_rwsem(&uobj->mutex); | 91 | init_rwsem(&uobj->mutex); |
92 | lockdep_set_class(&uobj->mutex, key); | ||
85 | uobj->live = 0; | 93 | uobj->live = 0; |
86 | } | 94 | } |
87 | 95 | ||
@@ -470,7 +478,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, | |||
470 | if (!uobj) | 478 | if (!uobj) |
471 | return -ENOMEM; | 479 | return -ENOMEM; |
472 | 480 | ||
473 | init_uobj(uobj, 0, file->ucontext); | 481 | init_uobj(uobj, 0, file->ucontext, &pd_lock_key); |
474 | down_write(&uobj->mutex); | 482 | down_write(&uobj->mutex); |
475 | 483 | ||
476 | pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, | 484 | pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, |
@@ -591,7 +599,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, | |||
591 | if (!obj) | 599 | if (!obj) |
592 | return -ENOMEM; | 600 | return -ENOMEM; |
593 | 601 | ||
594 | init_uobj(&obj->uobject, 0, file->ucontext); | 602 | init_uobj(&obj->uobject, 0, file->ucontext, &mr_lock_key); |
595 | down_write(&obj->uobject.mutex); | 603 | down_write(&obj->uobject.mutex); |
596 | 604 | ||
597 | /* | 605 | /* |
@@ -770,7 +778,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, | |||
770 | if (!obj) | 778 | if (!obj) |
771 | return -ENOMEM; | 779 | return -ENOMEM; |
772 | 780 | ||
773 | init_uobj(&obj->uobject, cmd.user_handle, file->ucontext); | 781 | init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &cq_lock_key); |
774 | down_write(&obj->uobject.mutex); | 782 | down_write(&obj->uobject.mutex); |
775 | 783 | ||
776 | if (cmd.comp_channel >= 0) { | 784 | if (cmd.comp_channel >= 0) { |
@@ -1051,13 +1059,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1051 | if (!obj) | 1059 | if (!obj) |
1052 | return -ENOMEM; | 1060 | return -ENOMEM; |
1053 | 1061 | ||
1054 | init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext); | 1062 | init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); |
1055 | down_write(&obj->uevent.uobject.mutex); | 1063 | down_write(&obj->uevent.uobject.mutex); |
1056 | 1064 | ||
1065 | srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; | ||
1057 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 1066 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); |
1058 | scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); | 1067 | scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); |
1059 | rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext); | 1068 | rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? |
1060 | srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; | 1069 | scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext); |
1061 | 1070 | ||
1062 | if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { | 1071 | if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { |
1063 | ret = -EINVAL; | 1072 | ret = -EINVAL; |
@@ -1125,7 +1134,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1125 | 1134 | ||
1126 | put_pd_read(pd); | 1135 | put_pd_read(pd); |
1127 | put_cq_read(scq); | 1136 | put_cq_read(scq); |
1128 | put_cq_read(rcq); | 1137 | if (rcq != scq) |
1138 | put_cq_read(rcq); | ||
1129 | if (srq) | 1139 | if (srq) |
1130 | put_srq_read(srq); | 1140 | put_srq_read(srq); |
1131 | 1141 | ||
@@ -1150,7 +1160,7 @@ err_put: | |||
1150 | put_pd_read(pd); | 1160 | put_pd_read(pd); |
1151 | if (scq) | 1161 | if (scq) |
1152 | put_cq_read(scq); | 1162 | put_cq_read(scq); |
1153 | if (rcq) | 1163 | if (rcq && rcq != scq) |
1154 | put_cq_read(rcq); | 1164 | put_cq_read(rcq); |
1155 | if (srq) | 1165 | if (srq) |
1156 | put_srq_read(srq); | 1166 | put_srq_read(srq); |
@@ -1751,7 +1761,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, | |||
1751 | if (!uobj) | 1761 | if (!uobj) |
1752 | return -ENOMEM; | 1762 | return -ENOMEM; |
1753 | 1763 | ||
1754 | init_uobj(uobj, cmd.user_handle, file->ucontext); | 1764 | init_uobj(uobj, cmd.user_handle, file->ucontext, &ah_lock_key); |
1755 | down_write(&uobj->mutex); | 1765 | down_write(&uobj->mutex); |
1756 | 1766 | ||
1757 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 1767 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); |
@@ -1775,7 +1785,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, | |||
1775 | ah = ib_create_ah(pd, &attr); | 1785 | ah = ib_create_ah(pd, &attr); |
1776 | if (IS_ERR(ah)) { | 1786 | if (IS_ERR(ah)) { |
1777 | ret = PTR_ERR(ah); | 1787 | ret = PTR_ERR(ah); |
1778 | goto err; | 1788 | goto err_put; |
1779 | } | 1789 | } |
1780 | 1790 | ||
1781 | ah->uobject = uobj; | 1791 | ah->uobject = uobj; |
@@ -1811,6 +1821,9 @@ err_copy: | |||
1811 | err_destroy: | 1821 | err_destroy: |
1812 | ib_destroy_ah(ah); | 1822 | ib_destroy_ah(ah); |
1813 | 1823 | ||
1824 | err_put: | ||
1825 | put_pd_read(pd); | ||
1826 | |||
1814 | err: | 1827 | err: |
1815 | put_uobj_write(uobj); | 1828 | put_uobj_write(uobj); |
1816 | return ret; | 1829 | return ret; |
@@ -1963,7 +1976,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | |||
1963 | if (!obj) | 1976 | if (!obj) |
1964 | return -ENOMEM; | 1977 | return -ENOMEM; |
1965 | 1978 | ||
1966 | init_uobj(&obj->uobject, cmd.user_handle, file->ucontext); | 1979 | init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key); |
1967 | down_write(&obj->uobject.mutex); | 1980 | down_write(&obj->uobject.mutex); |
1968 | 1981 | ||
1969 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 1982 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); |
@@ -1984,7 +1997,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | |||
1984 | srq = pd->device->create_srq(pd, &attr, &udata); | 1997 | srq = pd->device->create_srq(pd, &attr, &udata); |
1985 | if (IS_ERR(srq)) { | 1998 | if (IS_ERR(srq)) { |
1986 | ret = PTR_ERR(srq); | 1999 | ret = PTR_ERR(srq); |
1987 | goto err; | 2000 | goto err_put; |
1988 | } | 2001 | } |
1989 | 2002 | ||
1990 | srq->device = pd->device; | 2003 | srq->device = pd->device; |
@@ -2029,6 +2042,9 @@ err_copy: | |||
2029 | err_destroy: | 2042 | err_destroy: |
2030 | ib_destroy_srq(srq); | 2043 | ib_destroy_srq(srq); |
2031 | 2044 | ||
2045 | err_put: | ||
2046 | put_pd_read(pd); | ||
2047 | |||
2032 | err: | 2048 | err: |
2033 | put_uobj_write(&obj->uobject); | 2049 | put_uobj_write(&obj->uobject); |
2034 | return ret; | 2050 | return ret; |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index e725cccc7cde..4e16314e8e6d 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -122,7 +122,7 @@ static void ib_uverbs_release_dev(struct kref *ref) | |||
122 | struct ib_uverbs_device *dev = | 122 | struct ib_uverbs_device *dev = |
123 | container_of(ref, struct ib_uverbs_device, ref); | 123 | container_of(ref, struct ib_uverbs_device, ref); |
124 | 124 | ||
125 | kfree(dev); | 125 | complete(&dev->comp); |
126 | } | 126 | } |
127 | 127 | ||
128 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, | 128 | void ib_uverbs_release_ucq(struct ib_uverbs_file *file, |
@@ -740,6 +740,7 @@ static void ib_uverbs_add_one(struct ib_device *device) | |||
740 | return; | 740 | return; |
741 | 741 | ||
742 | kref_init(&uverbs_dev->ref); | 742 | kref_init(&uverbs_dev->ref); |
743 | init_completion(&uverbs_dev->comp); | ||
743 | 744 | ||
744 | spin_lock(&map_lock); | 745 | spin_lock(&map_lock); |
745 | uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); | 746 | uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES); |
@@ -793,6 +794,8 @@ err_cdev: | |||
793 | 794 | ||
794 | err: | 795 | err: |
795 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); | 796 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); |
797 | wait_for_completion(&uverbs_dev->comp); | ||
798 | kfree(uverbs_dev); | ||
796 | return; | 799 | return; |
797 | } | 800 | } |
798 | 801 | ||
@@ -812,7 +815,10 @@ static void ib_uverbs_remove_one(struct ib_device *device) | |||
812 | spin_unlock(&map_lock); | 815 | spin_unlock(&map_lock); |
813 | 816 | ||
814 | clear_bit(uverbs_dev->devnum, dev_map); | 817 | clear_bit(uverbs_dev->devnum, dev_map); |
818 | |||
815 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); | 819 | kref_put(&uverbs_dev->ref, ib_uverbs_release_dev); |
820 | wait_for_completion(&uverbs_dev->comp); | ||
821 | kfree(uverbs_dev); | ||
816 | } | 822 | } |
817 | 823 | ||
818 | static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags, | 824 | static int uverbs_event_get_sb(struct file_system_type *fs_type, int flags, |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 823131d58b34..f98518d912b5 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -859,6 +859,38 @@ static void ipath_rcv_layer(struct ipath_devdata *dd, u32 etail, | |||
859 | __ipath_layer_rcv_lid(dd, hdr); | 859 | __ipath_layer_rcv_lid(dd, hdr); |
860 | } | 860 | } |
861 | 861 | ||
862 | static void ipath_rcv_hdrerr(struct ipath_devdata *dd, | ||
863 | u32 eflags, | ||
864 | u32 l, | ||
865 | u32 etail, | ||
866 | u64 *rc) | ||
867 | { | ||
868 | char emsg[128]; | ||
869 | struct ipath_message_header *hdr; | ||
870 | |||
871 | get_rhf_errstring(eflags, emsg, sizeof emsg); | ||
872 | hdr = (struct ipath_message_header *)&rc[1]; | ||
873 | ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u " | ||
874 | "tlen=%x opcode=%x egridx=%x: %s\n", | ||
875 | eflags, l, | ||
876 | ipath_hdrget_rcv_type((__le32 *) rc), | ||
877 | ipath_hdrget_length_in_bytes((__le32 *) rc), | ||
878 | be32_to_cpu(hdr->bth[0]) >> 24, | ||
879 | etail, emsg); | ||
880 | |||
881 | /* Count local link integrity errors. */ | ||
882 | if (eflags & (INFINIPATH_RHF_H_ICRCERR | INFINIPATH_RHF_H_VCRCERR)) { | ||
883 | u8 n = (dd->ipath_ibcctrl >> | ||
884 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
885 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
886 | |||
887 | if (++dd->ipath_lli_counter > n) { | ||
888 | dd->ipath_lli_counter = 0; | ||
889 | dd->ipath_lli_errors++; | ||
890 | } | ||
891 | } | ||
892 | } | ||
893 | |||
862 | /* | 894 | /* |
863 | * ipath_kreceive - receive a packet | 895 | * ipath_kreceive - receive a packet |
864 | * @dd: the infinipath device | 896 | * @dd: the infinipath device |
@@ -875,7 +907,6 @@ void ipath_kreceive(struct ipath_devdata *dd) | |||
875 | struct ipath_message_header *hdr; | 907 | struct ipath_message_header *hdr; |
876 | u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0; | 908 | u32 eflags, i, etype, tlen, pkttot = 0, updegr=0, reloop=0; |
877 | static u64 totcalls; /* stats, may eventually remove */ | 909 | static u64 totcalls; /* stats, may eventually remove */ |
878 | char emsg[128]; | ||
879 | 910 | ||
880 | if (!dd->ipath_hdrqtailptr) { | 911 | if (!dd->ipath_hdrqtailptr) { |
881 | ipath_dev_err(dd, | 912 | ipath_dev_err(dd, |
@@ -938,26 +969,9 @@ reloop: | |||
938 | "%x\n", etype); | 969 | "%x\n", etype); |
939 | } | 970 | } |
940 | 971 | ||
941 | if (eflags & ~(INFINIPATH_RHF_H_TIDERR | | 972 | if (unlikely(eflags)) |
942 | INFINIPATH_RHF_H_IHDRERR)) { | 973 | ipath_rcv_hdrerr(dd, eflags, l, etail, rc); |
943 | get_rhf_errstring(eflags, emsg, sizeof emsg); | 974 | else if (etype == RCVHQ_RCV_TYPE_NON_KD) { |
944 | ipath_cdbg(PKT, "RHFerrs %x hdrqtail=%x typ=%u " | ||
945 | "tlen=%x opcode=%x egridx=%x: %s\n", | ||
946 | eflags, l, etype, tlen, bthbytes[0], | ||
947 | ipath_hdrget_index((__le32 *) rc), emsg); | ||
948 | /* Count local link integrity errors. */ | ||
949 | if (eflags & (INFINIPATH_RHF_H_ICRCERR | | ||
950 | INFINIPATH_RHF_H_VCRCERR)) { | ||
951 | u8 n = (dd->ipath_ibcctrl >> | ||
952 | INFINIPATH_IBCC_PHYERRTHRESHOLD_SHIFT) & | ||
953 | INFINIPATH_IBCC_PHYERRTHRESHOLD_MASK; | ||
954 | |||
955 | if (++dd->ipath_lli_counter > n) { | ||
956 | dd->ipath_lli_counter = 0; | ||
957 | dd->ipath_lli_errors++; | ||
958 | } | ||
959 | } | ||
960 | } else if (etype == RCVHQ_RCV_TYPE_NON_KD) { | ||
961 | int ret = __ipath_verbs_rcv(dd, rc + 1, | 975 | int ret = __ipath_verbs_rcv(dd, rc + 1, |
962 | ebuf, tlen); | 976 | ebuf, tlen); |
963 | if (ret == -ENODEV) | 977 | if (ret == -ENODEV) |
@@ -981,25 +995,7 @@ reloop: | |||
981 | else if (etype == RCVHQ_RCV_TYPE_EXPECTED) | 995 | else if (etype == RCVHQ_RCV_TYPE_EXPECTED) |
982 | ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", | 996 | ipath_dbg("Bug: Expected TID, opcode %x; ignored\n", |
983 | be32_to_cpu(hdr->bth[0]) & 0xff); | 997 | be32_to_cpu(hdr->bth[0]) & 0xff); |
984 | else if (eflags & (INFINIPATH_RHF_H_TIDERR | | 998 | else { |
985 | INFINIPATH_RHF_H_IHDRERR)) { | ||
986 | /* | ||
987 | * This is a type 3 packet, only the LRH is in the | ||
988 | * rcvhdrq, the rest of the header is in the eager | ||
989 | * buffer. | ||
990 | */ | ||
991 | u8 opcode; | ||
992 | if (ebuf) { | ||
993 | bthbytes = (u8 *) ebuf; | ||
994 | opcode = *bthbytes; | ||
995 | } | ||
996 | else | ||
997 | opcode = 0; | ||
998 | get_rhf_errstring(eflags, emsg, sizeof emsg); | ||
999 | ipath_dbg("Err %x (%s), opcode %x, egrbuf %x, " | ||
1000 | "len %x\n", eflags, emsg, opcode, etail, | ||
1001 | tlen); | ||
1002 | } else { | ||
1003 | /* | 999 | /* |
1004 | * error packet, type of error unknown. | 1000 | * error packet, type of error unknown. |
1005 | * Probably type 3, but we don't know, so don't | 1001 | * Probably type 3, but we don't know, so don't |
diff --git a/drivers/infiniband/hw/ipath/ipath_keys.c b/drivers/infiniband/hw/ipath/ipath_keys.c index 46773c673a1a..a5ca279370aa 100644 --- a/drivers/infiniband/hw/ipath/ipath_keys.c +++ b/drivers/infiniband/hw/ipath/ipath_keys.c | |||
@@ -197,6 +197,21 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss, | |||
197 | size_t off; | 197 | size_t off; |
198 | int ret; | 198 | int ret; |
199 | 199 | ||
200 | /* | ||
201 | * We use RKEY == zero for physical addresses | ||
202 | * (see ipath_get_dma_mr). | ||
203 | */ | ||
204 | if (rkey == 0) { | ||
205 | sge->mr = NULL; | ||
206 | sge->vaddr = phys_to_virt(vaddr); | ||
207 | sge->length = len; | ||
208 | sge->sge_length = len; | ||
209 | ss->sg_list = NULL; | ||
210 | ss->num_sge = 1; | ||
211 | ret = 1; | ||
212 | goto bail; | ||
213 | } | ||
214 | |||
200 | mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))]; | 215 | mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))]; |
201 | if (unlikely(mr == NULL || mr->lkey != rkey)) { | 216 | if (unlikely(mr == NULL || mr->lkey != rkey)) { |
202 | ret = 0; | 217 | ret = 0; |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 56ac336dd1ec..d70a9b6b5239 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
@@ -191,10 +191,6 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length) | |||
191 | { | 191 | { |
192 | struct ipath_sge *sge = &ss->sge; | 192 | struct ipath_sge *sge = &ss->sge; |
193 | 193 | ||
194 | while (length > sge->sge_length) { | ||
195 | length -= sge->sge_length; | ||
196 | ss->sge = *ss->sg_list++; | ||
197 | } | ||
198 | while (length) { | 194 | while (length) { |
199 | u32 len = sge->length; | 195 | u32 len = sge->length; |
200 | 196 | ||
@@ -627,6 +623,7 @@ static int ipath_query_device(struct ib_device *ibdev, | |||
627 | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | | 623 | props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | |
628 | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | | 624 | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | |
629 | IB_DEVICE_SYS_IMAGE_GUID; | 625 | IB_DEVICE_SYS_IMAGE_GUID; |
626 | props->page_size_cap = PAGE_SIZE; | ||
630 | props->vendor_id = ipath_layer_get_vendorid(dev->dd); | 627 | props->vendor_id = ipath_layer_get_vendorid(dev->dd); |
631 | props->vendor_part_id = ipath_layer_get_deviceid(dev->dd); | 628 | props->vendor_part_id = ipath_layer_get_deviceid(dev->dd); |
632 | props->hw_ver = ipath_layer_get_pcirev(dev->dd); | 629 | props->hw_ver = ipath_layer_get_pcirev(dev->dd); |
diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c index 9ba3211cef7c..25157f57a6d0 100644 --- a/drivers/infiniband/hw/mthca/mthca_allocator.c +++ b/drivers/infiniband/hw/mthca/mthca_allocator.c | |||
@@ -108,14 +108,15 @@ void mthca_alloc_cleanup(struct mthca_alloc *alloc) | |||
108 | * serialize access to the array. | 108 | * serialize access to the array. |
109 | */ | 109 | */ |
110 | 110 | ||
111 | #define MTHCA_ARRAY_MASK (PAGE_SIZE / sizeof (void *) - 1) | ||
112 | |||
111 | void *mthca_array_get(struct mthca_array *array, int index) | 113 | void *mthca_array_get(struct mthca_array *array, int index) |
112 | { | 114 | { |
113 | int p = (index * sizeof (void *)) >> PAGE_SHIFT; | 115 | int p = (index * sizeof (void *)) >> PAGE_SHIFT; |
114 | 116 | ||
115 | if (array->page_list[p].page) { | 117 | if (array->page_list[p].page) |
116 | int i = index & (PAGE_SIZE / sizeof (void *) - 1); | 118 | return array->page_list[p].page[index & MTHCA_ARRAY_MASK]; |
117 | return array->page_list[p].page[i]; | 119 | else |
118 | } else | ||
119 | return NULL; | 120 | return NULL; |
120 | } | 121 | } |
121 | 122 | ||
@@ -130,8 +131,7 @@ int mthca_array_set(struct mthca_array *array, int index, void *value) | |||
130 | if (!array->page_list[p].page) | 131 | if (!array->page_list[p].page) |
131 | return -ENOMEM; | 132 | return -ENOMEM; |
132 | 133 | ||
133 | array->page_list[p].page[index & (PAGE_SIZE / sizeof (void *) - 1)] = | 134 | array->page_list[p].page[index & MTHCA_ARRAY_MASK] = value; |
134 | value; | ||
135 | ++array->page_list[p].used; | 135 | ++array->page_list[p].used; |
136 | 136 | ||
137 | return 0; | 137 | return 0; |
@@ -144,7 +144,8 @@ void mthca_array_clear(struct mthca_array *array, int index) | |||
144 | if (--array->page_list[p].used == 0) { | 144 | if (--array->page_list[p].used == 0) { |
145 | free_page((unsigned long) array->page_list[p].page); | 145 | free_page((unsigned long) array->page_list[p].page); |
146 | array->page_list[p].page = NULL; | 146 | array->page_list[p].page = NULL; |
147 | } | 147 | } else |
148 | array->page_list[p].page[index & MTHCA_ARRAY_MASK] = NULL; | ||
148 | 149 | ||
149 | if (array->page_list[p].used < 0) | 150 | if (array->page_list[p].used < 0) |
150 | pr_debug("Array %p index %d page %d with ref count %d < 0\n", | 151 | pr_debug("Array %p index %d page %d with ref count %d < 0\n", |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index d0f7731802c9..deabc14b4ea4 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -778,11 +778,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) | |||
778 | ((dev->fw_ver & 0xffff0000ull) >> 16) | | 778 | ((dev->fw_ver & 0xffff0000ull) >> 16) | |
779 | ((dev->fw_ver & 0x0000ffffull) << 16); | 779 | ((dev->fw_ver & 0x0000ffffull) << 16); |
780 | 780 | ||
781 | MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); | ||
782 | dev->cmd.max_cmds = 1 << lg; | ||
783 | |||
781 | mthca_dbg(dev, "FW version %012llx, max commands %d\n", | 784 | mthca_dbg(dev, "FW version %012llx, max commands %d\n", |
782 | (unsigned long long) dev->fw_ver, dev->cmd.max_cmds); | 785 | (unsigned long long) dev->fw_ver, dev->cmd.max_cmds); |
783 | 786 | ||
784 | MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); | ||
785 | dev->cmd.max_cmds = 1 << lg; | ||
786 | MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET); | 787 | MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET); |
787 | MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET); | 788 | MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET); |
788 | 789 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index fab417c5cf43..b60a9d79ae54 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -370,7 +370,8 @@ int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | |||
370 | return -EINVAL; | 370 | return -EINVAL; |
371 | 371 | ||
372 | if (attr_mask & IB_SRQ_LIMIT) { | 372 | if (attr_mask & IB_SRQ_LIMIT) { |
373 | if (attr->srq_limit > srq->max) | 373 | u32 max_wr = mthca_is_memfree(dev) ? srq->max - 1 : srq->max; |
374 | if (attr->srq_limit > max_wr) | ||
374 | return -EINVAL; | 375 | return -EINVAL; |
375 | 376 | ||
376 | mutex_lock(&srq->mutex); | 377 | mutex_lock(&srq->mutex); |
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig index 13d6d01c72c0..d74653d7de1c 100644 --- a/drivers/infiniband/ulp/ipoib/Kconfig +++ b/drivers/infiniband/ulp/ipoib/Kconfig | |||
@@ -6,8 +6,7 @@ config INFINIBAND_IPOIB | |||
6 | transports IP packets over InfiniBand so you can use your IB | 6 | transports IP packets over InfiniBand so you can use your IB |
7 | device as a fancy NIC. | 7 | device as a fancy NIC. |
8 | 8 | ||
9 | The IPoIB protocol is defined by the IETF ipoib working | 9 | See Documentation/infiniband/ipoib.txt for more information |
10 | group: <http://www.ietf.org/html.charters/ipoib-charter.html>. | ||
11 | 10 | ||
12 | config INFINIBAND_IPOIB_DEBUG | 11 | config INFINIBAND_IPOIB_DEBUG |
13 | bool "IP-over-InfiniBand debugging" if EMBEDDED | 12 | bool "IP-over-InfiniBand debugging" if EMBEDDED |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 3f89f5e19036..474aa214ab57 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -212,6 +212,7 @@ struct ipoib_path { | |||
212 | 212 | ||
213 | struct ipoib_neigh { | 213 | struct ipoib_neigh { |
214 | struct ipoib_ah *ah; | 214 | struct ipoib_ah *ah; |
215 | union ib_gid dgid; | ||
215 | struct sk_buff_head queue; | 216 | struct sk_buff_head queue; |
216 | 217 | ||
217 | struct neighbour *neighbour; | 218 | struct neighbour *neighbour; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 1c6ea1c682a5..cf71d2a5515c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -404,6 +404,8 @@ static void path_rec_completion(int status, | |||
404 | list_for_each_entry(neigh, &path->neigh_list, list) { | 404 | list_for_each_entry(neigh, &path->neigh_list, list) { |
405 | kref_get(&path->ah->ref); | 405 | kref_get(&path->ah->ref); |
406 | neigh->ah = path->ah; | 406 | neigh->ah = path->ah; |
407 | memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, | ||
408 | sizeof(union ib_gid)); | ||
407 | 409 | ||
408 | while ((skb = __skb_dequeue(&neigh->queue))) | 410 | while ((skb = __skb_dequeue(&neigh->queue))) |
409 | __skb_queue_tail(&skqueue, skb); | 411 | __skb_queue_tail(&skqueue, skb); |
@@ -510,6 +512,8 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) | |||
510 | if (path->ah) { | 512 | if (path->ah) { |
511 | kref_get(&path->ah->ref); | 513 | kref_get(&path->ah->ref); |
512 | neigh->ah = path->ah; | 514 | neigh->ah = path->ah; |
515 | memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, | ||
516 | sizeof(union ib_gid)); | ||
513 | 517 | ||
514 | ipoib_send(dev, skb, path->ah, | 518 | ipoib_send(dev, skb, path->ah, |
515 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); | 519 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); |
@@ -633,6 +637,25 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
633 | neigh = *to_ipoib_neigh(skb->dst->neighbour); | 637 | neigh = *to_ipoib_neigh(skb->dst->neighbour); |
634 | 638 | ||
635 | if (likely(neigh->ah)) { | 639 | if (likely(neigh->ah)) { |
640 | if (unlikely(memcmp(&neigh->dgid.raw, | ||
641 | skb->dst->neighbour->ha + 4, | ||
642 | sizeof(union ib_gid)))) { | ||
643 | spin_lock(&priv->lock); | ||
644 | /* | ||
645 | * It's safe to call ipoib_put_ah() inside | ||
646 | * priv->lock here, because we know that | ||
647 | * path->ah will always hold one more reference, | ||
648 | * so ipoib_put_ah() will never do more than | ||
649 | * decrement the ref count. | ||
650 | */ | ||
651 | ipoib_put_ah(neigh->ah); | ||
652 | list_del(&neigh->list); | ||
653 | ipoib_neigh_free(neigh); | ||
654 | spin_unlock(&priv->lock); | ||
655 | ipoib_path_lookup(skb, dev); | ||
656 | goto out; | ||
657 | } | ||
658 | |||
636 | ipoib_send(dev, skb, neigh->ah, | 659 | ipoib_send(dev, skb, neigh->ah, |
637 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); | 660 | be32_to_cpup((__be32 *) skb->dst->neighbour->ha)); |
638 | goto out; | 661 | goto out; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ab40488182b3..b5e6a7be603d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -264,6 +264,10 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
264 | if (!ah) { | 264 | if (!ah) { |
265 | ipoib_warn(priv, "ib_address_create failed\n"); | 265 | ipoib_warn(priv, "ib_address_create failed\n"); |
266 | } else { | 266 | } else { |
267 | spin_lock_irq(&priv->lock); | ||
268 | mcast->ah = ah; | ||
269 | spin_unlock_irq(&priv->lock); | ||
270 | |||
267 | ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT | 271 | ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT |
268 | " AV %p, LID 0x%04x, SL %d\n", | 272 | " AV %p, LID 0x%04x, SL %d\n", |
269 | IPOIB_GID_ARG(mcast->mcmember.mgid), | 273 | IPOIB_GID_ARG(mcast->mcmember.mgid), |
@@ -271,10 +275,6 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
271 | be16_to_cpu(mcast->mcmember.mlid), | 275 | be16_to_cpu(mcast->mcmember.mlid), |
272 | mcast->mcmember.sl); | 276 | mcast->mcmember.sl); |
273 | } | 277 | } |
274 | |||
275 | spin_lock_irq(&priv->lock); | ||
276 | mcast->ah = ah; | ||
277 | spin_unlock_irq(&priv->lock); | ||
278 | } | 278 | } |
279 | 279 | ||
280 | /* actually send any queued packets */ | 280 | /* actually send any queued packets */ |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 8f472e7113b4..8257d5a2c8f8 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -77,6 +77,14 @@ MODULE_PARM_DESC(topspin_workarounds, | |||
77 | 77 | ||
78 | static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; | 78 | static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; |
79 | 79 | ||
80 | static int mellanox_workarounds = 1; | ||
81 | |||
82 | module_param(mellanox_workarounds, int, 0444); | ||
83 | MODULE_PARM_DESC(mellanox_workarounds, | ||
84 | "Enable workarounds for Mellanox SRP target bugs if != 0"); | ||
85 | |||
86 | static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; | ||
87 | |||
80 | static void srp_add_one(struct ib_device *device); | 88 | static void srp_add_one(struct ib_device *device); |
81 | static void srp_remove_one(struct ib_device *device); | 89 | static void srp_remove_one(struct ib_device *device); |
82 | static void srp_completion(struct ib_cq *cq, void *target_ptr); | 90 | static void srp_completion(struct ib_cq *cq, void *target_ptr); |
@@ -526,8 +534,10 @@ static int srp_reconnect_target(struct srp_target_port *target) | |||
526 | while (ib_poll_cq(target->cq, 1, &wc) > 0) | 534 | while (ib_poll_cq(target->cq, 1, &wc) > 0) |
527 | ; /* nothing */ | 535 | ; /* nothing */ |
528 | 536 | ||
537 | spin_lock_irq(target->scsi_host->host_lock); | ||
529 | list_for_each_entry_safe(req, tmp, &target->req_queue, list) | 538 | list_for_each_entry_safe(req, tmp, &target->req_queue, list) |
530 | srp_reset_req(target, req); | 539 | srp_reset_req(target, req); |
540 | spin_unlock_irq(target->scsi_host->host_lock); | ||
531 | 541 | ||
532 | target->rx_head = 0; | 542 | target->rx_head = 0; |
533 | target->tx_head = 0; | 543 | target->tx_head = 0; |
@@ -567,7 +577,7 @@ err: | |||
567 | return ret; | 577 | return ret; |
568 | } | 578 | } |
569 | 579 | ||
570 | static int srp_map_fmr(struct srp_device *dev, struct scatterlist *scat, | 580 | static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, |
571 | int sg_cnt, struct srp_request *req, | 581 | int sg_cnt, struct srp_request *req, |
572 | struct srp_direct_buf *buf) | 582 | struct srp_direct_buf *buf) |
573 | { | 583 | { |
@@ -577,10 +587,15 @@ static int srp_map_fmr(struct srp_device *dev, struct scatterlist *scat, | |||
577 | int page_cnt; | 587 | int page_cnt; |
578 | int i, j; | 588 | int i, j; |
579 | int ret; | 589 | int ret; |
590 | struct srp_device *dev = target->srp_host->dev; | ||
580 | 591 | ||
581 | if (!dev->fmr_pool) | 592 | if (!dev->fmr_pool) |
582 | return -ENODEV; | 593 | return -ENODEV; |
583 | 594 | ||
595 | if ((sg_dma_address(&scat[0]) & ~dev->fmr_page_mask) && | ||
596 | mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) | ||
597 | return -EINVAL; | ||
598 | |||
584 | len = page_cnt = 0; | 599 | len = page_cnt = 0; |
585 | for (i = 0; i < sg_cnt; ++i) { | 600 | for (i = 0; i < sg_cnt; ++i) { |
586 | if (sg_dma_address(&scat[i]) & ~dev->fmr_page_mask) { | 601 | if (sg_dma_address(&scat[i]) & ~dev->fmr_page_mask) { |
@@ -683,7 +698,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | |||
683 | buf->va = cpu_to_be64(sg_dma_address(scat)); | 698 | buf->va = cpu_to_be64(sg_dma_address(scat)); |
684 | buf->key = cpu_to_be32(target->srp_host->dev->mr->rkey); | 699 | buf->key = cpu_to_be32(target->srp_host->dev->mr->rkey); |
685 | buf->len = cpu_to_be32(sg_dma_len(scat)); | 700 | buf->len = cpu_to_be32(sg_dma_len(scat)); |
686 | } else if (srp_map_fmr(target->srp_host->dev, scat, count, req, | 701 | } else if (srp_map_fmr(target, scat, count, req, |
687 | (void *) cmd->add_data)) { | 702 | (void *) cmd->add_data)) { |
688 | /* | 703 | /* |
689 | * FMR mapping failed, and the scatterlist has more | 704 | * FMR mapping failed, and the scatterlist has more |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index a29d5ceb00cf..4bf48188cc91 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -127,14 +127,10 @@ static int evdev_open(struct inode * inode, struct file * file) | |||
127 | { | 127 | { |
128 | struct evdev_list *list; | 128 | struct evdev_list *list; |
129 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 129 | int i = iminor(inode) - EVDEV_MINOR_BASE; |
130 | int accept_err; | ||
131 | 130 | ||
132 | if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) | 131 | if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) |
133 | return -ENODEV; | 132 | return -ENODEV; |
134 | 133 | ||
135 | if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) | ||
136 | return accept_err; | ||
137 | |||
138 | if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) | 134 | if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) |
139 | return -ENOMEM; | 135 | return -ENOMEM; |
140 | 136 | ||
@@ -260,7 +256,7 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_ | |||
260 | 256 | ||
261 | if (evdev_event_from_user(buffer + retval, &event)) | 257 | if (evdev_event_from_user(buffer + retval, &event)) |
262 | return -EFAULT; | 258 | return -EFAULT; |
263 | input_event(list->evdev->handle.dev, event.type, event.code, event.value); | 259 | input_inject_event(&list->evdev->handle, event.type, event.code, event.value); |
264 | retval += evdev_event_size(); | 260 | retval += evdev_event_size(); |
265 | } | 261 | } |
266 | 262 | ||
@@ -428,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
428 | if (get_user(v, ip + 1)) | 424 | if (get_user(v, ip + 1)) |
429 | return -EFAULT; | 425 | return -EFAULT; |
430 | 426 | ||
431 | input_event(dev, EV_REP, REP_DELAY, u); | 427 | input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u); |
432 | input_event(dev, EV_REP, REP_PERIOD, v); | 428 | input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v); |
433 | 429 | ||
434 | return 0; | 430 | return 0; |
435 | 431 | ||
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 47e93daa0fa7..90de5afe03c2 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
@@ -106,10 +106,10 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
106 | gp->gameport = port; | 106 | gp->gameport = port; |
107 | gp->res_port = request_region(port->io, 0x10, "FM801 GP"); | 107 | gp->res_port = request_region(port->io, 0x10, "FM801 GP"); |
108 | if (!gp->res_port) { | 108 | if (!gp->res_port) { |
109 | kfree(gp); | ||
110 | gameport_free_port(port); | ||
111 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", | 109 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", |
112 | port->io, port->io + 0x0f); | 110 | port->io, port->io + 0x0f); |
111 | gameport_free_port(port); | ||
112 | kfree(gp); | ||
113 | return -EBUSY; | 113 | return -EBUSY; |
114 | } | 114 | } |
115 | 115 | ||
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 36644bff379d..3f47ae55c6f3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -53,6 +53,7 @@ static LIST_HEAD(gameport_list); | |||
53 | 53 | ||
54 | static struct bus_type gameport_bus; | 54 | static struct bus_type gameport_bus; |
55 | 55 | ||
56 | static void gameport_add_driver(struct gameport_driver *drv); | ||
56 | static void gameport_add_port(struct gameport *gameport); | 57 | static void gameport_add_port(struct gameport *gameport); |
57 | static void gameport_destroy_port(struct gameport *gameport); | 58 | static void gameport_destroy_port(struct gameport *gameport); |
58 | static void gameport_reconnect_port(struct gameport *gameport); | 59 | static void gameport_reconnect_port(struct gameport *gameport); |
@@ -211,8 +212,14 @@ static void gameport_release_driver(struct gameport *gameport) | |||
211 | 212 | ||
212 | static void gameport_find_driver(struct gameport *gameport) | 213 | static void gameport_find_driver(struct gameport *gameport) |
213 | { | 214 | { |
215 | int error; | ||
216 | |||
214 | down_write(&gameport_bus.subsys.rwsem); | 217 | down_write(&gameport_bus.subsys.rwsem); |
215 | device_attach(&gameport->dev); | 218 | error = device_attach(&gameport->dev); |
219 | if (error < 0) | ||
220 | printk(KERN_WARNING | ||
221 | "gameport: device_attach() failed for %s (%s), error: %d\n", | ||
222 | gameport->phys, gameport->name, error); | ||
216 | up_write(&gameport_bus.subsys.rwsem); | 223 | up_write(&gameport_bus.subsys.rwsem); |
217 | } | 224 | } |
218 | 225 | ||
@@ -316,7 +323,6 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
316 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 323 | spin_unlock_irqrestore(&gameport_event_lock, flags); |
317 | } | 324 | } |
318 | 325 | ||
319 | |||
320 | static struct gameport_event *gameport_get_event(void) | 326 | static struct gameport_event *gameport_get_event(void) |
321 | { | 327 | { |
322 | struct gameport_event *event; | 328 | struct gameport_event *event; |
@@ -342,7 +348,6 @@ static struct gameport_event *gameport_get_event(void) | |||
342 | static void gameport_handle_event(void) | 348 | static void gameport_handle_event(void) |
343 | { | 349 | { |
344 | struct gameport_event *event; | 350 | struct gameport_event *event; |
345 | struct gameport_driver *gameport_drv; | ||
346 | 351 | ||
347 | mutex_lock(&gameport_mutex); | 352 | mutex_lock(&gameport_mutex); |
348 | 353 | ||
@@ -369,8 +374,7 @@ static void gameport_handle_event(void) | |||
369 | break; | 374 | break; |
370 | 375 | ||
371 | case GAMEPORT_REGISTER_DRIVER: | 376 | case GAMEPORT_REGISTER_DRIVER: |
372 | gameport_drv = event->object; | 377 | gameport_add_driver(event->object); |
373 | driver_register(&gameport_drv->driver); | ||
374 | break; | 378 | break; |
375 | 379 | ||
376 | default: | 380 | default: |
@@ -532,6 +536,7 @@ static void gameport_init_port(struct gameport *gameport) | |||
532 | if (gameport->parent) | 536 | if (gameport->parent) |
533 | gameport->dev.parent = &gameport->parent->dev; | 537 | gameport->dev.parent = &gameport->parent->dev; |
534 | 538 | ||
539 | INIT_LIST_HEAD(&gameport->node); | ||
535 | spin_lock_init(&gameport->timer_lock); | 540 | spin_lock_init(&gameport->timer_lock); |
536 | init_timer(&gameport->poll_timer); | 541 | init_timer(&gameport->poll_timer); |
537 | gameport->poll_timer.function = gameport_run_poll_handler; | 542 | gameport->poll_timer.function = gameport_run_poll_handler; |
@@ -544,6 +549,8 @@ static void gameport_init_port(struct gameport *gameport) | |||
544 | */ | 549 | */ |
545 | static void gameport_add_port(struct gameport *gameport) | 550 | static void gameport_add_port(struct gameport *gameport) |
546 | { | 551 | { |
552 | int error; | ||
553 | |||
547 | if (gameport->parent) | 554 | if (gameport->parent) |
548 | gameport->parent->child = gameport; | 555 | gameport->parent->child = gameport; |
549 | 556 | ||
@@ -558,8 +565,13 @@ static void gameport_add_port(struct gameport *gameport) | |||
558 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", | 565 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", |
559 | gameport->name, gameport->phys, gameport->speed); | 566 | gameport->name, gameport->phys, gameport->speed); |
560 | 567 | ||
561 | device_add(&gameport->dev); | 568 | error = device_add(&gameport->dev); |
562 | gameport->registered = 1; | 569 | if (error) |
570 | printk(KERN_ERR | ||
571 | "gameport: device_add() failed for %s (%s), error: %d\n", | ||
572 | gameport->phys, gameport->name, error); | ||
573 | else | ||
574 | gameport->registered = 1; | ||
563 | } | 575 | } |
564 | 576 | ||
565 | /* | 577 | /* |
@@ -583,10 +595,11 @@ static void gameport_destroy_port(struct gameport *gameport) | |||
583 | 595 | ||
584 | if (gameport->registered) { | 596 | if (gameport->registered) { |
585 | device_del(&gameport->dev); | 597 | device_del(&gameport->dev); |
586 | list_del_init(&gameport->node); | ||
587 | gameport->registered = 0; | 598 | gameport->registered = 0; |
588 | } | 599 | } |
589 | 600 | ||
601 | list_del_init(&gameport->node); | ||
602 | |||
590 | gameport_remove_pending_events(gameport); | 603 | gameport_remove_pending_events(gameport); |
591 | put_device(&gameport->dev); | 604 | put_device(&gameport->dev); |
592 | } | 605 | } |
@@ -704,11 +717,22 @@ static int gameport_driver_remove(struct device *dev) | |||
704 | } | 717 | } |
705 | 718 | ||
706 | static struct bus_type gameport_bus = { | 719 | static struct bus_type gameport_bus = { |
707 | .name = "gameport", | 720 | .name = "gameport", |
708 | .probe = gameport_driver_probe, | 721 | .probe = gameport_driver_probe, |
709 | .remove = gameport_driver_remove, | 722 | .remove = gameport_driver_remove, |
710 | }; | 723 | }; |
711 | 724 | ||
725 | static void gameport_add_driver(struct gameport_driver *drv) | ||
726 | { | ||
727 | int error; | ||
728 | |||
729 | error = driver_register(&drv->driver); | ||
730 | if (error) | ||
731 | printk(KERN_ERR | ||
732 | "gameport: driver_register() failed for %s, error: %d\n", | ||
733 | drv->driver.name, error); | ||
734 | } | ||
735 | |||
712 | void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) | 736 | void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) |
713 | { | 737 | { |
714 | drv->driver.bus = &gameport_bus; | 738 | drv->driver.bus = &gameport_bus; |
@@ -778,16 +802,24 @@ void gameport_close(struct gameport *gameport) | |||
778 | 802 | ||
779 | static int __init gameport_init(void) | 803 | static int __init gameport_init(void) |
780 | { | 804 | { |
781 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | 805 | int error; |
782 | if (IS_ERR(gameport_task)) { | ||
783 | printk(KERN_ERR "gameport: Failed to start kgameportd\n"); | ||
784 | return PTR_ERR(gameport_task); | ||
785 | } | ||
786 | 806 | ||
787 | gameport_bus.dev_attrs = gameport_device_attrs; | 807 | gameport_bus.dev_attrs = gameport_device_attrs; |
788 | gameport_bus.drv_attrs = gameport_driver_attrs; | 808 | gameport_bus.drv_attrs = gameport_driver_attrs; |
789 | gameport_bus.match = gameport_bus_match; | 809 | gameport_bus.match = gameport_bus_match; |
790 | bus_register(&gameport_bus); | 810 | error = bus_register(&gameport_bus); |
811 | if (error) { | ||
812 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); | ||
813 | return error; | ||
814 | } | ||
815 | |||
816 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | ||
817 | if (IS_ERR(gameport_task)) { | ||
818 | bus_unregister(&gameport_bus); | ||
819 | error = PTR_ERR(gameport_task); | ||
820 | printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); | ||
821 | return error; | ||
822 | } | ||
791 | 823 | ||
792 | return 0; | 824 | return 0; |
793 | } | 825 | } |
diff --git a/drivers/input/input.c b/drivers/input/input.c index a90486f5e491..9cb4b9a54f01 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list); | |||
35 | 35 | ||
36 | static struct input_handler *input_table[8]; | 36 | static struct input_handler *input_table[8]; |
37 | 37 | ||
38 | /** | ||
39 | * input_event() - report new input event | ||
40 | * @handle: device that generated the event | ||
41 | * @type: type of the event | ||
42 | * @code: event code | ||
43 | * @value: value of the event | ||
44 | * | ||
45 | * This function should be used by drivers implementing various input devices | ||
46 | * See also input_inject_event() | ||
47 | */ | ||
38 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 48 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
39 | { | 49 | { |
40 | struct input_handle *handle; | 50 | struct input_handle *handle; |
@@ -183,6 +193,23 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in | |||
183 | } | 193 | } |
184 | EXPORT_SYMBOL(input_event); | 194 | EXPORT_SYMBOL(input_event); |
185 | 195 | ||
196 | /** | ||
197 | * input_inject_event() - send input event from input handler | ||
198 | * @handle: input handle to send event through | ||
199 | * @type: type of the event | ||
200 | * @code: event code | ||
201 | * @value: value of the event | ||
202 | * | ||
203 | * Similar to input_event() but will ignore event if device is "grabbed" and handle | ||
204 | * injecting event is not the one that owns the device. | ||
205 | */ | ||
206 | void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | ||
207 | { | ||
208 | if (!handle->dev->grab || handle->dev->grab == handle) | ||
209 | input_event(handle->dev, type, code, value); | ||
210 | } | ||
211 | EXPORT_SYMBOL(input_inject_event); | ||
212 | |||
186 | static void input_repeat_key(unsigned long data) | 213 | static void input_repeat_key(unsigned long data) |
187 | { | 214 | { |
188 | struct input_dev *dev = (void *) data; | 215 | struct input_dev *dev = (void *) data; |
@@ -197,15 +224,6 @@ static void input_repeat_key(unsigned long data) | |||
197 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); | 224 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); |
198 | } | 225 | } |
199 | 226 | ||
200 | int input_accept_process(struct input_handle *handle, struct file *file) | ||
201 | { | ||
202 | if (handle->dev->accept) | ||
203 | return handle->dev->accept(handle->dev, file); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | EXPORT_SYMBOL(input_accept_process); | ||
208 | |||
209 | int input_grab_device(struct input_handle *handle) | 227 | int input_grab_device(struct input_handle *handle) |
210 | { | 228 | { |
211 | if (handle->dev->grab) | 229 | if (handle->dev->grab) |
@@ -218,8 +236,15 @@ EXPORT_SYMBOL(input_grab_device); | |||
218 | 236 | ||
219 | void input_release_device(struct input_handle *handle) | 237 | void input_release_device(struct input_handle *handle) |
220 | { | 238 | { |
221 | if (handle->dev->grab == handle) | 239 | struct input_dev *dev = handle->dev; |
222 | handle->dev->grab = NULL; | 240 | |
241 | if (dev->grab == handle) { | ||
242 | dev->grab = NULL; | ||
243 | |||
244 | list_for_each_entry(handle, &dev->h_list, d_node) | ||
245 | if (handle->handler->start) | ||
246 | handle->handler->start(handle); | ||
247 | } | ||
223 | } | 248 | } |
224 | EXPORT_SYMBOL(input_release_device); | 249 | EXPORT_SYMBOL(input_release_device); |
225 | 250 | ||
@@ -963,8 +988,11 @@ int input_register_device(struct input_dev *dev) | |||
963 | list_for_each_entry(handler, &input_handler_list, node) | 988 | list_for_each_entry(handler, &input_handler_list, node) |
964 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 989 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) |
965 | if ((id = input_match_device(handler->id_table, dev))) | 990 | if ((id = input_match_device(handler->id_table, dev))) |
966 | if ((handle = handler->connect(handler, dev, id))) | 991 | if ((handle = handler->connect(handler, dev, id))) { |
967 | input_link_handle(handle); | 992 | input_link_handle(handle); |
993 | if (handler->start) | ||
994 | handler->start(handle); | ||
995 | } | ||
968 | 996 | ||
969 | input_wakeup_procfs_readers(); | 997 | input_wakeup_procfs_readers(); |
970 | 998 | ||
@@ -1028,8 +1056,11 @@ void input_register_handler(struct input_handler *handler) | |||
1028 | list_for_each_entry(dev, &input_dev_list, node) | 1056 | list_for_each_entry(dev, &input_dev_list, node) |
1029 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1057 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) |
1030 | if ((id = input_match_device(handler->id_table, dev))) | 1058 | if ((id = input_match_device(handler->id_table, dev))) |
1031 | if ((handle = handler->connect(handler, dev, id))) | 1059 | if ((handle = handler->connect(handler, dev, id))) { |
1032 | input_link_handle(handle); | 1060 | input_link_handle(handle); |
1061 | if (handler->start) | ||
1062 | handler->start(handle); | ||
1063 | } | ||
1033 | 1064 | ||
1034 | input_wakeup_procfs_readers(); | 1065 | input_wakeup_procfs_readers(); |
1035 | } | 1066 | } |
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 6d99e3c37884..b4914e7231f8 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
@@ -79,6 +79,7 @@ static struct iforce_device iforce_device[] = { | |||
79 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
80 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 80 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
81 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 81 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
82 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | ||
82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 83 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } |
83 | }; | 84 | }; |
84 | 85 | ||
@@ -222,22 +223,22 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id) | |||
222 | int err = 0; | 223 | int err = 0; |
223 | struct iforce_core_effect* core_effect; | 224 | struct iforce_core_effect* core_effect; |
224 | 225 | ||
225 | /* Check who is trying to erase this effect */ | ||
226 | if (iforce->core_effects[effect_id].owner != current->pid) { | ||
227 | printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, iforce->core_effects[effect_id].owner); | ||
228 | return -EACCES; | ||
229 | } | ||
230 | |||
231 | if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX) | 226 | if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX) |
232 | return -EINVAL; | 227 | return -EINVAL; |
233 | 228 | ||
234 | core_effect = iforce->core_effects + effect_id; | 229 | core_effect = &iforce->core_effects[effect_id]; |
230 | |||
231 | /* Check who is trying to erase this effect */ | ||
232 | if (core_effect->owner != current->pid) { | ||
233 | printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner); | ||
234 | return -EACCES; | ||
235 | } | ||
235 | 236 | ||
236 | if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) | 237 | if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) |
237 | err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk)); | 238 | err = release_resource(&core_effect->mod1_chunk); |
238 | 239 | ||
239 | if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) | 240 | if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) |
240 | err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk)); | 241 | err = release_resource(&core_effect->mod2_chunk); |
241 | 242 | ||
242 | /*TODO: remember to change that if more FF_MOD* bits are added */ | 243 | /*TODO: remember to change that if more FF_MOD* bits are added */ |
243 | core_effect->flags[0] = 0; | 244 | core_effect->flags[0] = 0; |
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 75eb5ca59992..7a19ee052972 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); | |||
50 | */ | 50 | */ |
51 | 51 | ||
52 | #define SPACEBALL_MAX_LENGTH 128 | 52 | #define SPACEBALL_MAX_LENGTH 128 |
53 | #define SPACEBALL_MAX_ID 8 | 53 | #define SPACEBALL_MAX_ID 9 |
54 | 54 | ||
55 | #define SPACEBALL_1003 1 | 55 | #define SPACEBALL_1003 1 |
56 | #define SPACEBALL_2003B 3 | 56 | #define SPACEBALL_2003B 3 |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ce1f10e8984b..6bfa0cf4b1d2 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -482,13 +482,7 @@ out: | |||
482 | return IRQ_HANDLED; | 482 | return IRQ_HANDLED; |
483 | } | 483 | } |
484 | 484 | ||
485 | /* | 485 | static int atkbd_set_repeat_rate(struct atkbd *atkbd) |
486 | * atkbd_event_work() is used to complete processing of events that | ||
487 | * can not be processed by input_event() which is often called from | ||
488 | * interrupt context. | ||
489 | */ | ||
490 | |||
491 | static void atkbd_event_work(void *data) | ||
492 | { | 486 | { |
493 | const short period[32] = | 487 | const short period[32] = |
494 | { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, | 488 | { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, |
@@ -496,41 +490,64 @@ static void atkbd_event_work(void *data) | |||
496 | const short delay[4] = | 490 | const short delay[4] = |
497 | { 250, 500, 750, 1000 }; | 491 | { 250, 500, 750, 1000 }; |
498 | 492 | ||
499 | struct atkbd *atkbd = data; | 493 | struct input_dev *dev = atkbd->dev; |
494 | unsigned char param; | ||
495 | int i = 0, j = 0; | ||
496 | |||
497 | while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD]) | ||
498 | i++; | ||
499 | dev->rep[REP_PERIOD] = period[i]; | ||
500 | |||
501 | while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY]) | ||
502 | j++; | ||
503 | dev->rep[REP_DELAY] = delay[j]; | ||
504 | |||
505 | param = i | (j << 5); | ||
506 | return ps2_command(&atkbd->ps2dev, ¶m, ATKBD_CMD_SETREP); | ||
507 | } | ||
508 | |||
509 | static int atkbd_set_leds(struct atkbd *atkbd) | ||
510 | { | ||
500 | struct input_dev *dev = atkbd->dev; | 511 | struct input_dev *dev = atkbd->dev; |
501 | unsigned char param[2]; | 512 | unsigned char param[2]; |
502 | int i, j; | ||
503 | 513 | ||
504 | mutex_lock(&atkbd->event_mutex); | 514 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) |
515 | | (test_bit(LED_NUML, dev->led) ? 2 : 0) | ||
516 | | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); | ||
517 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) | ||
518 | return -1; | ||
505 | 519 | ||
506 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { | 520 | if (atkbd->extra) { |
507 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | 521 | param[0] = 0; |
508 | | (test_bit(LED_NUML, dev->led) ? 2 : 0) | 522 | param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0) |
509 | | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); | 523 | | (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0) |
510 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS); | 524 | | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) |
511 | 525 | | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | |
512 | if (atkbd->extra) { | 526 | | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); |
513 | param[0] = 0; | 527 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS)) |
514 | param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0) | 528 | return -1; |
515 | | (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0) | ||
516 | | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | ||
517 | | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | ||
518 | | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); | ||
519 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS); | ||
520 | } | ||
521 | } | 529 | } |
522 | 530 | ||
523 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) { | 531 | return 0; |
524 | i = j = 0; | 532 | } |
525 | while (i < 31 && period[i] < dev->rep[REP_PERIOD]) | 533 | |
526 | i++; | 534 | /* |
527 | while (j < 3 && delay[j] < dev->rep[REP_DELAY]) | 535 | * atkbd_event_work() is used to complete processing of events that |
528 | j++; | 536 | * can not be processed by input_event() which is often called from |
529 | dev->rep[REP_PERIOD] = period[i]; | 537 | * interrupt context. |
530 | dev->rep[REP_DELAY] = delay[j]; | 538 | */ |
531 | param[0] = i | (j << 5); | 539 | |
532 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); | 540 | static void atkbd_event_work(void *data) |
533 | } | 541 | { |
542 | struct atkbd *atkbd = data; | ||
543 | |||
544 | mutex_lock(&atkbd->event_mutex); | ||
545 | |||
546 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) | ||
547 | atkbd_set_leds(atkbd); | ||
548 | |||
549 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) | ||
550 | atkbd_set_repeat_rate(atkbd); | ||
534 | 551 | ||
535 | mutex_unlock(&atkbd->event_mutex); | 552 | mutex_unlock(&atkbd->event_mutex); |
536 | } | 553 | } |
@@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
975 | { | 992 | { |
976 | struct atkbd *atkbd = serio_get_drvdata(serio); | 993 | struct atkbd *atkbd = serio_get_drvdata(serio); |
977 | struct serio_driver *drv = serio->drv; | 994 | struct serio_driver *drv = serio->drv; |
978 | unsigned char param[1]; | ||
979 | 995 | ||
980 | if (!atkbd || !drv) { | 996 | if (!atkbd || !drv) { |
981 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 997 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); |
@@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
985 | atkbd_disable(atkbd); | 1001 | atkbd_disable(atkbd); |
986 | 1002 | ||
987 | if (atkbd->write) { | 1003 | if (atkbd->write) { |
988 | param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0) | ||
989 | | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0) | ||
990 | | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0); | ||
991 | |||
992 | if (atkbd_probe(atkbd)) | 1004 | if (atkbd_probe(atkbd)) |
993 | return -1; | 1005 | return -1; |
994 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1006 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) |
@@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio) | |||
996 | 1008 | ||
997 | atkbd_activate(atkbd); | 1009 | atkbd_activate(atkbd); |
998 | 1010 | ||
999 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) | 1011 | /* |
1000 | return -1; | 1012 | * Restore repeat rate and LEDs (that were reset by atkbd_activate) |
1013 | * to pre-resume state | ||
1014 | */ | ||
1015 | if (!atkbd->softrepeat) | ||
1016 | atkbd_set_repeat_rate(atkbd); | ||
1017 | atkbd_set_leds(atkbd); | ||
1001 | } | 1018 | } |
1002 | 1019 | ||
1003 | atkbd_enable(atkbd); | 1020 | atkbd_enable(atkbd); |
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index ccf0faeee5c1..a8efc1af36cb 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -94,7 +94,7 @@ static void call_bios(struct regs *regs) | |||
94 | 94 | ||
95 | static ssize_t __init locate_wistron_bios(void __iomem *base) | 95 | static ssize_t __init locate_wistron_bios(void __iomem *base) |
96 | { | 96 | { |
97 | static const unsigned char __initdata signature[] = | 97 | static unsigned char __initdata signature[] = |
98 | { 0x42, 0x21, 0x55, 0x30 }; | 98 | { 0x42, 0x21, 0x55, 0x30 }; |
99 | ssize_t offset; | 99 | ssize_t offset; |
100 | 100 | ||
@@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi) | |||
259 | return 1; | 259 | return 1; |
260 | } | 260 | } |
261 | 261 | ||
262 | static struct key_entry keymap_empty[] = { | 262 | static struct key_entry keymap_empty[] __initdata = { |
263 | { KE_END, 0 } | 263 | { KE_END, 0 } |
264 | }; | 264 | }; |
265 | 265 | ||
266 | static struct key_entry keymap_fs_amilo_pro_v2000[] = { | 266 | static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { |
267 | { KE_KEY, 0x01, KEY_HELP }, | 267 | { KE_KEY, 0x01, KEY_HELP }, |
268 | { KE_KEY, 0x11, KEY_PROG1 }, | 268 | { KE_KEY, 0x11, KEY_PROG1 }, |
269 | { KE_KEY, 0x12, KEY_PROG2 }, | 269 | { KE_KEY, 0x12, KEY_PROG2 }, |
@@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { | |||
273 | { KE_END, 0 } | 273 | { KE_END, 0 } |
274 | }; | 274 | }; |
275 | 275 | ||
276 | static struct key_entry keymap_fujitsu_n3510[] = { | 276 | static struct key_entry keymap_fujitsu_n3510[] __initdata = { |
277 | { KE_KEY, 0x11, KEY_PROG1 }, | 277 | { KE_KEY, 0x11, KEY_PROG1 }, |
278 | { KE_KEY, 0x12, KEY_PROG2 }, | 278 | { KE_KEY, 0x12, KEY_PROG2 }, |
279 | { KE_KEY, 0x36, KEY_WWW }, | 279 | { KE_KEY, 0x36, KEY_WWW }, |
@@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] = { | |||
285 | { KE_END, 0 } | 285 | { KE_END, 0 } |
286 | }; | 286 | }; |
287 | 287 | ||
288 | static struct key_entry keymap_wistron_ms2111[] = { | 288 | static struct key_entry keymap_wistron_ms2111[] __initdata = { |
289 | { KE_KEY, 0x11, KEY_PROG1 }, | 289 | { KE_KEY, 0x11, KEY_PROG1 }, |
290 | { KE_KEY, 0x12, KEY_PROG2 }, | 290 | { KE_KEY, 0x12, KEY_PROG2 }, |
291 | { KE_KEY, 0x13, KEY_PROG3 }, | 291 | { KE_KEY, 0x13, KEY_PROG3 }, |
@@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] = { | |||
294 | { KE_END, 0 } | 294 | { KE_END, 0 } |
295 | }; | 295 | }; |
296 | 296 | ||
297 | static struct key_entry keymap_wistron_ms2141[] = { | 297 | static struct key_entry keymap_wistron_ms2141[] __initdata = { |
298 | { KE_KEY, 0x11, KEY_PROG1 }, | 298 | { KE_KEY, 0x11, KEY_PROG1 }, |
299 | { KE_KEY, 0x12, KEY_PROG2 }, | 299 | { KE_KEY, 0x12, KEY_PROG2 }, |
300 | { KE_WIFI, 0x30, 0 }, | 300 | { KE_WIFI, 0x30, 0 }, |
@@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] = { | |||
307 | { KE_END, 0 } | 307 | { KE_END, 0 } |
308 | }; | 308 | }; |
309 | 309 | ||
310 | static struct key_entry keymap_acer_aspire_1500[] = { | 310 | static struct key_entry keymap_acer_aspire_1500[] __initdata = { |
311 | { KE_KEY, 0x11, KEY_PROG1 }, | 311 | { KE_KEY, 0x11, KEY_PROG1 }, |
312 | { KE_KEY, 0x12, KEY_PROG2 }, | 312 | { KE_KEY, 0x12, KEY_PROG2 }, |
313 | { KE_WIFI, 0x30, 0 }, | 313 | { KE_WIFI, 0x30, 0 }, |
@@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] = { | |||
317 | { KE_END, 0 } | 317 | { KE_END, 0 } |
318 | }; | 318 | }; |
319 | 319 | ||
320 | static struct key_entry keymap_acer_travelmate_240[] = { | 320 | static struct key_entry keymap_acer_travelmate_240[] __initdata = { |
321 | { KE_KEY, 0x31, KEY_MAIL }, | 321 | { KE_KEY, 0x31, KEY_MAIL }, |
322 | { KE_KEY, 0x36, KEY_WWW }, | 322 | { KE_KEY, 0x36, KEY_WWW }, |
323 | { KE_KEY, 0x11, KEY_PROG1 }, | 323 | { KE_KEY, 0x11, KEY_PROG1 }, |
@@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] = { | |||
327 | { KE_END, 0 } | 327 | { KE_END, 0 } |
328 | }; | 328 | }; |
329 | 329 | ||
330 | static struct key_entry keymap_aopen_1559as[] = { | 330 | static struct key_entry keymap_aopen_1559as[] __initdata = { |
331 | { KE_KEY, 0x01, KEY_HELP }, | 331 | { KE_KEY, 0x01, KEY_HELP }, |
332 | { KE_KEY, 0x06, KEY_PROG3 }, | 332 | { KE_KEY, 0x06, KEY_PROG3 }, |
333 | { KE_KEY, 0x11, KEY_PROG1 }, | 333 | { KE_KEY, 0x11, KEY_PROG1 }, |
@@ -343,7 +343,7 @@ static struct key_entry keymap_aopen_1559as[] = { | |||
343 | * a list of buttons and their key codes (reported when loading this module | 343 | * a list of buttons and their key codes (reported when loading this module |
344 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. | 344 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. |
345 | */ | 345 | */ |
346 | static struct dmi_system_id dmi_ids[] = { | 346 | static struct dmi_system_id dmi_ids[] __initdata = { |
347 | { | 347 | { |
348 | .callback = dmi_matched, | 348 | .callback = dmi_matched, |
349 | .ident = "Fujitsu-Siemens Amilo Pro V2000", | 349 | .ident = "Fujitsu-Siemens Amilo Pro V2000", |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 2f0d28840810..54b696cfe1e3 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -238,8 +238,7 @@ static struct ps2pp_info *get_model_info(unsigned char model) | |||
238 | { 100, PS2PP_KIND_MX, /* MX510 */ | 238 | { 100, PS2PP_KIND_MX, /* MX510 */ |
239 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 239 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | |
240 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 240 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, |
241 | { 111, PS2PP_KIND_MX, /* MX300 */ | 241 | { 111, PS2PP_KIND_MX, PS2PP_WHEEL | PS2PP_SIDE_BTN }, /* MX300 reports task button as side */ |
242 | PS2PP_WHEEL | PS2PP_EXTRA_BTN | PS2PP_TASK_BTN }, | ||
243 | { 112, PS2PP_KIND_MX, /* MX500 */ | 242 | { 112, PS2PP_KIND_MX, /* MX500 */ |
244 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 243 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | |
245 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 244 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 6d9ec9ab1b90..ae5871a0e060 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -183,21 +183,26 @@ static struct attribute_group trackpoint_attr_group = { | |||
183 | .attrs = trackpoint_attrs, | 183 | .attrs = trackpoint_attrs, |
184 | }; | 184 | }; |
185 | 185 | ||
186 | static void trackpoint_disconnect(struct psmouse *psmouse) | 186 | static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id) |
187 | { | 187 | { |
188 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | 188 | unsigned char param[2] = { 0 }; |
189 | 189 | ||
190 | kfree(psmouse->private); | 190 | if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) |
191 | psmouse->private = NULL; | 191 | return -1; |
192 | |||
193 | if (param[0] != TP_MAGIC_IDENT) | ||
194 | return -1; | ||
195 | |||
196 | if (firmware_id) | ||
197 | *firmware_id = param[1]; | ||
198 | |||
199 | return 0; | ||
192 | } | 200 | } |
193 | 201 | ||
194 | static int trackpoint_sync(struct psmouse *psmouse) | 202 | static int trackpoint_sync(struct psmouse *psmouse) |
195 | { | 203 | { |
196 | unsigned char toggle; | ||
197 | struct trackpoint_data *tp = psmouse->private; | 204 | struct trackpoint_data *tp = psmouse->private; |
198 | 205 | unsigned char toggle; | |
199 | if (!tp) | ||
200 | return -1; | ||
201 | 206 | ||
202 | /* Disable features that may make device unusable with this driver */ | 207 | /* Disable features that may make device unusable with this driver */ |
203 | trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle); | 208 | trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle); |
@@ -263,27 +268,38 @@ static void trackpoint_defaults(struct trackpoint_data *tp) | |||
263 | tp->ext_dev = TP_DEF_EXT_DEV; | 268 | tp->ext_dev = TP_DEF_EXT_DEV; |
264 | } | 269 | } |
265 | 270 | ||
271 | static void trackpoint_disconnect(struct psmouse *psmouse) | ||
272 | { | ||
273 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | ||
274 | |||
275 | kfree(psmouse->private); | ||
276 | psmouse->private = NULL; | ||
277 | } | ||
278 | |||
279 | static int trackpoint_reconnect(struct psmouse *psmouse) | ||
280 | { | ||
281 | if (trackpoint_start_protocol(psmouse, NULL)) | ||
282 | return -1; | ||
283 | |||
284 | if (trackpoint_sync(psmouse)) | ||
285 | return -1; | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
266 | int trackpoint_detect(struct psmouse *psmouse, int set_properties) | 290 | int trackpoint_detect(struct psmouse *psmouse, int set_properties) |
267 | { | 291 | { |
268 | struct trackpoint_data *priv; | 292 | struct trackpoint_data *priv; |
269 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 293 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
270 | unsigned char firmware_id; | 294 | unsigned char firmware_id; |
271 | unsigned char button_info; | 295 | unsigned char button_info; |
272 | unsigned char param[2]; | ||
273 | |||
274 | param[0] = param[1] = 0; | ||
275 | 296 | ||
276 | if (ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) | 297 | if (trackpoint_start_protocol(psmouse, &firmware_id)) |
277 | return -1; | ||
278 | |||
279 | if (param[0] != TP_MAGIC_IDENT) | ||
280 | return -1; | 298 | return -1; |
281 | 299 | ||
282 | if (!set_properties) | 300 | if (!set_properties) |
283 | return 0; | 301 | return 0; |
284 | 302 | ||
285 | firmware_id = param[1]; | ||
286 | |||
287 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { | 303 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { |
288 | printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); | 304 | printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); |
289 | button_info = 0; | 305 | button_info = 0; |
@@ -296,7 +312,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) | |||
296 | psmouse->vendor = "IBM"; | 312 | psmouse->vendor = "IBM"; |
297 | psmouse->name = "TrackPoint"; | 313 | psmouse->name = "TrackPoint"; |
298 | 314 | ||
299 | psmouse->reconnect = trackpoint_sync; | 315 | psmouse->reconnect = trackpoint_reconnect; |
300 | psmouse->disconnect = trackpoint_disconnect; | 316 | psmouse->disconnect = trackpoint_disconnect; |
301 | 317 | ||
302 | trackpoint_defaults(priv); | 318 | trackpoint_defaults(priv); |
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 61a6f977846f..ed202f2f251a 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -177,6 +177,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
177 | return -1; | 177 | return -1; |
178 | } | 178 | } |
179 | 179 | ||
180 | if (send && !param) { | ||
181 | WARN_ON(1); | ||
182 | return -1; | ||
183 | } | ||
184 | |||
180 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); | 185 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); |
181 | 186 | ||
182 | serio_pause_rx(ps2dev->serio); | 187 | serio_pause_rx(ps2dev->serio); |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 6521034bc933..3e76ad71c9a0 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -62,6 +62,7 @@ static LIST_HEAD(serio_list); | |||
62 | 62 | ||
63 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; |
64 | 64 | ||
65 | static void serio_add_driver(struct serio_driver *drv); | ||
65 | static void serio_add_port(struct serio *serio); | 66 | static void serio_add_port(struct serio *serio); |
66 | static void serio_destroy_port(struct serio *serio); | 67 | static void serio_destroy_port(struct serio *serio); |
67 | static void serio_reconnect_port(struct serio *serio); | 68 | static void serio_reconnect_port(struct serio *serio); |
@@ -140,8 +141,14 @@ static void serio_release_driver(struct serio *serio) | |||
140 | 141 | ||
141 | static void serio_find_driver(struct serio *serio) | 142 | static void serio_find_driver(struct serio *serio) |
142 | { | 143 | { |
144 | int error; | ||
145 | |||
143 | down_write(&serio_bus.subsys.rwsem); | 146 | down_write(&serio_bus.subsys.rwsem); |
144 | device_attach(&serio->dev); | 147 | error = device_attach(&serio->dev); |
148 | if (error < 0) | ||
149 | printk(KERN_WARNING | ||
150 | "serio: device_attach() failed for %s (%s), error: %d\n", | ||
151 | serio->phys, serio->name, error); | ||
145 | up_write(&serio_bus.subsys.rwsem); | 152 | up_write(&serio_bus.subsys.rwsem); |
146 | } | 153 | } |
147 | 154 | ||
@@ -272,7 +279,6 @@ static struct serio_event *serio_get_event(void) | |||
272 | static void serio_handle_event(void) | 279 | static void serio_handle_event(void) |
273 | { | 280 | { |
274 | struct serio_event *event; | 281 | struct serio_event *event; |
275 | struct serio_driver *serio_drv; | ||
276 | 282 | ||
277 | mutex_lock(&serio_mutex); | 283 | mutex_lock(&serio_mutex); |
278 | 284 | ||
@@ -304,8 +310,7 @@ static void serio_handle_event(void) | |||
304 | break; | 310 | break; |
305 | 311 | ||
306 | case SERIO_REGISTER_DRIVER: | 312 | case SERIO_REGISTER_DRIVER: |
307 | serio_drv = event->object; | 313 | serio_add_driver(event->object); |
308 | driver_register(&serio_drv->driver); | ||
309 | break; | 314 | break; |
310 | 315 | ||
311 | default: | 316 | default: |
@@ -525,6 +530,7 @@ static void serio_init_port(struct serio *serio) | |||
525 | 530 | ||
526 | __module_get(THIS_MODULE); | 531 | __module_get(THIS_MODULE); |
527 | 532 | ||
533 | INIT_LIST_HEAD(&serio->node); | ||
528 | spin_lock_init(&serio->lock); | 534 | spin_lock_init(&serio->lock); |
529 | mutex_init(&serio->drv_mutex); | 535 | mutex_init(&serio->drv_mutex); |
530 | device_initialize(&serio->dev); | 536 | device_initialize(&serio->dev); |
@@ -542,6 +548,8 @@ static void serio_init_port(struct serio *serio) | |||
542 | */ | 548 | */ |
543 | static void serio_add_port(struct serio *serio) | 549 | static void serio_add_port(struct serio *serio) |
544 | { | 550 | { |
551 | int error; | ||
552 | |||
545 | if (serio->parent) { | 553 | if (serio->parent) { |
546 | serio_pause_rx(serio->parent); | 554 | serio_pause_rx(serio->parent); |
547 | serio->parent->child = serio; | 555 | serio->parent->child = serio; |
@@ -551,9 +559,19 @@ static void serio_add_port(struct serio *serio) | |||
551 | list_add_tail(&serio->node, &serio_list); | 559 | list_add_tail(&serio->node, &serio_list); |
552 | if (serio->start) | 560 | if (serio->start) |
553 | serio->start(serio); | 561 | serio->start(serio); |
554 | device_add(&serio->dev); | 562 | error = device_add(&serio->dev); |
555 | sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | 563 | if (error) |
556 | serio->registered = 1; | 564 | printk(KERN_ERR |
565 | "serio: device_add() failed for %s (%s), error: %d\n", | ||
566 | serio->phys, serio->name, error); | ||
567 | else { | ||
568 | serio->registered = 1; | ||
569 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
570 | if (error) | ||
571 | printk(KERN_ERR | ||
572 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
573 | serio->phys, serio->name, error); | ||
574 | } | ||
557 | } | 575 | } |
558 | 576 | ||
559 | /* | 577 | /* |
@@ -583,10 +601,10 @@ static void serio_destroy_port(struct serio *serio) | |||
583 | if (serio->registered) { | 601 | if (serio->registered) { |
584 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | 602 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); |
585 | device_del(&serio->dev); | 603 | device_del(&serio->dev); |
586 | list_del_init(&serio->node); | ||
587 | serio->registered = 0; | 604 | serio->registered = 0; |
588 | } | 605 | } |
589 | 606 | ||
607 | list_del_init(&serio->node); | ||
590 | serio_remove_pending_events(serio); | 608 | serio_remove_pending_events(serio); |
591 | put_device(&serio->dev); | 609 | put_device(&serio->dev); |
592 | } | 610 | } |
@@ -756,6 +774,17 @@ static struct bus_type serio_bus = { | |||
756 | .remove = serio_driver_remove, | 774 | .remove = serio_driver_remove, |
757 | }; | 775 | }; |
758 | 776 | ||
777 | static void serio_add_driver(struct serio_driver *drv) | ||
778 | { | ||
779 | int error; | ||
780 | |||
781 | error = driver_register(&drv->driver); | ||
782 | if (error) | ||
783 | printk(KERN_ERR | ||
784 | "serio: driver_register() failed for %s, error: %d\n", | ||
785 | drv->driver.name, error); | ||
786 | } | ||
787 | |||
759 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 788 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) |
760 | { | 789 | { |
761 | drv->driver.bus = &serio_bus; | 790 | drv->driver.bus = &serio_bus; |
@@ -903,18 +932,26 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
903 | 932 | ||
904 | static int __init serio_init(void) | 933 | static int __init serio_init(void) |
905 | { | 934 | { |
906 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | 935 | int error; |
907 | if (IS_ERR(serio_task)) { | ||
908 | printk(KERN_ERR "serio: Failed to start kseriod\n"); | ||
909 | return PTR_ERR(serio_task); | ||
910 | } | ||
911 | 936 | ||
912 | serio_bus.dev_attrs = serio_device_attrs; | 937 | serio_bus.dev_attrs = serio_device_attrs; |
913 | serio_bus.drv_attrs = serio_driver_attrs; | 938 | serio_bus.drv_attrs = serio_driver_attrs; |
914 | serio_bus.match = serio_bus_match; | 939 | serio_bus.match = serio_bus_match; |
915 | serio_bus.uevent = serio_uevent; | 940 | serio_bus.uevent = serio_uevent; |
916 | serio_bus.resume = serio_resume; | 941 | serio_bus.resume = serio_resume; |
917 | bus_register(&serio_bus); | 942 | error = bus_register(&serio_bus); |
943 | if (error) { | ||
944 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | ||
945 | return error; | ||
946 | } | ||
947 | |||
948 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | ||
949 | if (IS_ERR(serio_task)) { | ||
950 | bus_unregister(&serio_bus); | ||
951 | error = PTR_ERR(serio_task); | ||
952 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | ||
953 | return error; | ||
954 | } | ||
918 | 955 | ||
919 | return 0; | 956 | return 0; |
920 | } | 957 | } |
diff --git a/drivers/isdn/hardware/eicon/divasync.h b/drivers/isdn/hardware/eicon/divasync.h index 0a5be7f969f2..af3eb9e795b5 100644 --- a/drivers/isdn/hardware/eicon/divasync.h +++ b/drivers/isdn/hardware/eicon/divasync.h | |||
@@ -256,7 +256,6 @@ typedef struct | |||
256 | #define NO_ORDER_CHECK_MASK 0x00000010 | 256 | #define NO_ORDER_CHECK_MASK 0x00000010 |
257 | #define LOW_CHANNEL_MASK 0x00000020 | 257 | #define LOW_CHANNEL_MASK 0x00000020 |
258 | #define NO_HSCX30_MASK 0x00000040 | 258 | #define NO_HSCX30_MASK 0x00000040 |
259 | #define MODE_MASK 0x00000080 | ||
260 | #define SET_BOARD 0x00001000 | 259 | #define SET_BOARD 0x00001000 |
261 | #define SET_CRC4 0x00030000 | 260 | #define SET_CRC4 0x00030000 |
262 | #define SET_L1_TRISTATE 0x00040000 | 261 | #define SET_L1_TRISTATE 0x00040000 |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index f5fe7fb4b3ad..d5d649f5ccdb 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -90,6 +90,15 @@ config ADB_PMU_LED | |||
90 | and the ide-disk LED trigger and configure appropriately through | 90 | and the ide-disk LED trigger and configure appropriately through |
91 | sysfs. | 91 | sysfs. |
92 | 92 | ||
93 | config ADB_PMU_LED_IDE | ||
94 | bool "Use front LED as IDE LED by default" | ||
95 | depends on ADB_PMU_LED | ||
96 | select LEDS_TRIGGERS | ||
97 | select LEDS_TRIGGER_IDE_DISK | ||
98 | help | ||
99 | This option makes the front LED default to the IDE trigger | ||
100 | so that it blinks on IDE activity. | ||
101 | |||
93 | config PMAC_SMU | 102 | config PMAC_SMU |
94 | bool "Support for SMU based PowerMacs" | 103 | bool "Support for SMU based PowerMacs" |
95 | depends on PPC_PMAC64 | 104 | depends on PPC_PMAC64 |
@@ -100,7 +109,7 @@ config PMAC_SMU | |||
100 | 109 | ||
101 | config PMAC_APM_EMU | 110 | config PMAC_APM_EMU |
102 | tristate "APM emulation" | 111 | tristate "APM emulation" |
103 | depends on PPC_PMAC && PPC32 && PM | 112 | depends on PPC_PMAC && PPC32 && PM && ADB_PMU |
104 | 113 | ||
105 | config PMAC_MEDIABAY | 114 | config PMAC_MEDIABAY |
106 | bool "Support PowerBook hotswap media bay" | 115 | bool "Support PowerBook hotswap media bay" |
@@ -115,8 +124,6 @@ config PMAC_BACKLIGHT | |||
115 | bool "Backlight control for LCD screens" | 124 | bool "Backlight control for LCD screens" |
116 | depends on ADB_PMU && FB = y && (BROKEN || !PPC64) | 125 | depends on ADB_PMU && FB = y && (BROKEN || !PPC64) |
117 | select FB_BACKLIGHT | 126 | select FB_BACKLIGHT |
118 | select BACKLIGHT_CLASS_DEVICE | ||
119 | select BACKLIGHT_LCD_SUPPORT | ||
120 | help | 127 | help |
121 | Say Y here to enable Macintosh specific extensions of the generic | 128 | Say Y here to enable Macintosh specific extensions of the generic |
122 | backlight code. With this enabled, the brightness keys on older | 129 | backlight code. With this enabled, the brightness keys on older |
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 545be1ed6927..c69d23bb255e 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c | |||
@@ -45,14 +45,11 @@ | |||
45 | #include <linux/pmu.h> | 45 | #include <linux/pmu.h> |
46 | 46 | ||
47 | #include <asm/machdep.h> | 47 | #include <asm/machdep.h> |
48 | #include <asm/backlight.h> | ||
48 | #ifdef CONFIG_PPC_PMAC | 49 | #ifdef CONFIG_PPC_PMAC |
49 | #include <asm/pmac_feature.h> | 50 | #include <asm/pmac_feature.h> |
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
53 | #include <asm/backlight.h> | ||
54 | #endif | ||
55 | |||
56 | MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>"); | 53 | MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>"); |
57 | 54 | ||
58 | #define KEYB_KEYREG 0 /* register # for key up/down data */ | 55 | #define KEYB_KEYREG 0 /* register # for key up/down data */ |
@@ -237,11 +234,6 @@ static struct adb_ids keyboard_ids; | |||
237 | static struct adb_ids mouse_ids; | 234 | static struct adb_ids mouse_ids; |
238 | static struct adb_ids buttons_ids; | 235 | static struct adb_ids buttons_ids; |
239 | 236 | ||
240 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
241 | /* Exported to via-pmu.c */ | ||
242 | int disable_kernel_backlight = 0; | ||
243 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
244 | |||
245 | /* Kind of keyboard, see Apple technote 1152 */ | 237 | /* Kind of keyboard, see Apple technote 1152 */ |
246 | #define ADB_KEYBOARD_UNKNOWN 0 | 238 | #define ADB_KEYBOARD_UNKNOWN 0 |
247 | #define ADB_KEYBOARD_ANSI 0x0100 | 239 | #define ADB_KEYBOARD_ANSI 0x0100 |
@@ -527,7 +519,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto | |||
527 | 519 | ||
528 | case 0xa: /* brightness decrease */ | 520 | case 0xa: /* brightness decrease */ |
529 | #ifdef CONFIG_PMAC_BACKLIGHT | 521 | #ifdef CONFIG_PMAC_BACKLIGHT |
530 | if (!disable_kernel_backlight && down) | 522 | if (down) |
531 | pmac_backlight_key_down(); | 523 | pmac_backlight_key_down(); |
532 | #endif | 524 | #endif |
533 | input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); | 525 | input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); |
@@ -535,7 +527,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto | |||
535 | 527 | ||
536 | case 0x9: /* brightness increase */ | 528 | case 0x9: /* brightness increase */ |
537 | #ifdef CONFIG_PMAC_BACKLIGHT | 529 | #ifdef CONFIG_PMAC_BACKLIGHT |
538 | if (!disable_kernel_backlight && down) | 530 | if (down) |
539 | pmac_backlight_key_up(); | 531 | pmac_backlight_key_up(); |
540 | #endif | 532 | #endif |
541 | input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); | 533 | input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index c1fe0b368f76..20bf67244e2c 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -95,6 +95,17 @@ | |||
95 | * - Use min/max macros here or there | 95 | * - Use min/max macros here or there |
96 | * - Latest darwin updated U3H min fan speed to 20% PWM | 96 | * - Latest darwin updated U3H min fan speed to 20% PWM |
97 | * | 97 | * |
98 | * July. 06, 2006 : 1.3 | ||
99 | * - Fix setting of RPM fans on Xserve G5 (they were going too fast) | ||
100 | * - Add missing slots fan control loop for Xserve G5 | ||
101 | * - Lower fixed slots fan speed from 50% to 40% on desktop G5s. We | ||
102 | * still can't properly implement the control loop for these, so let's | ||
103 | * reduce the noise a little bit, it appears that 40% still gives us | ||
104 | * a pretty good air flow | ||
105 | * - Add code to "tickle" the FCU regulary so it doesn't think that | ||
106 | * we are gone while in fact, the machine just didn't need any fan | ||
107 | * speed change lately | ||
108 | * | ||
98 | */ | 109 | */ |
99 | 110 | ||
100 | #include <linux/types.h> | 111 | #include <linux/types.h> |
@@ -121,7 +132,7 @@ | |||
121 | 132 | ||
122 | #include "therm_pm72.h" | 133 | #include "therm_pm72.h" |
123 | 134 | ||
124 | #define VERSION "1.2b2" | 135 | #define VERSION "1.3" |
125 | 136 | ||
126 | #undef DEBUG | 137 | #undef DEBUG |
127 | 138 | ||
@@ -146,6 +157,7 @@ static struct basckside_pid_params backside_params; | |||
146 | static struct backside_pid_state backside_state; | 157 | static struct backside_pid_state backside_state; |
147 | static struct drives_pid_state drives_state; | 158 | static struct drives_pid_state drives_state; |
148 | static struct dimm_pid_state dimms_state; | 159 | static struct dimm_pid_state dimms_state; |
160 | static struct slots_pid_state slots_state; | ||
149 | static int state; | 161 | static int state; |
150 | static int cpu_count; | 162 | static int cpu_count; |
151 | static int cpu_pid_type; | 163 | static int cpu_pid_type; |
@@ -154,7 +166,8 @@ static struct completion ctrl_complete; | |||
154 | static int critical_state; | 166 | static int critical_state; |
155 | static int rackmac; | 167 | static int rackmac; |
156 | static s32 dimm_output_clamp; | 168 | static s32 dimm_output_clamp; |
157 | 169 | static int fcu_rpm_shift; | |
170 | static int fcu_tickle_ticks; | ||
158 | static DECLARE_MUTEX(driver_lock); | 171 | static DECLARE_MUTEX(driver_lock); |
159 | 172 | ||
160 | /* | 173 | /* |
@@ -495,13 +508,20 @@ static int start_fcu(void) | |||
495 | rc = fan_write_reg(0x2e, &buf, 1); | 508 | rc = fan_write_reg(0x2e, &buf, 1); |
496 | if (rc < 0) | 509 | if (rc < 0) |
497 | return -EIO; | 510 | return -EIO; |
511 | rc = fan_read_reg(0, &buf, 1); | ||
512 | if (rc < 0) | ||
513 | return -EIO; | ||
514 | fcu_rpm_shift = (buf == 1) ? 2 : 3; | ||
515 | printk(KERN_DEBUG "FCU Initialized, RPM fan shift is %d\n", | ||
516 | fcu_rpm_shift); | ||
517 | |||
498 | return 0; | 518 | return 0; |
499 | } | 519 | } |
500 | 520 | ||
501 | static int set_rpm_fan(int fan_index, int rpm) | 521 | static int set_rpm_fan(int fan_index, int rpm) |
502 | { | 522 | { |
503 | unsigned char buf[2]; | 523 | unsigned char buf[2]; |
504 | int rc, id; | 524 | int rc, id, min, max; |
505 | 525 | ||
506 | if (fcu_fans[fan_index].type != FCU_FAN_RPM) | 526 | if (fcu_fans[fan_index].type != FCU_FAN_RPM) |
507 | return -EINVAL; | 527 | return -EINVAL; |
@@ -509,12 +529,15 @@ static int set_rpm_fan(int fan_index, int rpm) | |||
509 | if (id == FCU_FAN_ABSENT_ID) | 529 | if (id == FCU_FAN_ABSENT_ID) |
510 | return -EINVAL; | 530 | return -EINVAL; |
511 | 531 | ||
512 | if (rpm < 300) | 532 | min = 2400 >> fcu_rpm_shift; |
513 | rpm = 300; | 533 | max = 56000 >> fcu_rpm_shift; |
514 | else if (rpm > 8191) | 534 | |
515 | rpm = 8191; | 535 | if (rpm < min) |
516 | buf[0] = rpm >> 5; | 536 | rpm = min; |
517 | buf[1] = rpm << 3; | 537 | else if (rpm > max) |
538 | rpm = max; | ||
539 | buf[0] = rpm >> (8 - fcu_rpm_shift); | ||
540 | buf[1] = rpm << fcu_rpm_shift; | ||
518 | rc = fan_write_reg(0x10 + (id * 2), buf, 2); | 541 | rc = fan_write_reg(0x10 + (id * 2), buf, 2); |
519 | if (rc < 0) | 542 | if (rc < 0) |
520 | return -EIO; | 543 | return -EIO; |
@@ -551,7 +574,7 @@ static int get_rpm_fan(int fan_index, int programmed) | |||
551 | if (rc != 2) | 574 | if (rc != 2) |
552 | return -EIO; | 575 | return -EIO; |
553 | 576 | ||
554 | return (buf[0] << 5) | buf[1] >> 3; | 577 | return (buf[0] << (8 - fcu_rpm_shift)) | buf[1] >> fcu_rpm_shift; |
555 | } | 578 | } |
556 | 579 | ||
557 | static int set_pwm_fan(int fan_index, int pwm) | 580 | static int set_pwm_fan(int fan_index, int pwm) |
@@ -609,6 +632,26 @@ static int get_pwm_fan(int fan_index) | |||
609 | return (buf[0] * 1000) / 2559; | 632 | return (buf[0] * 1000) / 2559; |
610 | } | 633 | } |
611 | 634 | ||
635 | static void tickle_fcu(void) | ||
636 | { | ||
637 | int pwm; | ||
638 | |||
639 | pwm = get_pwm_fan(SLOTS_FAN_PWM_INDEX); | ||
640 | |||
641 | DBG("FCU Tickle, slots fan is: %d\n", pwm); | ||
642 | if (pwm < 0) | ||
643 | pwm = 100; | ||
644 | |||
645 | if (!rackmac) { | ||
646 | pwm = SLOTS_FAN_DEFAULT_PWM; | ||
647 | } else if (pwm < SLOTS_PID_OUTPUT_MIN) | ||
648 | pwm = SLOTS_PID_OUTPUT_MIN; | ||
649 | |||
650 | /* That is hopefully enough to make the FCU happy */ | ||
651 | set_pwm_fan(SLOTS_FAN_PWM_INDEX, pwm); | ||
652 | } | ||
653 | |||
654 | |||
612 | /* | 655 | /* |
613 | * Utility routine to read the CPU calibration EEPROM data | 656 | * Utility routine to read the CPU calibration EEPROM data |
614 | * from the device-tree | 657 | * from the device-tree |
@@ -715,6 +758,9 @@ BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm) | |||
715 | BUILD_SHOW_FUNC_FIX(drives_temperature, drives_state.last_temp) | 758 | BUILD_SHOW_FUNC_FIX(drives_temperature, drives_state.last_temp) |
716 | BUILD_SHOW_FUNC_INT(drives_fan_rpm, drives_state.rpm) | 759 | BUILD_SHOW_FUNC_INT(drives_fan_rpm, drives_state.rpm) |
717 | 760 | ||
761 | BUILD_SHOW_FUNC_FIX(slots_temperature, slots_state.last_temp) | ||
762 | BUILD_SHOW_FUNC_INT(slots_fan_pwm, slots_state.pwm) | ||
763 | |||
718 | BUILD_SHOW_FUNC_FIX(dimms_temperature, dimms_state.last_temp) | 764 | BUILD_SHOW_FUNC_FIX(dimms_temperature, dimms_state.last_temp) |
719 | 765 | ||
720 | static DEVICE_ATTR(cpu0_temperature,S_IRUGO,show_cpu0_temperature,NULL); | 766 | static DEVICE_ATTR(cpu0_temperature,S_IRUGO,show_cpu0_temperature,NULL); |
@@ -735,6 +781,9 @@ static DEVICE_ATTR(backside_fan_pwm,S_IRUGO,show_backside_fan_pwm,NULL); | |||
735 | static DEVICE_ATTR(drives_temperature,S_IRUGO,show_drives_temperature,NULL); | 781 | static DEVICE_ATTR(drives_temperature,S_IRUGO,show_drives_temperature,NULL); |
736 | static DEVICE_ATTR(drives_fan_rpm,S_IRUGO,show_drives_fan_rpm,NULL); | 782 | static DEVICE_ATTR(drives_fan_rpm,S_IRUGO,show_drives_fan_rpm,NULL); |
737 | 783 | ||
784 | static DEVICE_ATTR(slots_temperature,S_IRUGO,show_slots_temperature,NULL); | ||
785 | static DEVICE_ATTR(slots_fan_pwm,S_IRUGO,show_slots_fan_pwm,NULL); | ||
786 | |||
738 | static DEVICE_ATTR(dimms_temperature,S_IRUGO,show_dimms_temperature,NULL); | 787 | static DEVICE_ATTR(dimms_temperature,S_IRUGO,show_dimms_temperature,NULL); |
739 | 788 | ||
740 | /* | 789 | /* |
@@ -1076,6 +1125,9 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state) | |||
1076 | fan_min = dimm_output_clamp; | 1125 | fan_min = dimm_output_clamp; |
1077 | fan_min = max(fan_min, (int)state->mpu.rminn_intake_fan); | 1126 | fan_min = max(fan_min, (int)state->mpu.rminn_intake_fan); |
1078 | 1127 | ||
1128 | DBG(" CPU min mpu = %d, min dimm = %d\n", | ||
1129 | state->mpu.rminn_intake_fan, dimm_output_clamp); | ||
1130 | |||
1079 | state->rpm = max(state->rpm, (int)fan_min); | 1131 | state->rpm = max(state->rpm, (int)fan_min); |
1080 | state->rpm = min(state->rpm, (int)state->mpu.rmaxn_intake_fan); | 1132 | state->rpm = min(state->rpm, (int)state->mpu.rmaxn_intake_fan); |
1081 | state->intake_rpm = state->rpm; | 1133 | state->intake_rpm = state->rpm; |
@@ -1374,7 +1426,8 @@ static void do_monitor_drives(struct drives_pid_state *state) | |||
1374 | DBG(" current rpm: %d\n", state->rpm); | 1426 | DBG(" current rpm: %d\n", state->rpm); |
1375 | 1427 | ||
1376 | /* Get some sensor readings */ | 1428 | /* Get some sensor readings */ |
1377 | temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, DS1775_TEMP)) << 8; | 1429 | temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, |
1430 | DS1775_TEMP)) << 8; | ||
1378 | state->last_temp = temp; | 1431 | state->last_temp = temp; |
1379 | DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), | 1432 | DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), |
1380 | FIX32TOPRINT(DRIVES_PID_INPUT_TARGET)); | 1433 | FIX32TOPRINT(DRIVES_PID_INPUT_TARGET)); |
@@ -1575,7 +1628,7 @@ static int init_dimms_state(struct dimm_pid_state *state) | |||
1575 | } | 1628 | } |
1576 | 1629 | ||
1577 | /* | 1630 | /* |
1578 | * Dispose of the state data for the drives control loop | 1631 | * Dispose of the state data for the DIMM control loop |
1579 | */ | 1632 | */ |
1580 | static void dispose_dimms_state(struct dimm_pid_state *state) | 1633 | static void dispose_dimms_state(struct dimm_pid_state *state) |
1581 | { | 1634 | { |
@@ -1588,6 +1641,127 @@ static void dispose_dimms_state(struct dimm_pid_state *state) | |||
1588 | state->monitor = NULL; | 1641 | state->monitor = NULL; |
1589 | } | 1642 | } |
1590 | 1643 | ||
1644 | /* | ||
1645 | * Slots fan control loop | ||
1646 | */ | ||
1647 | static void do_monitor_slots(struct slots_pid_state *state) | ||
1648 | { | ||
1649 | s32 temp, integral, derivative; | ||
1650 | s64 integ_p, deriv_p, prop_p, sum; | ||
1651 | int i, rc; | ||
1652 | |||
1653 | if (--state->ticks != 0) | ||
1654 | return; | ||
1655 | state->ticks = SLOTS_PID_INTERVAL; | ||
1656 | |||
1657 | DBG("slots:\n"); | ||
1658 | |||
1659 | /* Check fan status */ | ||
1660 | rc = get_pwm_fan(SLOTS_FAN_PWM_INDEX); | ||
1661 | if (rc < 0) { | ||
1662 | printk(KERN_WARNING "Error %d reading slots fan !\n", rc); | ||
1663 | /* XXX What do we do now ? */ | ||
1664 | } else | ||
1665 | state->pwm = rc; | ||
1666 | DBG(" current pwm: %d\n", state->pwm); | ||
1667 | |||
1668 | /* Get some sensor readings */ | ||
1669 | temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, | ||
1670 | DS1775_TEMP)) << 8; | ||
1671 | state->last_temp = temp; | ||
1672 | DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), | ||
1673 | FIX32TOPRINT(SLOTS_PID_INPUT_TARGET)); | ||
1674 | |||
1675 | /* Store temperature and error in history array */ | ||
1676 | state->cur_sample = (state->cur_sample + 1) % SLOTS_PID_HISTORY_SIZE; | ||
1677 | state->sample_history[state->cur_sample] = temp; | ||
1678 | state->error_history[state->cur_sample] = temp - SLOTS_PID_INPUT_TARGET; | ||
1679 | |||
1680 | /* If first loop, fill the history table */ | ||
1681 | if (state->first) { | ||
1682 | for (i = 0; i < (SLOTS_PID_HISTORY_SIZE - 1); i++) { | ||
1683 | state->cur_sample = (state->cur_sample + 1) % | ||
1684 | SLOTS_PID_HISTORY_SIZE; | ||
1685 | state->sample_history[state->cur_sample] = temp; | ||
1686 | state->error_history[state->cur_sample] = | ||
1687 | temp - SLOTS_PID_INPUT_TARGET; | ||
1688 | } | ||
1689 | state->first = 0; | ||
1690 | } | ||
1691 | |||
1692 | /* Calculate the integral term */ | ||
1693 | sum = 0; | ||
1694 | integral = 0; | ||
1695 | for (i = 0; i < SLOTS_PID_HISTORY_SIZE; i++) | ||
1696 | integral += state->error_history[i]; | ||
1697 | integral *= SLOTS_PID_INTERVAL; | ||
1698 | DBG(" integral: %08x\n", integral); | ||
1699 | integ_p = ((s64)SLOTS_PID_G_r) * (s64)integral; | ||
1700 | DBG(" integ_p: %d\n", (int)(integ_p >> 36)); | ||
1701 | sum += integ_p; | ||
1702 | |||
1703 | /* Calculate the derivative term */ | ||
1704 | derivative = state->error_history[state->cur_sample] - | ||
1705 | state->error_history[(state->cur_sample + SLOTS_PID_HISTORY_SIZE - 1) | ||
1706 | % SLOTS_PID_HISTORY_SIZE]; | ||
1707 | derivative /= SLOTS_PID_INTERVAL; | ||
1708 | deriv_p = ((s64)SLOTS_PID_G_d) * (s64)derivative; | ||
1709 | DBG(" deriv_p: %d\n", (int)(deriv_p >> 36)); | ||
1710 | sum += deriv_p; | ||
1711 | |||
1712 | /* Calculate the proportional term */ | ||
1713 | prop_p = ((s64)SLOTS_PID_G_p) * (s64)(state->error_history[state->cur_sample]); | ||
1714 | DBG(" prop_p: %d\n", (int)(prop_p >> 36)); | ||
1715 | sum += prop_p; | ||
1716 | |||
1717 | /* Scale sum */ | ||
1718 | sum >>= 36; | ||
1719 | |||
1720 | DBG(" sum: %d\n", (int)sum); | ||
1721 | state->pwm = (s32)sum; | ||
1722 | |||
1723 | state->pwm = max(state->pwm, SLOTS_PID_OUTPUT_MIN); | ||
1724 | state->pwm = min(state->pwm, SLOTS_PID_OUTPUT_MAX); | ||
1725 | |||
1726 | DBG("** DRIVES PWM: %d\n", (int)state->pwm); | ||
1727 | set_pwm_fan(SLOTS_FAN_PWM_INDEX, state->pwm); | ||
1728 | } | ||
1729 | |||
1730 | /* | ||
1731 | * Initialize the state structure for the slots bay fan control loop | ||
1732 | */ | ||
1733 | static int init_slots_state(struct slots_pid_state *state) | ||
1734 | { | ||
1735 | state->ticks = 1; | ||
1736 | state->first = 1; | ||
1737 | state->pwm = 50; | ||
1738 | |||
1739 | state->monitor = attach_i2c_chip(XSERVE_SLOTS_LM75, "slots_temp"); | ||
1740 | if (state->monitor == NULL) | ||
1741 | return -ENODEV; | ||
1742 | |||
1743 | device_create_file(&of_dev->dev, &dev_attr_slots_temperature); | ||
1744 | device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); | ||
1745 | |||
1746 | return 0; | ||
1747 | } | ||
1748 | |||
1749 | /* | ||
1750 | * Dispose of the state data for the slots control loop | ||
1751 | */ | ||
1752 | static void dispose_slots_state(struct slots_pid_state *state) | ||
1753 | { | ||
1754 | if (state->monitor == NULL) | ||
1755 | return; | ||
1756 | |||
1757 | device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); | ||
1758 | device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); | ||
1759 | |||
1760 | detach_i2c_chip(state->monitor); | ||
1761 | state->monitor = NULL; | ||
1762 | } | ||
1763 | |||
1764 | |||
1591 | static int call_critical_overtemp(void) | 1765 | static int call_critical_overtemp(void) |
1592 | { | 1766 | { |
1593 | char *argv[] = { critical_overtemp_path, NULL }; | 1767 | char *argv[] = { critical_overtemp_path, NULL }; |
@@ -1617,14 +1791,17 @@ static int main_control_loop(void *x) | |||
1617 | goto out; | 1791 | goto out; |
1618 | } | 1792 | } |
1619 | 1793 | ||
1620 | /* Set the PCI fan once for now */ | 1794 | /* Set the PCI fan once for now on non-RackMac */ |
1621 | set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); | 1795 | if (!rackmac) |
1796 | set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); | ||
1622 | 1797 | ||
1623 | /* Initialize ADCs */ | 1798 | /* Initialize ADCs */ |
1624 | initialize_adc(&cpu_state[0]); | 1799 | initialize_adc(&cpu_state[0]); |
1625 | if (cpu_state[1].monitor != NULL) | 1800 | if (cpu_state[1].monitor != NULL) |
1626 | initialize_adc(&cpu_state[1]); | 1801 | initialize_adc(&cpu_state[1]); |
1627 | 1802 | ||
1803 | fcu_tickle_ticks = FCU_TICKLE_TICKS; | ||
1804 | |||
1628 | up(&driver_lock); | 1805 | up(&driver_lock); |
1629 | 1806 | ||
1630 | while (state == state_attached) { | 1807 | while (state == state_attached) { |
@@ -1634,6 +1811,12 @@ static int main_control_loop(void *x) | |||
1634 | 1811 | ||
1635 | down(&driver_lock); | 1812 | down(&driver_lock); |
1636 | 1813 | ||
1814 | /* Tickle the FCU just in case */ | ||
1815 | if (--fcu_tickle_ticks < 0) { | ||
1816 | fcu_tickle_ticks = FCU_TICKLE_TICKS; | ||
1817 | tickle_fcu(); | ||
1818 | } | ||
1819 | |||
1637 | /* First, we always calculate the new DIMMs state on an Xserve */ | 1820 | /* First, we always calculate the new DIMMs state on an Xserve */ |
1638 | if (rackmac) | 1821 | if (rackmac) |
1639 | do_monitor_dimms(&dimms_state); | 1822 | do_monitor_dimms(&dimms_state); |
@@ -1654,7 +1837,9 @@ static int main_control_loop(void *x) | |||
1654 | } | 1837 | } |
1655 | /* Then, the rest */ | 1838 | /* Then, the rest */ |
1656 | do_monitor_backside(&backside_state); | 1839 | do_monitor_backside(&backside_state); |
1657 | if (!rackmac) | 1840 | if (rackmac) |
1841 | do_monitor_slots(&slots_state); | ||
1842 | else | ||
1658 | do_monitor_drives(&drives_state); | 1843 | do_monitor_drives(&drives_state); |
1659 | up(&driver_lock); | 1844 | up(&driver_lock); |
1660 | 1845 | ||
@@ -1696,6 +1881,7 @@ static void dispose_control_loops(void) | |||
1696 | dispose_cpu_state(&cpu_state[1]); | 1881 | dispose_cpu_state(&cpu_state[1]); |
1697 | dispose_backside_state(&backside_state); | 1882 | dispose_backside_state(&backside_state); |
1698 | dispose_drives_state(&drives_state); | 1883 | dispose_drives_state(&drives_state); |
1884 | dispose_slots_state(&slots_state); | ||
1699 | dispose_dimms_state(&dimms_state); | 1885 | dispose_dimms_state(&dimms_state); |
1700 | } | 1886 | } |
1701 | 1887 | ||
@@ -1745,6 +1931,8 @@ static int create_control_loops(void) | |||
1745 | goto fail; | 1931 | goto fail; |
1746 | if (rackmac && init_dimms_state(&dimms_state)) | 1932 | if (rackmac && init_dimms_state(&dimms_state)) |
1747 | goto fail; | 1933 | goto fail; |
1934 | if (rackmac && init_slots_state(&slots_state)) | ||
1935 | goto fail; | ||
1748 | if (!rackmac && init_drives_state(&drives_state)) | 1936 | if (!rackmac && init_drives_state(&drives_state)) |
1749 | goto fail; | 1937 | goto fail; |
1750 | 1938 | ||
diff --git a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h index fc7e9b7ecaf2..393cc9df94e1 100644 --- a/drivers/macintosh/therm_pm72.h +++ b/drivers/macintosh/therm_pm72.h | |||
@@ -105,6 +105,7 @@ static char * critical_overtemp_path = "/sbin/critical_overtemp"; | |||
105 | #define DRIVES_DALLAS_ID 0x94 | 105 | #define DRIVES_DALLAS_ID 0x94 |
106 | #define BACKSIDE_MAX_ID 0x98 | 106 | #define BACKSIDE_MAX_ID 0x98 |
107 | #define XSERVE_DIMMS_LM87 0x25a | 107 | #define XSERVE_DIMMS_LM87 0x25a |
108 | #define XSERVE_SLOTS_LM75 0x290 | ||
108 | 109 | ||
109 | /* | 110 | /* |
110 | * Some MAX6690, DS1775, LM87 register definitions | 111 | * Some MAX6690, DS1775, LM87 register definitions |
@@ -198,7 +199,7 @@ struct drives_pid_state | |||
198 | 199 | ||
199 | #define SLOTS_FAN_PWM_DEFAULT_ID 2 | 200 | #define SLOTS_FAN_PWM_DEFAULT_ID 2 |
200 | #define SLOTS_FAN_PWM_INDEX 2 | 201 | #define SLOTS_FAN_PWM_INDEX 2 |
201 | #define SLOTS_FAN_DEFAULT_PWM 50 /* Do better here ! */ | 202 | #define SLOTS_FAN_DEFAULT_PWM 40 /* Do better here ! */ |
202 | 203 | ||
203 | 204 | ||
204 | /* | 205 | /* |
@@ -206,7 +207,7 @@ struct drives_pid_state | |||
206 | */ | 207 | */ |
207 | #define DIMM_PID_G_d 0 | 208 | #define DIMM_PID_G_d 0 |
208 | #define DIMM_PID_G_p 0 | 209 | #define DIMM_PID_G_p 0 |
209 | #define DIMM_PID_G_r 0x6553600 | 210 | #define DIMM_PID_G_r 0x06553600 |
210 | #define DIMM_PID_INPUT_TARGET 3276800 | 211 | #define DIMM_PID_INPUT_TARGET 3276800 |
211 | #define DIMM_PID_INTERVAL 1 | 212 | #define DIMM_PID_INTERVAL 1 |
212 | #define DIMM_PID_OUTPUT_MAX 14000 | 213 | #define DIMM_PID_OUTPUT_MAX 14000 |
@@ -226,6 +227,31 @@ struct dimm_pid_state | |||
226 | }; | 227 | }; |
227 | 228 | ||
228 | 229 | ||
230 | /* | ||
231 | * PID factors for the Xserve Slots control loop | ||
232 | */ | ||
233 | #define SLOTS_PID_G_d 0 | ||
234 | #define SLOTS_PID_G_p 0 | ||
235 | #define SLOTS_PID_G_r 0x00100000 | ||
236 | #define SLOTS_PID_INPUT_TARGET 3200000 | ||
237 | #define SLOTS_PID_INTERVAL 1 | ||
238 | #define SLOTS_PID_OUTPUT_MAX 100 | ||
239 | #define SLOTS_PID_OUTPUT_MIN 20 | ||
240 | #define SLOTS_PID_HISTORY_SIZE 20 | ||
241 | |||
242 | struct slots_pid_state | ||
243 | { | ||
244 | int ticks; | ||
245 | struct i2c_client * monitor; | ||
246 | s32 sample_history[SLOTS_PID_HISTORY_SIZE]; | ||
247 | s32 error_history[SLOTS_PID_HISTORY_SIZE]; | ||
248 | int cur_sample; | ||
249 | s32 last_temp; | ||
250 | int first; | ||
251 | int pwm; | ||
252 | }; | ||
253 | |||
254 | |||
229 | 255 | ||
230 | /* Desktops */ | 256 | /* Desktops */ |
231 | 257 | ||
@@ -283,6 +309,9 @@ struct cpu_pid_state | |||
283 | s32 pump_max; | 309 | s32 pump_max; |
284 | }; | 310 | }; |
285 | 311 | ||
312 | /* Tickle FCU every 10 seconds */ | ||
313 | #define FCU_TICKLE_TICKS 10 | ||
314 | |||
286 | /* | 315 | /* |
287 | * Driver state | 316 | * Driver state |
288 | */ | 317 | */ |
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index b42d05f2aaff..d3f8d75bcbb4 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
@@ -15,8 +15,9 @@ | |||
15 | 15 | ||
16 | #define MAX_PMU_LEVEL 0xFF | 16 | #define MAX_PMU_LEVEL 0xFF |
17 | 17 | ||
18 | static struct device_node *vias; | ||
19 | static struct backlight_properties pmu_backlight_data; | 18 | static struct backlight_properties pmu_backlight_data; |
19 | static spinlock_t pmu_backlight_lock; | ||
20 | static int sleeping; | ||
20 | 21 | ||
21 | static int pmu_backlight_get_level_brightness(struct fb_info *info, | 22 | static int pmu_backlight_get_level_brightness(struct fb_info *info, |
22 | int level) | 23 | int level) |
@@ -40,23 +41,36 @@ static int pmu_backlight_update_status(struct backlight_device *bd) | |||
40 | { | 41 | { |
41 | struct fb_info *info = class_get_devdata(&bd->class_dev); | 42 | struct fb_info *info = class_get_devdata(&bd->class_dev); |
42 | struct adb_request req; | 43 | struct adb_request req; |
43 | int pmulevel, level = bd->props->brightness; | 44 | unsigned long flags; |
45 | int level = bd->props->brightness; | ||
44 | 46 | ||
45 | if (vias == NULL) | 47 | spin_lock_irqsave(&pmu_backlight_lock, flags); |
46 | return -ENODEV; | 48 | |
49 | /* Don't update brightness when sleeping */ | ||
50 | if (sleeping) | ||
51 | goto out; | ||
47 | 52 | ||
48 | if (bd->props->power != FB_BLANK_UNBLANK || | 53 | if (bd->props->power != FB_BLANK_UNBLANK || |
49 | bd->props->fb_blank != FB_BLANK_UNBLANK) | 54 | bd->props->fb_blank != FB_BLANK_UNBLANK) |
50 | level = 0; | 55 | level = 0; |
51 | 56 | ||
52 | pmulevel = pmu_backlight_get_level_brightness(info, level); | 57 | if (level > 0) { |
58 | int pmulevel = pmu_backlight_get_level_brightness(info, level); | ||
53 | 59 | ||
54 | pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); | 60 | pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); |
55 | pmu_wait_complete(&req); | 61 | pmu_wait_complete(&req); |
56 | 62 | ||
57 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL, | 63 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL, |
58 | PMU_POW_BACKLIGHT | (level > 0 ? PMU_POW_ON : PMU_POW_OFF)); | 64 | PMU_POW_BACKLIGHT | PMU_POW_ON); |
59 | pmu_wait_complete(&req); | 65 | pmu_wait_complete(&req); |
66 | } else { | ||
67 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL, | ||
68 | PMU_POW_BACKLIGHT | PMU_POW_OFF); | ||
69 | pmu_wait_complete(&req); | ||
70 | } | ||
71 | |||
72 | out: | ||
73 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | ||
60 | 74 | ||
61 | return 0; | 75 | return 0; |
62 | } | 76 | } |
@@ -73,15 +87,39 @@ static struct backlight_properties pmu_backlight_data = { | |||
73 | .max_brightness = (FB_BACKLIGHT_LEVELS - 1), | 87 | .max_brightness = (FB_BACKLIGHT_LEVELS - 1), |
74 | }; | 88 | }; |
75 | 89 | ||
76 | void __init pmu_backlight_init(struct device_node *in_vias) | 90 | #ifdef CONFIG_PM |
91 | static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when) | ||
92 | { | ||
93 | unsigned long flags; | ||
94 | |||
95 | spin_lock_irqsave(&pmu_backlight_lock, flags); | ||
96 | |||
97 | switch (when) { | ||
98 | case PBOOK_SLEEP_REQUEST: | ||
99 | sleeping = 1; | ||
100 | break; | ||
101 | case PBOOK_WAKE: | ||
102 | sleeping = 0; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | ||
107 | |||
108 | return PBOOK_SLEEP_OK; | ||
109 | } | ||
110 | |||
111 | static struct pmu_sleep_notifier pmu_backlight_sleep_notif = { | ||
112 | .notifier_call = pmu_backlight_sleep_call, | ||
113 | }; | ||
114 | #endif | ||
115 | |||
116 | void __init pmu_backlight_init() | ||
77 | { | 117 | { |
78 | struct backlight_device *bd; | 118 | struct backlight_device *bd; |
79 | struct fb_info *info; | 119 | struct fb_info *info; |
80 | char name[10]; | 120 | char name[10]; |
81 | int level, autosave; | 121 | int level, autosave; |
82 | 122 | ||
83 | vias = in_vias; | ||
84 | |||
85 | /* Special case for the old PowerBook since I can't test on it */ | 123 | /* Special case for the old PowerBook since I can't test on it */ |
86 | autosave = | 124 | autosave = |
87 | machine_is_compatible("AAPL,3400/2400") || | 125 | machine_is_compatible("AAPL,3400/2400") || |
@@ -141,6 +179,10 @@ void __init pmu_backlight_init(struct device_node *in_vias) | |||
141 | pmac_backlight = bd; | 179 | pmac_backlight = bd; |
142 | mutex_unlock(&pmac_backlight_mutex); | 180 | mutex_unlock(&pmac_backlight_mutex); |
143 | 181 | ||
182 | #ifdef CONFIG_PM | ||
183 | pmu_register_sleep_notifier(&pmu_backlight_sleep_notif); | ||
184 | #endif | ||
185 | |||
144 | printk("pmubl: Backlight initialized (%s)\n", name); | 186 | printk("pmubl: Backlight initialized (%s)\n", name); |
145 | 187 | ||
146 | return; | 188 | return; |
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c index af8375ed0f5e..5189d5454b1f 100644 --- a/drivers/macintosh/via-pmu-led.c +++ b/drivers/macintosh/via-pmu-led.c | |||
@@ -74,7 +74,7 @@ static void pmu_led_set(struct led_classdev *led_cdev, | |||
74 | 74 | ||
75 | static struct led_classdev pmu_led = { | 75 | static struct led_classdev pmu_led = { |
76 | .name = "pmu-front-led", | 76 | .name = "pmu-front-led", |
77 | #ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK | 77 | #ifdef CONFIG_ADB_PMU_LED_IDE |
78 | .default_trigger = "ide-disk", | 78 | .default_trigger = "ide-disk", |
79 | #endif | 79 | #endif |
80 | .brightness_set = pmu_led_set, | 80 | .brightness_set = pmu_led_set, |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 06ca80bfd6b9..ea386801e215 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -16,7 +16,6 @@ | |||
16 | * a sleep or a freq. switch | 16 | * a sleep or a freq. switch |
17 | * - Move sleep code out of here to pmac_pm, merge into new | 17 | * - Move sleep code out of here to pmac_pm, merge into new |
18 | * common PM infrastructure | 18 | * common PM infrastructure |
19 | * - Move backlight code out as well | ||
20 | * - Save/Restore PCI space properly | 19 | * - Save/Restore PCI space properly |
21 | * | 20 | * |
22 | */ | 21 | */ |
@@ -60,9 +59,7 @@ | |||
60 | #include <asm/mmu_context.h> | 59 | #include <asm/mmu_context.h> |
61 | #include <asm/cputable.h> | 60 | #include <asm/cputable.h> |
62 | #include <asm/time.h> | 61 | #include <asm/time.h> |
63 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
64 | #include <asm/backlight.h> | 62 | #include <asm/backlight.h> |
65 | #endif | ||
66 | 63 | ||
67 | #include "via-pmu-event.h" | 64 | #include "via-pmu-event.h" |
68 | 65 | ||
@@ -177,10 +174,6 @@ static int query_batt_timer = BATTERY_POLLING_COUNT; | |||
177 | static struct adb_request batt_req; | 174 | static struct adb_request batt_req; |
178 | static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES]; | 175 | static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES]; |
179 | 176 | ||
180 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) | ||
181 | extern int disable_kernel_backlight; | ||
182 | #endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ | ||
183 | |||
184 | int __fake_sleep; | 177 | int __fake_sleep; |
185 | int asleep; | 178 | int asleep; |
186 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); | 179 | BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); |
@@ -466,7 +459,7 @@ static int __init via_pmu_dev_init(void) | |||
466 | 459 | ||
467 | #ifdef CONFIG_PMAC_BACKLIGHT | 460 | #ifdef CONFIG_PMAC_BACKLIGHT |
468 | /* Initialize backlight */ | 461 | /* Initialize backlight */ |
469 | pmu_backlight_init(vias); | 462 | pmu_backlight_init(); |
470 | #endif | 463 | #endif |
471 | 464 | ||
472 | #ifdef CONFIG_PPC32 | 465 | #ifdef CONFIG_PPC32 |
@@ -1403,11 +1396,8 @@ next: | |||
1403 | else if ((1 << pirq) & PMU_INT_SNDBRT) { | 1396 | else if ((1 << pirq) & PMU_INT_SNDBRT) { |
1404 | #ifdef CONFIG_PMAC_BACKLIGHT | 1397 | #ifdef CONFIG_PMAC_BACKLIGHT |
1405 | if (len == 3) | 1398 | if (len == 3) |
1406 | #ifdef CONFIG_INPUT_ADBHID | 1399 | pmac_backlight_set_legacy_brightness_pmu(data[1] >> 4); |
1407 | if (!disable_kernel_backlight) | 1400 | #endif |
1408 | #endif /* CONFIG_INPUT_ADBHID */ | ||
1409 | pmac_backlight_set_legacy_brightness(data[1] >> 4); | ||
1410 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
1411 | } | 1401 | } |
1412 | /* Tick interrupt */ | 1402 | /* Tick interrupt */ |
1413 | else if ((1 << pirq) & PMU_INT_TICK) { | 1403 | else if ((1 << pirq) & PMU_INT_TICK) { |
@@ -2414,7 +2404,7 @@ struct pmu_private { | |||
2414 | spinlock_t lock; | 2404 | spinlock_t lock; |
2415 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) | 2405 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) |
2416 | int backlight_locker; | 2406 | int backlight_locker; |
2417 | #endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ | 2407 | #endif |
2418 | }; | 2408 | }; |
2419 | 2409 | ||
2420 | static LIST_HEAD(all_pmu_pvt); | 2410 | static LIST_HEAD(all_pmu_pvt); |
@@ -2464,7 +2454,7 @@ pmu_open(struct inode *inode, struct file *file) | |||
2464 | spin_lock_irqsave(&all_pvt_lock, flags); | 2454 | spin_lock_irqsave(&all_pvt_lock, flags); |
2465 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) | 2455 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) |
2466 | pp->backlight_locker = 0; | 2456 | pp->backlight_locker = 0; |
2467 | #endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ | 2457 | #endif |
2468 | list_add(&pp->list, &all_pmu_pvt); | 2458 | list_add(&pp->list, &all_pmu_pvt); |
2469 | spin_unlock_irqrestore(&all_pvt_lock, flags); | 2459 | spin_unlock_irqrestore(&all_pvt_lock, flags); |
2470 | file->private_data = pp; | 2460 | file->private_data = pp; |
@@ -2559,13 +2549,12 @@ pmu_release(struct inode *inode, struct file *file) | |||
2559 | spin_lock_irqsave(&all_pvt_lock, flags); | 2549 | spin_lock_irqsave(&all_pvt_lock, flags); |
2560 | list_del(&pp->list); | 2550 | list_del(&pp->list); |
2561 | spin_unlock_irqrestore(&all_pvt_lock, flags); | 2551 | spin_unlock_irqrestore(&all_pvt_lock, flags); |
2552 | |||
2562 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) | 2553 | #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) |
2563 | if (pp->backlight_locker) { | 2554 | if (pp->backlight_locker) |
2564 | spin_lock_irqsave(&pmu_lock, flags); | 2555 | pmac_backlight_enable(); |
2565 | disable_kernel_backlight--; | 2556 | #endif |
2566 | spin_unlock_irqrestore(&pmu_lock, flags); | 2557 | |
2567 | } | ||
2568 | #endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ | ||
2569 | kfree(pp); | 2558 | kfree(pp); |
2570 | } | 2559 | } |
2571 | unlock_kernel(); | 2560 | unlock_kernel(); |
@@ -2642,18 +2631,18 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2642 | #ifdef CONFIG_INPUT_ADBHID | 2631 | #ifdef CONFIG_INPUT_ADBHID |
2643 | case PMU_IOC_GRAB_BACKLIGHT: { | 2632 | case PMU_IOC_GRAB_BACKLIGHT: { |
2644 | struct pmu_private *pp = filp->private_data; | 2633 | struct pmu_private *pp = filp->private_data; |
2645 | unsigned long flags; | ||
2646 | 2634 | ||
2647 | if (pp->backlight_locker) | 2635 | if (pp->backlight_locker) |
2648 | return 0; | 2636 | return 0; |
2637 | |||
2649 | pp->backlight_locker = 1; | 2638 | pp->backlight_locker = 1; |
2650 | spin_lock_irqsave(&pmu_lock, flags); | 2639 | pmac_backlight_disable(); |
2651 | disable_kernel_backlight++; | 2640 | |
2652 | spin_unlock_irqrestore(&pmu_lock, flags); | ||
2653 | return 0; | 2641 | return 0; |
2654 | } | 2642 | } |
2655 | #endif /* CONFIG_INPUT_ADBHID */ | 2643 | #endif /* CONFIG_INPUT_ADBHID */ |
2656 | #endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ | 2644 | #endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ |
2645 | |||
2657 | case PMU_IOC_GET_MODEL: | 2646 | case PMU_IOC_GET_MODEL: |
2658 | return put_user(pmu_kind, argp); | 2647 | return put_user(pmu_kind, argp); |
2659 | case PMU_IOC_HAS_ADB: | 2648 | case PMU_IOC_HAS_ADB: |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index ff83c9b5979e..b99c19c7eb22 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -162,7 +162,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
162 | goto out; | 162 | goto out; |
163 | } | 163 | } |
164 | 164 | ||
165 | min_spacing = mddev->array_size; | 165 | min_spacing = conf->array_size; |
166 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); | 166 | sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *)); |
167 | 167 | ||
168 | /* min_spacing is the minimum spacing that will fit the hash | 168 | /* min_spacing is the minimum spacing that will fit the hash |
@@ -171,7 +171,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
171 | * that is larger than min_spacing as use the size of that as | 171 | * that is larger than min_spacing as use the size of that as |
172 | * the actual spacing | 172 | * the actual spacing |
173 | */ | 173 | */ |
174 | conf->hash_spacing = mddev->array_size; | 174 | conf->hash_spacing = conf->array_size; |
175 | for (i=0; i < cnt-1 ; i++) { | 175 | for (i=0; i < cnt-1 ; i++) { |
176 | sector_t sz = 0; | 176 | sector_t sz = 0; |
177 | int j; | 177 | int j; |
@@ -228,7 +228,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
228 | curr_offset = 0; | 228 | curr_offset = 0; |
229 | i = 0; | 229 | i = 0; |
230 | for (curr_offset = 0; | 230 | for (curr_offset = 0; |
231 | curr_offset < mddev->array_size; | 231 | curr_offset < conf->array_size; |
232 | curr_offset += conf->hash_spacing) { | 232 | curr_offset += conf->hash_spacing) { |
233 | 233 | ||
234 | while (i < mddev->raid_disks-1 && | 234 | while (i < mddev->raid_disks-1 && |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 59ac35ddd51e..57b34cda99f5 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -526,7 +526,9 @@ static int dvb_frontend_thread(void *data) | |||
526 | fepriv->delay = 3*HZ; | 526 | fepriv->delay = 3*HZ; |
527 | fepriv->status = 0; | 527 | fepriv->status = 0; |
528 | fepriv->wakeup = 0; | 528 | fepriv->wakeup = 0; |
529 | fepriv->reinitialise = 1; | 529 | fepriv->reinitialise = 0; |
530 | |||
531 | dvb_frontend_init(fe); | ||
530 | 532 | ||
531 | while (1) { | 533 | while (1) { |
532 | up(&fepriv->sem); /* is locked when we enter the thread... */ | 534 | up(&fepriv->sem); /* is locked when we enter the thread... */ |
@@ -1013,17 +1015,18 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
1013 | return ret; | 1015 | return ret; |
1014 | 1016 | ||
1015 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 1017 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
1018 | |||
1019 | /* normal tune mode when opened R/W */ | ||
1020 | fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; | ||
1021 | fepriv->tone = -1; | ||
1022 | fepriv->voltage = -1; | ||
1023 | |||
1016 | ret = dvb_frontend_start (fe); | 1024 | ret = dvb_frontend_start (fe); |
1017 | if (ret) | 1025 | if (ret) |
1018 | dvb_generic_release (inode, file); | 1026 | dvb_generic_release (inode, file); |
1019 | 1027 | ||
1020 | /* empty event queue */ | 1028 | /* empty event queue */ |
1021 | fepriv->events.eventr = fepriv->events.eventw = 0; | 1029 | fepriv->events.eventr = fepriv->events.eventw = 0; |
1022 | |||
1023 | /* normal tune mode when opened R/W */ | ||
1024 | fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; | ||
1025 | fepriv->tone = -1; | ||
1026 | fepriv->voltage = -1; | ||
1027 | } | 1030 | } |
1028 | 1031 | ||
1029 | return ret; | 1032 | return ret; |
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index a189683454b7..2be33f27c69f 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -194,11 +194,11 @@ struct dvb_pll_desc dvb_pll_tda665x = { | |||
194 | { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, | 194 | { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, |
195 | { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, | 195 | { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, |
196 | { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, | 196 | { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, |
197 | { 444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, | 197 | { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
198 | { 583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0 11 */ }, | 198 | { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, |
199 | { 793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0 11 */ }, | 199 | { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, |
200 | { 444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ }, | 200 | { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
201 | { 861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0 11 */ }, | 201 | { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, |
202 | } | 202 | } |
203 | }; | 203 | }; |
204 | EXPORT_SYMBOL(dvb_pll_tda665x); | 204 | EXPORT_SYMBOL(dvb_pll_tda665x); |
@@ -613,7 +613,21 @@ static struct dvb_tuner_ops dvb_pll_tuner_ops = { | |||
613 | 613 | ||
614 | int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) | 614 | int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) |
615 | { | 615 | { |
616 | u8 b1 [] = { 0 }; | ||
617 | struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }; | ||
616 | struct dvb_pll_priv *priv = NULL; | 618 | struct dvb_pll_priv *priv = NULL; |
619 | int ret; | ||
620 | |||
621 | if (i2c != NULL) { | ||
622 | if (fe->ops.i2c_gate_ctrl) | ||
623 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
624 | |||
625 | ret = i2c_transfer (i2c, &msg, 1); | ||
626 | if (ret != 1) | ||
627 | return -1; | ||
628 | if (fe->ops.i2c_gate_ctrl) | ||
629 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
630 | } | ||
617 | 631 | ||
618 | priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); | 632 | priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); |
619 | if (priv == NULL) | 633 | if (priv == NULL) |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 500f15c10aaf..4506165c5de2 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -2203,8 +2203,8 @@ static int frontend_init(struct av7110 *av7110) | |||
2203 | av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; | 2203 | av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; |
2204 | 2204 | ||
2205 | /* set TDA9819 into DVB mode */ | 2205 | /* set TDA9819 into DVB mode */ |
2206 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) | 2206 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) |
2207 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) | 2207 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) |
2208 | 2208 | ||
2209 | /* tuner on this needs a slower i2c bus speed */ | 2209 | /* tuner on this needs a slower i2c bus speed */ |
2210 | av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | 2210 | av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index 64055461559d..6ffe53fdcf57 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -272,8 +272,8 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) | |||
272 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) | 272 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) |
273 | dprintk(1, "setting band in demodulator failed.\n"); | 273 | dprintk(1, "setting band in demodulator failed.\n"); |
274 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | 274 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { |
275 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD) | 275 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD) |
276 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF) | 276 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF) |
277 | } | 277 | } |
278 | if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1) | 278 | if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1) |
279 | dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); | 279 | dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); |
@@ -308,8 +308,8 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) | |||
308 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x20)) | 308 | if (ves1820_writereg(dev, 0x09, 0x0f, 0x20)) |
309 | dprintk(1, "setting band in demodulator failed.\n"); | 309 | dprintk(1, "setting band in demodulator failed.\n"); |
310 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | 310 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { |
311 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) | 311 | saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) |
312 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) | 312 | saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) |
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
@@ -750,8 +750,8 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
750 | if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20)) | 750 | if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20)) |
751 | dprintk(1, "setting band in demodulator failed.\n"); | 751 | dprintk(1, "setting band in demodulator failed.\n"); |
752 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { | 752 | } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { |
753 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) | 753 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) |
754 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) | 754 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) |
755 | } | 755 | } |
756 | 756 | ||
757 | /* init the saa7113 */ | 757 | /* init the saa7113 */ |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 5f111d407730..2d21fec23b4d 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -1303,6 +1303,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
1303 | budget_av->budget.dvb_adapter.priv = budget_av; | 1303 | budget_av->budget.dvb_adapter.priv = budget_av; |
1304 | frontend_init(budget_av); | 1304 | frontend_init(budget_av); |
1305 | ciintf_init(budget_av); | 1305 | ciintf_init(budget_av); |
1306 | |||
1307 | ttpci_budget_init_hooks(&budget_av->budget); | ||
1308 | |||
1306 | return 0; | 1309 | return 0; |
1307 | } | 1310 | } |
1308 | 1311 | ||
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 4b966eea3834..ffbbb3e34be4 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -1101,6 +1101,8 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
1101 | budget_ci->budget.dvb_adapter.priv = budget_ci; | 1101 | budget_ci->budget.dvb_adapter.priv = budget_ci; |
1102 | frontend_init(budget_ci); | 1102 | frontend_init(budget_ci); |
1103 | 1103 | ||
1104 | ttpci_budget_init_hooks(&budget_ci->budget); | ||
1105 | |||
1104 | return 0; | 1106 | return 0; |
1105 | } | 1107 | } |
1106 | 1108 | ||
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index e4cf7775e07f..e15562f81664 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -63,9 +63,6 @@ static int stop_ts_capture(struct budget *budget) | |||
63 | { | 63 | { |
64 | dprintk(2, "budget: %p\n", budget); | 64 | dprintk(2, "budget: %p\n", budget); |
65 | 65 | ||
66 | if (--budget->feeding) | ||
67 | return budget->feeding; | ||
68 | |||
69 | saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off | 66 | saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off |
70 | SAA7146_IER_DISABLE(budget->dev, MASK_10); | 67 | SAA7146_IER_DISABLE(budget->dev, MASK_10); |
71 | return 0; | 68 | return 0; |
@@ -77,8 +74,8 @@ static int start_ts_capture(struct budget *budget) | |||
77 | 74 | ||
78 | dprintk(2, "budget: %p\n", budget); | 75 | dprintk(2, "budget: %p\n", budget); |
79 | 76 | ||
80 | if (budget->feeding) | 77 | if (!budget->feeding || !budget->fe_synced) |
81 | return ++budget->feeding; | 78 | return 0; |
82 | 79 | ||
83 | saa7146_write(dev, MC1, MASK_20); // DMA3 off | 80 | saa7146_write(dev, MC1, MASK_20); // DMA3 off |
84 | 81 | ||
@@ -139,7 +136,33 @@ static int start_ts_capture(struct budget *budget) | |||
139 | SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ | 136 | SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ |
140 | saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ | 137 | saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ |
141 | 138 | ||
142 | return ++budget->feeding; | 139 | return 0; |
140 | } | ||
141 | |||
142 | static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status) | ||
143 | { | ||
144 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
145 | int synced; | ||
146 | int ret; | ||
147 | |||
148 | if (budget->read_fe_status) | ||
149 | ret = budget->read_fe_status(fe, status); | ||
150 | else | ||
151 | ret = -EINVAL; | ||
152 | |||
153 | if (!ret) { | ||
154 | synced = (*status & FE_HAS_LOCK); | ||
155 | if (synced != budget->fe_synced) { | ||
156 | budget->fe_synced = synced; | ||
157 | spin_lock(&budget->feedlock); | ||
158 | if (synced) | ||
159 | start_ts_capture(budget); | ||
160 | else | ||
161 | stop_ts_capture(budget); | ||
162 | spin_unlock(&budget->feedlock); | ||
163 | } | ||
164 | } | ||
165 | return ret; | ||
143 | } | 166 | } |
144 | 167 | ||
145 | static void vpeirq(unsigned long data) | 168 | static void vpeirq(unsigned long data) |
@@ -267,7 +290,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) | |||
267 | { | 290 | { |
268 | struct dvb_demux *demux = feed->demux; | 291 | struct dvb_demux *demux = feed->demux; |
269 | struct budget *budget = (struct budget *) demux->priv; | 292 | struct budget *budget = (struct budget *) demux->priv; |
270 | int status; | 293 | int status = 0; |
271 | 294 | ||
272 | dprintk(2, "budget: %p\n", budget); | 295 | dprintk(2, "budget: %p\n", budget); |
273 | 296 | ||
@@ -276,7 +299,8 @@ static int budget_start_feed(struct dvb_demux_feed *feed) | |||
276 | 299 | ||
277 | spin_lock(&budget->feedlock); | 300 | spin_lock(&budget->feedlock); |
278 | feed->pusi_seen = 0; /* have a clean section start */ | 301 | feed->pusi_seen = 0; /* have a clean section start */ |
279 | status = start_ts_capture(budget); | 302 | if (budget->feeding++ == 0) |
303 | status = start_ts_capture(budget); | ||
280 | spin_unlock(&budget->feedlock); | 304 | spin_unlock(&budget->feedlock); |
281 | return status; | 305 | return status; |
282 | } | 306 | } |
@@ -285,12 +309,13 @@ static int budget_stop_feed(struct dvb_demux_feed *feed) | |||
285 | { | 309 | { |
286 | struct dvb_demux *demux = feed->demux; | 310 | struct dvb_demux *demux = feed->demux; |
287 | struct budget *budget = (struct budget *) demux->priv; | 311 | struct budget *budget = (struct budget *) demux->priv; |
288 | int status; | 312 | int status = 0; |
289 | 313 | ||
290 | dprintk(2, "budget: %p\n", budget); | 314 | dprintk(2, "budget: %p\n", budget); |
291 | 315 | ||
292 | spin_lock(&budget->feedlock); | 316 | spin_lock(&budget->feedlock); |
293 | status = stop_ts_capture(budget); | 317 | if (--budget->feeding == 0) |
318 | status = stop_ts_capture(budget); | ||
294 | spin_unlock(&budget->feedlock); | 319 | spin_unlock(&budget->feedlock); |
295 | return status; | 320 | return status; |
296 | } | 321 | } |
@@ -470,6 +495,14 @@ err: | |||
470 | return ret; | 495 | return ret; |
471 | } | 496 | } |
472 | 497 | ||
498 | void ttpci_budget_init_hooks(struct budget *budget) | ||
499 | { | ||
500 | if (budget->dvb_frontend && !budget->read_fe_status) { | ||
501 | budget->read_fe_status = budget->dvb_frontend->ops.read_status; | ||
502 | budget->dvb_frontend->ops.read_status = budget_read_fe_status; | ||
503 | } | ||
504 | } | ||
505 | |||
473 | int ttpci_budget_deinit(struct budget *budget) | 506 | int ttpci_budget_deinit(struct budget *budget) |
474 | { | 507 | { |
475 | struct saa7146_dev *dev = budget->dev; | 508 | struct saa7146_dev *dev = budget->dev; |
@@ -508,11 +541,8 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) | |||
508 | spin_lock(&budget->feedlock); | 541 | spin_lock(&budget->feedlock); |
509 | budget->video_port = video_port; | 542 | budget->video_port = video_port; |
510 | if (budget->feeding) { | 543 | if (budget->feeding) { |
511 | int oldfeeding = budget->feeding; | ||
512 | budget->feeding = 1; | ||
513 | stop_ts_capture(budget); | 544 | stop_ts_capture(budget); |
514 | start_ts_capture(budget); | 545 | start_ts_capture(budget); |
515 | budget->feeding = oldfeeding; | ||
516 | } | 546 | } |
517 | spin_unlock(&budget->feedlock); | 547 | spin_unlock(&budget->feedlock); |
518 | } | 548 | } |
@@ -520,6 +550,7 @@ void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) | |||
520 | EXPORT_SYMBOL_GPL(ttpci_budget_debiread); | 550 | EXPORT_SYMBOL_GPL(ttpci_budget_debiread); |
521 | EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); | 551 | EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); |
522 | EXPORT_SYMBOL_GPL(ttpci_budget_init); | 552 | EXPORT_SYMBOL_GPL(ttpci_budget_init); |
553 | EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); | ||
523 | EXPORT_SYMBOL_GPL(ttpci_budget_deinit); | 554 | EXPORT_SYMBOL_GPL(ttpci_budget_deinit); |
524 | EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); | 555 | EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); |
525 | EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); | 556 | EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); |
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index ee60ce90a400..57227441891e 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
@@ -617,6 +617,8 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte | |||
617 | budget->dvb_adapter.priv = budget; | 617 | budget->dvb_adapter.priv = budget; |
618 | frontend_init(budget); | 618 | frontend_init(budget); |
619 | 619 | ||
620 | ttpci_budget_init_hooks(budget); | ||
621 | |||
620 | return 0; | 622 | return 0; |
621 | } | 623 | } |
622 | 624 | ||
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 35761f13c12b..863dffb4ed8e 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -375,9 +375,6 @@ static void frontend_init(struct budget *budget) | |||
375 | if (budget->dvb_frontend) { | 375 | if (budget->dvb_frontend) { |
376 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | 376 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
377 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; | 377 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
378 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
379 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
380 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
381 | break; | 378 | break; |
382 | } | 379 | } |
383 | break; | 380 | break; |
@@ -474,6 +471,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ | |||
474 | budget->dvb_adapter.priv = budget; | 471 | budget->dvb_adapter.priv = budget; |
475 | frontend_init(budget); | 472 | frontend_init(budget); |
476 | 473 | ||
474 | ttpci_budget_init_hooks(budget); | ||
475 | |||
477 | return 0; | 476 | return 0; |
478 | } | 477 | } |
479 | 478 | ||
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index ecea3a13030e..e8a5c79178e1 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h | |||
@@ -52,9 +52,6 @@ struct budget { | |||
52 | struct dmx_frontend hw_frontend; | 52 | struct dmx_frontend hw_frontend; |
53 | struct dmx_frontend mem_frontend; | 53 | struct dmx_frontend mem_frontend; |
54 | 54 | ||
55 | int fe_synced; | ||
56 | struct mutex pid_mutex; | ||
57 | |||
58 | int ci_present; | 55 | int ci_present; |
59 | int video_port; | 56 | int video_port; |
60 | 57 | ||
@@ -74,6 +71,9 @@ struct budget { | |||
74 | 71 | ||
75 | struct dvb_adapter dvb_adapter; | 72 | struct dvb_adapter dvb_adapter; |
76 | struct dvb_frontend *dvb_frontend; | 73 | struct dvb_frontend *dvb_frontend; |
74 | int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status); | ||
75 | int fe_synced; | ||
76 | |||
77 | void *priv; | 77 | void *priv; |
78 | }; | 78 | }; |
79 | 79 | ||
@@ -106,6 +106,7 @@ static struct saa7146_pci_extension_data x_var = { \ | |||
106 | extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | 106 | extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, |
107 | struct saa7146_pci_extension_data *info, | 107 | struct saa7146_pci_extension_data *info, |
108 | struct module *owner); | 108 | struct module *owner); |
109 | extern void ttpci_budget_init_hooks(struct budget *budget); | ||
109 | extern int ttpci_budget_deinit(struct budget *budget); | 110 | extern int ttpci_budget_deinit(struct budget *budget); |
110 | extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); | 111 | extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); |
111 | extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); | 112 | extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 6d532f170ce5..fe56862d51e4 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -145,7 +145,7 @@ config VIDEO_SAA5246A | |||
145 | 145 | ||
146 | config VIDEO_SAA5249 | 146 | config VIDEO_SAA5249 |
147 | tristate "SAA5249 Teletext processor" | 147 | tristate "SAA5249 Teletext processor" |
148 | depends on VIDEO_DEV && I2C | 148 | depends on VIDEO_DEV && I2C && VIDEO_V4L1 |
149 | help | 149 | help |
150 | Support for I2C bus based teletext using the SAA5249 chip. At the | 150 | Support for I2C bus based teletext using the SAA5249 chip. At the |
151 | moment this is only useful on some European WinTV cards. | 151 | moment this is only useful on some European WinTV cards. |
@@ -155,7 +155,7 @@ config VIDEO_SAA5249 | |||
155 | 155 | ||
156 | config TUNER_3036 | 156 | config TUNER_3036 |
157 | tristate "SAB3036 tuner" | 157 | tristate "SAB3036 tuner" |
158 | depends on VIDEO_DEV && I2C | 158 | depends on VIDEO_DEV && I2C && VIDEO_V4L1 |
159 | help | 159 | help |
160 | Say Y here to include support for Philips SAB3036 compatible tuners. | 160 | Say Y here to include support for Philips SAB3036 compatible tuners. |
161 | If in doubt, say N. | 161 | If in doubt, say N. |
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig index 153f6a4a96c9..cdcf55650714 100644 --- a/drivers/media/video/bt8xx/Kconfig +++ b/drivers/media/video/bt8xx/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_BT848 | 1 | config VIDEO_BT848 |
2 | tristate "BT848 Video For Linux" | 2 | tristate "BT848 Video For Linux" |
3 | depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 | 3 | depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L1 |
4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select VIDEO_BTCX | 6 | select VIDEO_BTCX |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 5764a89d3562..20dff7c316eb 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3923,7 +3923,12 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
3923 | goto err; | 3923 | goto err; |
3924 | printk(KERN_INFO "bttv%d: registered device video%d\n", | 3924 | printk(KERN_INFO "bttv%d: registered device video%d\n", |
3925 | btv->c.nr,btv->video_dev->minor & 0x1f); | 3925 | btv->c.nr,btv->video_dev->minor & 0x1f); |
3926 | video_device_create_file(btv->video_dev, &class_device_attr_card); | 3926 | if (class_device_create_file(&btv->video_dev->class_dev, |
3927 | &class_device_attr_card)<0) { | ||
3928 | printk(KERN_ERR "bttv%d: class_device_create_file 'card' " | ||
3929 | "failed\n", btv->c.nr); | ||
3930 | goto err; | ||
3931 | } | ||
3927 | 3932 | ||
3928 | /* vbi */ | 3933 | /* vbi */ |
3929 | btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); | 3934 | btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); |
@@ -4287,6 +4292,8 @@ static struct pci_driver bttv_pci_driver = { | |||
4287 | 4292 | ||
4288 | static int bttv_init_module(void) | 4293 | static int bttv_init_module(void) |
4289 | { | 4294 | { |
4295 | int ret; | ||
4296 | |||
4290 | bttv_num = 0; | 4297 | bttv_num = 0; |
4291 | 4298 | ||
4292 | printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n", | 4299 | printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n", |
@@ -4308,7 +4315,11 @@ static int bttv_init_module(void) | |||
4308 | 4315 | ||
4309 | bttv_check_chipset(); | 4316 | bttv_check_chipset(); |
4310 | 4317 | ||
4311 | bus_register(&bttv_sub_bus_type); | 4318 | ret = bus_register(&bttv_sub_bus_type); |
4319 | if (ret < 0) { | ||
4320 | printk(KERN_WARNING "bttv: bus_register error: %d\n", ret); | ||
4321 | return ret; | ||
4322 | } | ||
4312 | return pci_register_driver(&bttv_pci_driver); | 4323 | return pci_register_driver(&bttv_pci_driver); |
4313 | } | 4324 | } |
4314 | 4325 | ||
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 8c9f0f7cf467..63676e7bd635 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c | |||
@@ -31,11 +31,16 @@ | |||
31 | #include <asm/io.h> | 31 | #include <asm/io.h> |
32 | #include "bttvp.h" | 32 | #include "bttvp.h" |
33 | 33 | ||
34 | /* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate: | 34 | /* Offset from line sync pulse leading edge (0H) to start of VBI capture, |
35 | bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC | 35 | in fCLKx2 pixels. According to the datasheet, VBI capture starts |
36 | HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge | 36 | VBI_HDELAY fCLKx1 pixels from the tailing edgeof /HRESET, and /HRESET |
37 | of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */ | 37 | is 64 fCLKx1 pixels wide. VBI_HDELAY is set to 0, so this should be |
38 | #define VBI_OFFSET ((64 + 0) * 2) | 38 | (64 + 0) * 2 = 128 fCLKx2 pixels. But it's not! The datasheet is |
39 | Just Plain Wrong. The real value appears to be different for | ||
40 | different revisions of the bt8x8 chips, and to be affected by the | ||
41 | horizontal scaling factor. Experimentally, the value is measured | ||
42 | to be about 244. */ | ||
43 | #define VBI_OFFSET 244 | ||
39 | 44 | ||
40 | #define VBI_DEFLINES 16 | 45 | #define VBI_DEFLINES 16 |
41 | #define VBI_MAXLINES 32 | 46 | #define VBI_MAXLINES 32 |
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 353d02b67c33..9dddff42ec13 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -490,6 +490,23 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user | |||
490 | return 0; | 490 | return 0; |
491 | } | 491 | } |
492 | 492 | ||
493 | struct video_code32 | ||
494 | { | ||
495 | char loadwhat[16]; /* name or tag of file being passed */ | ||
496 | compat_int_t datasize; | ||
497 | unsigned char *data; | ||
498 | }; | ||
499 | |||
500 | static inline int microcode32(struct video_code *kp, struct video_code32 __user *up) | ||
501 | { | ||
502 | if(!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || | ||
503 | copy_from_user(kp->loadwhat, up->loadwhat, sizeof (up->loadwhat)) || | ||
504 | get_user(kp->datasize, &up->datasize) || | ||
505 | copy_from_user(kp->data, up->data, up->datasize)) | ||
506 | return -EFAULT; | ||
507 | return 0; | ||
508 | } | ||
509 | |||
493 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) | 510 | #define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) |
494 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) | 511 | #define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) |
495 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) | 512 | #define VIDIOCGWIN32 _IOR('v',9, struct video_window32) |
@@ -498,6 +515,7 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user | |||
498 | #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) | 515 | #define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) |
499 | #define VIDIOCGFREQ32 _IOR('v',14, u32) | 516 | #define VIDIOCGFREQ32 _IOR('v',14, u32) |
500 | #define VIDIOCSFREQ32 _IOW('v',15, u32) | 517 | #define VIDIOCSFREQ32 _IOW('v',15, u32) |
518 | #define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32) | ||
501 | 519 | ||
502 | /* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */ | 520 | /* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */ |
503 | #define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4) | 521 | #define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4) |
@@ -590,6 +608,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
590 | struct video_tuner vt; | 608 | struct video_tuner vt; |
591 | struct video_buffer vb; | 609 | struct video_buffer vb; |
592 | struct video_window vw; | 610 | struct video_window vw; |
611 | struct video_code vc; | ||
593 | struct v4l2_format v2f; | 612 | struct v4l2_format v2f; |
594 | struct v4l2_buffer v2b; | 613 | struct v4l2_buffer v2b; |
595 | struct v4l2_framebuffer v2fb; | 614 | struct v4l2_framebuffer v2fb; |
@@ -628,6 +647,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
628 | case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; | 647 | case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; |
629 | case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; | 648 | case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; |
630 | case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; | 649 | case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; |
650 | case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; | ||
631 | }; | 651 | }; |
632 | 652 | ||
633 | switch(cmd) { | 653 | switch(cmd) { |
@@ -703,6 +723,10 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg | |||
703 | case VIDIOC_G_FBUF: | 723 | case VIDIOC_G_FBUF: |
704 | case VIDIOC_G_INPUT: | 724 | case VIDIOC_G_INPUT: |
705 | compatible_arg = 0; | 725 | compatible_arg = 0; |
726 | case VIDIOCSMICROCODE: | ||
727 | err = microcode32(&karg.vc, up); | ||
728 | compatible_arg = 0; | ||
729 | break; | ||
706 | }; | 730 | }; |
707 | 731 | ||
708 | if(err) | 732 | if(err) |
diff --git a/drivers/media/video/cpia2/Kconfig b/drivers/media/video/cpia2/Kconfig index 513cc0927389..e39a96152004 100644 --- a/drivers/media/video/cpia2/Kconfig +++ b/drivers/media/video/cpia2/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_CPIA2 | 1 | config VIDEO_CPIA2 |
2 | tristate "CPiA2 Video For Linux" | 2 | tristate "CPiA2 Video For Linux" |
3 | depends on VIDEO_DEV && USB | 3 | depends on VIDEO_DEV && USB && VIDEO_V4L1 |
4 | ---help--- | 4 | ---help--- |
5 | This is the video4linux driver for cameras based on Vision's CPiA2 | 5 | This is the video4linux driver for cameras based on Vision's CPiA2 |
6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 | 6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 72b630a91f41..c25564648993 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -89,7 +89,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
89 | 89 | ||
90 | auxgpio = cx_read(MO_GP1_IO); | 90 | auxgpio = cx_read(MO_GP1_IO); |
91 | /* Take out the parity part */ | 91 | /* Take out the parity part */ |
92 | gpio+=(gpio & 0x7fd) + (auxgpio & 0xef); | 92 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); |
93 | } else | 93 | } else |
94 | auxgpio = gpio; | 94 | auxgpio = gpio; |
95 | 95 | ||
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 2225d4b94140..547cdbdb644d 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1180,7 +1180,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1180 | V4L2_CAP_READWRITE | | 1180 | V4L2_CAP_READWRITE | |
1181 | V4L2_CAP_STREAMING | | 1181 | V4L2_CAP_STREAMING | |
1182 | V4L2_CAP_VBI_CAPTURE | | 1182 | V4L2_CAP_VBI_CAPTURE | |
1183 | V4L2_CAP_VIDEO_OVERLAY | | ||
1184 | 0; | 1183 | 0; |
1185 | if (UNSET != core->tuner_type) | 1184 | if (UNSET != core->tuner_type) |
1186 | cap->capabilities |= V4L2_CAP_TUNER; | 1185 | cap->capabilities |= V4L2_CAP_TUNER; |
@@ -1226,7 +1225,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1226 | struct v4l2_format *f = arg; | 1225 | struct v4l2_format *f = arg; |
1227 | return cx8800_try_fmt(dev,fh,f); | 1226 | return cx8800_try_fmt(dev,fh,f); |
1228 | } | 1227 | } |
1229 | #ifdef HAVE_V4L1 | 1228 | #ifdef CONFIG_V4L1_COMPAT |
1230 | /* --- streaming capture ------------------------------------- */ | 1229 | /* --- streaming capture ------------------------------------- */ |
1231 | case VIDIOCGMBUF: | 1230 | case VIDIOCGMBUF: |
1232 | { | 1231 | { |
@@ -1585,7 +1584,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1585 | *id = 0; | 1584 | *id = 0; |
1586 | return 0; | 1585 | return 0; |
1587 | } | 1586 | } |
1588 | #ifdef HAVE_V4L1 | 1587 | #ifdef CONFIG_V4L1_COMPAT |
1589 | case VIDIOCSTUNER: | 1588 | case VIDIOCSTUNER: |
1590 | { | 1589 | { |
1591 | struct video_tuner *v = arg; | 1590 | struct video_tuner *v = arg; |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index dbb75a7db199..56246b8578f3 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -362,7 +362,7 @@ int msp_sleep(struct msp_state *state, int timeout) | |||
362 | } | 362 | } |
363 | 363 | ||
364 | /* ------------------------------------------------------------------------ */ | 364 | /* ------------------------------------------------------------------------ */ |
365 | 365 | #ifdef CONFIG_VIDEO_V4L1 | |
366 | static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) | 366 | static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) |
367 | { | 367 | { |
368 | if (rxsubchans == V4L2_TUNER_SUB_MONO) | 368 | if (rxsubchans == V4L2_TUNER_SUB_MONO) |
@@ -384,6 +384,7 @@ static int msp_mode_v4l1_to_v4l2(int mode) | |||
384 | return V4L2_TUNER_MODE_LANG1; | 384 | return V4L2_TUNER_MODE_LANG1; |
385 | return V4L2_TUNER_MODE_MONO; | 385 | return V4L2_TUNER_MODE_MONO; |
386 | } | 386 | } |
387 | #endif | ||
387 | 388 | ||
388 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) | 389 | static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) |
389 | { | 390 | { |
@@ -509,6 +510,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
509 | /* --- v4l ioctls --- */ | 510 | /* --- v4l ioctls --- */ |
510 | /* take care: bttv does userspace copying, we'll get a | 511 | /* take care: bttv does userspace copying, we'll get a |
511 | kernel pointer here... */ | 512 | kernel pointer here... */ |
513 | #ifdef CONFIG_VIDEO_V4L1 | ||
512 | case VIDIOCGAUDIO: | 514 | case VIDIOCGAUDIO: |
513 | { | 515 | { |
514 | struct video_audio *va = arg; | 516 | struct video_audio *va = arg; |
@@ -577,6 +579,12 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
577 | } | 579 | } |
578 | 580 | ||
579 | case VIDIOCSFREQ: | 581 | case VIDIOCSFREQ: |
582 | { | ||
583 | /* new channel -- kick audio carrier scan */ | ||
584 | msp_wake_thread(client); | ||
585 | break; | ||
586 | } | ||
587 | #endif | ||
580 | case VIDIOC_S_FREQUENCY: | 588 | case VIDIOC_S_FREQUENCY: |
581 | { | 589 | { |
582 | /* new channel -- kick audio carrier scan */ | 590 | /* new channel -- kick audio carrier scan */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 9b48abcf6089..be1e5cc78081 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -852,7 +852,6 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) | |||
852 | return hdw->serial_number; | 852 | return hdw->serial_number; |
853 | } | 853 | } |
854 | 854 | ||
855 | |||
856 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) | 855 | int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) |
857 | { | 856 | { |
858 | return hdw->unit_number; | 857 | return hdw->unit_number; |
@@ -2318,7 +2317,6 @@ void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw) | |||
2318 | } | 2317 | } |
2319 | } | 2318 | } |
2320 | 2319 | ||
2321 | |||
2322 | /* Return name for this driver instance */ | 2320 | /* Return name for this driver instance */ |
2323 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) | 2321 | const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) |
2324 | { | 2322 | { |
@@ -2542,6 +2540,10 @@ static void pvr2_ctl_timeout(unsigned long data) | |||
2542 | } | 2540 | } |
2543 | 2541 | ||
2544 | 2542 | ||
2543 | /* Issue a command and get a response from the device. This extended | ||
2544 | version includes a probe flag (which if set means that device errors | ||
2545 | should not be logged or treated as fatal) and a timeout in jiffies. | ||
2546 | This can be used to non-lethally probe the health of endpoint 1. */ | ||
2545 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | 2547 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, |
2546 | unsigned int timeout,int probe_fl, | 2548 | unsigned int timeout,int probe_fl, |
2547 | void *write_data,unsigned int write_len, | 2549 | void *write_data,unsigned int write_len, |
@@ -2970,6 +2972,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) | |||
2970 | } | 2972 | } |
2971 | 2973 | ||
2972 | 2974 | ||
2975 | /* Stop / start video stream transport */ | ||
2973 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | 2976 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) |
2974 | { | 2977 | { |
2975 | int status; | 2978 | int status; |
@@ -3068,6 +3071,7 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) | |||
3068 | } | 3071 | } |
3069 | 3072 | ||
3070 | 3073 | ||
3074 | /* Find I2C address of eeprom */ | ||
3071 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) | 3075 | static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) |
3072 | { | 3076 | { |
3073 | int result; | 3077 | int result; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c index 681f79c8064e..1e393762546c 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.c +++ b/drivers/media/video/pvrusb2/pvrusb2-io.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | 28 | ||
29 | static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); | ||
30 | |||
29 | #define BUFFER_SIG 0x47653271 | 31 | #define BUFFER_SIG 0x47653271 |
30 | 32 | ||
31 | // #define SANITY_CHECK_BUFFERS | 33 | // #define SANITY_CHECK_BUFFERS |
@@ -515,6 +517,10 @@ void pvr2_stream_set_callback(struct pvr2_stream *sp, | |||
515 | } | 517 | } |
516 | 518 | ||
517 | /* Query / set the nominal buffer count */ | 519 | /* Query / set the nominal buffer count */ |
520 | int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) | ||
521 | { | ||
522 | return sp->buffer_target_count; | ||
523 | } | ||
518 | 524 | ||
519 | int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) | 525 | int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) |
520 | { | 526 | { |
@@ -553,7 +559,6 @@ int pvr2_stream_get_ready_count(struct pvr2_stream *sp) | |||
553 | return sp->r_count; | 559 | return sp->r_count; |
554 | } | 560 | } |
555 | 561 | ||
556 | |||
557 | void pvr2_stream_kill(struct pvr2_stream *sp) | 562 | void pvr2_stream_kill(struct pvr2_stream *sp) |
558 | { | 563 | { |
559 | struct pvr2_buffer *bp; | 564 | struct pvr2_buffer *bp; |
@@ -607,7 +612,6 @@ int pvr2_buffer_queue(struct pvr2_buffer *bp) | |||
607 | return ret; | 612 | return ret; |
608 | } | 613 | } |
609 | 614 | ||
610 | |||
611 | int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) | 615 | int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) |
612 | { | 616 | { |
613 | int ret = 0; | 617 | int ret = 0; |
@@ -646,7 +650,6 @@ int pvr2_buffer_get_status(struct pvr2_buffer *bp) | |||
646 | return bp->status; | 650 | return bp->status; |
647 | } | 651 | } |
648 | 652 | ||
649 | |||
650 | int pvr2_buffer_get_id(struct pvr2_buffer *bp) | 653 | int pvr2_buffer_get_id(struct pvr2_buffer *bp) |
651 | { | 654 | { |
652 | return bp->id; | 655 | return bp->id; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h index 96285ad234a6..93279cc2a35e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.h +++ b/drivers/media/video/pvrusb2/pvrusb2-io.h | |||
@@ -47,6 +47,7 @@ void pvr2_stream_set_callback(struct pvr2_stream *, | |||
47 | void *data); | 47 | void *data); |
48 | 48 | ||
49 | /* Query / set the nominal buffer count */ | 49 | /* Query / set the nominal buffer count */ |
50 | int pvr2_stream_get_buffer_count(struct pvr2_stream *); | ||
50 | int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); | 51 | int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); |
51 | 52 | ||
52 | /* Get a pointer to a buffer that is either idle, ready, or is specified | 53 | /* Get a pointer to a buffer that is either idle, ready, or is specified |
@@ -58,6 +59,7 @@ struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id); | |||
58 | /* Find out how many buffers are idle or ready */ | 59 | /* Find out how many buffers are idle or ready */ |
59 | int pvr2_stream_get_ready_count(struct pvr2_stream *); | 60 | int pvr2_stream_get_ready_count(struct pvr2_stream *); |
60 | 61 | ||
62 | |||
61 | /* Kill all pending buffers and throw away any ready buffers as well */ | 63 | /* Kill all pending buffers and throw away any ready buffers as well */ |
62 | void pvr2_stream_kill(struct pvr2_stream *); | 64 | void pvr2_stream_kill(struct pvr2_stream *); |
63 | 65 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c index f7a2e225a002..b71f9a961f8a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c | |||
@@ -213,7 +213,9 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) | |||
213 | " pvr2_ioread_setup (tear-down) id=%p",cp); | 213 | " pvr2_ioread_setup (tear-down) id=%p",cp); |
214 | pvr2_ioread_stop(cp); | 214 | pvr2_ioread_stop(cp); |
215 | pvr2_stream_kill(cp->stream); | 215 | pvr2_stream_kill(cp->stream); |
216 | pvr2_stream_set_buffer_count(cp->stream,0); | 216 | if (pvr2_stream_get_buffer_count(cp->stream)) { |
217 | pvr2_stream_set_buffer_count(cp->stream,0); | ||
218 | } | ||
217 | cp->stream = NULL; | 219 | cp->stream = NULL; |
218 | } | 220 | } |
219 | if (sp) { | 221 | if (sp) { |
@@ -251,7 +253,6 @@ int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) | |||
251 | return ret; | 253 | return ret; |
252 | } | 254 | } |
253 | 255 | ||
254 | |||
255 | static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) | 256 | static int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) |
256 | { | 257 | { |
257 | int stat; | 258 | int stat; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 6af55a8b6f05..d1dda5caf406 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -44,12 +44,16 @@ struct pvr2_sysfs { | |||
44 | struct kobj_type ktype; | 44 | struct kobj_type ktype; |
45 | struct class_device_attribute attr_v4l_minor_number; | 45 | struct class_device_attribute attr_v4l_minor_number; |
46 | struct class_device_attribute attr_unit_number; | 46 | struct class_device_attribute attr_unit_number; |
47 | int v4l_minor_number_created_ok; | ||
48 | int unit_number_created_ok; | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | 51 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC |
50 | struct pvr2_sysfs_debugifc { | 52 | struct pvr2_sysfs_debugifc { |
51 | struct class_device_attribute attr_debugcmd; | 53 | struct class_device_attribute attr_debugcmd; |
52 | struct class_device_attribute attr_debuginfo; | 54 | struct class_device_attribute attr_debuginfo; |
55 | int debugcmd_created_ok; | ||
56 | int debuginfo_created_ok; | ||
53 | }; | 57 | }; |
54 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | 58 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ |
55 | 59 | ||
@@ -67,6 +71,7 @@ struct pvr2_sysfs_ctl_item { | |||
67 | struct pvr2_sysfs_ctl_item *item_next; | 71 | struct pvr2_sysfs_ctl_item *item_next; |
68 | struct attribute *attr_gen[7]; | 72 | struct attribute *attr_gen[7]; |
69 | struct attribute_group grp; | 73 | struct attribute_group grp; |
74 | int created_ok; | ||
70 | char name[80]; | 75 | char name[80]; |
71 | }; | 76 | }; |
72 | 77 | ||
@@ -487,6 +492,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
487 | struct pvr2_sysfs_func_set *fp; | 492 | struct pvr2_sysfs_func_set *fp; |
488 | struct pvr2_ctrl *cptr; | 493 | struct pvr2_ctrl *cptr; |
489 | unsigned int cnt,acnt; | 494 | unsigned int cnt,acnt; |
495 | int ret; | ||
490 | 496 | ||
491 | if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { | 497 | if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { |
492 | return; | 498 | return; |
@@ -589,7 +595,13 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
589 | cip->grp.name = cip->name; | 595 | cip->grp.name = cip->name; |
590 | cip->grp.attrs = cip->attr_gen; | 596 | cip->grp.attrs = cip->attr_gen; |
591 | 597 | ||
592 | sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); | 598 | ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); |
599 | if (ret) { | ||
600 | printk(KERN_WARNING "%s: sysfs_create_group error: %d\n", | ||
601 | __FUNCTION__, ret); | ||
602 | return; | ||
603 | } | ||
604 | cip->created_ok = !0; | ||
593 | } | 605 | } |
594 | 606 | ||
595 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | 607 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC |
@@ -600,6 +612,8 @@ static ssize_t debugcmd_store(struct class_device *,const char *,size_t count); | |||
600 | static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) | 612 | static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) |
601 | { | 613 | { |
602 | struct pvr2_sysfs_debugifc *dip; | 614 | struct pvr2_sysfs_debugifc *dip; |
615 | int ret; | ||
616 | |||
603 | dip = kmalloc(sizeof(*dip),GFP_KERNEL); | 617 | dip = kmalloc(sizeof(*dip),GFP_KERNEL); |
604 | if (!dip) return; | 618 | if (!dip) return; |
605 | memset(dip,0,sizeof(*dip)); | 619 | memset(dip,0,sizeof(*dip)); |
@@ -613,17 +627,34 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) | |||
613 | dip->attr_debuginfo.attr.mode = S_IRUGO; | 627 | dip->attr_debuginfo.attr.mode = S_IRUGO; |
614 | dip->attr_debuginfo.show = debuginfo_show; | 628 | dip->attr_debuginfo.show = debuginfo_show; |
615 | sfp->debugifc = dip; | 629 | sfp->debugifc = dip; |
616 | class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); | 630 | ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); |
617 | class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); | 631 | if (ret < 0) { |
632 | printk(KERN_WARNING "%s: class_device_create_file error: %d\n", | ||
633 | __FUNCTION__, ret); | ||
634 | } else { | ||
635 | dip->debugcmd_created_ok = !0; | ||
636 | } | ||
637 | ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); | ||
638 | if (ret < 0) { | ||
639 | printk(KERN_WARNING "%s: class_device_create_file error: %d\n", | ||
640 | __FUNCTION__, ret); | ||
641 | } else { | ||
642 | dip->debuginfo_created_ok = !0; | ||
643 | } | ||
618 | } | 644 | } |
619 | 645 | ||
620 | 646 | ||
621 | static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) | 647 | static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) |
622 | { | 648 | { |
623 | if (!sfp->debugifc) return; | 649 | if (!sfp->debugifc) return; |
624 | class_device_remove_file(sfp->class_dev, | 650 | if (sfp->debugifc->debuginfo_created_ok) { |
625 | &sfp->debugifc->attr_debuginfo); | 651 | class_device_remove_file(sfp->class_dev, |
626 | class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd); | 652 | &sfp->debugifc->attr_debuginfo); |
653 | } | ||
654 | if (sfp->debugifc->debugcmd_created_ok) { | ||
655 | class_device_remove_file(sfp->class_dev, | ||
656 | &sfp->debugifc->attr_debugcmd); | ||
657 | } | ||
627 | kfree(sfp->debugifc); | 658 | kfree(sfp->debugifc); |
628 | sfp->debugifc = NULL; | 659 | sfp->debugifc = NULL; |
629 | } | 660 | } |
@@ -645,7 +676,9 @@ static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) | |||
645 | struct pvr2_sysfs_ctl_item *cip1,*cip2; | 676 | struct pvr2_sysfs_ctl_item *cip1,*cip2; |
646 | for (cip1 = sfp->item_first; cip1; cip1 = cip2) { | 677 | for (cip1 = sfp->item_first; cip1; cip1 = cip2) { |
647 | cip2 = cip1->item_next; | 678 | cip2 = cip1->item_next; |
648 | sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); | 679 | if (cip1->created_ok) { |
680 | sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); | ||
681 | } | ||
649 | pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); | 682 | pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); |
650 | kfree(cip1); | 683 | kfree(cip1); |
651 | } | 684 | } |
@@ -675,8 +708,14 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp) | |||
675 | pvr2_sysfs_tear_down_debugifc(sfp); | 708 | pvr2_sysfs_tear_down_debugifc(sfp); |
676 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ | 709 | #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ |
677 | pvr2_sysfs_tear_down_controls(sfp); | 710 | pvr2_sysfs_tear_down_controls(sfp); |
678 | class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number); | 711 | if (sfp->v4l_minor_number_created_ok) { |
679 | class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number); | 712 | class_device_remove_file(sfp->class_dev, |
713 | &sfp->attr_v4l_minor_number); | ||
714 | } | ||
715 | if (sfp->unit_number_created_ok) { | ||
716 | class_device_remove_file(sfp->class_dev, | ||
717 | &sfp->attr_unit_number); | ||
718 | } | ||
680 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); | 719 | pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); |
681 | sfp->class_dev->class_data = NULL; | 720 | sfp->class_dev->class_data = NULL; |
682 | class_device_unregister(sfp->class_dev); | 721 | class_device_unregister(sfp->class_dev); |
@@ -709,6 +748,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
709 | { | 748 | { |
710 | struct usb_device *usb_dev; | 749 | struct usb_device *usb_dev; |
711 | struct class_device *class_dev; | 750 | struct class_device *class_dev; |
751 | int ret; | ||
752 | |||
712 | usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); | 753 | usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); |
713 | if (!usb_dev) return; | 754 | if (!usb_dev) return; |
714 | class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); | 755 | class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); |
@@ -733,20 +774,40 @@ static void class_dev_create(struct pvr2_sysfs *sfp, | |||
733 | 774 | ||
734 | sfp->class_dev = class_dev; | 775 | sfp->class_dev = class_dev; |
735 | class_dev->class_data = sfp; | 776 | class_dev->class_data = sfp; |
736 | class_device_register(class_dev); | 777 | ret = class_device_register(class_dev); |
778 | if (ret) { | ||
779 | printk(KERN_ERR "%s: class_device_register failed\n", | ||
780 | __FUNCTION__); | ||
781 | kfree(class_dev); | ||
782 | return; | ||
783 | } | ||
737 | 784 | ||
738 | sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; | 785 | sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; |
739 | sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; | 786 | sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; |
740 | sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; | 787 | sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; |
741 | sfp->attr_v4l_minor_number.show = v4l_minor_number_show; | 788 | sfp->attr_v4l_minor_number.show = v4l_minor_number_show; |
742 | sfp->attr_v4l_minor_number.store = NULL; | 789 | sfp->attr_v4l_minor_number.store = NULL; |
743 | class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); | 790 | ret = class_device_create_file(sfp->class_dev, |
791 | &sfp->attr_v4l_minor_number); | ||
792 | if (ret < 0) { | ||
793 | printk(KERN_WARNING "%s: class_device_create_file error: %d\n", | ||
794 | __FUNCTION__, ret); | ||
795 | } else { | ||
796 | sfp->v4l_minor_number_created_ok = !0; | ||
797 | } | ||
798 | |||
744 | sfp->attr_unit_number.attr.owner = THIS_MODULE; | 799 | sfp->attr_unit_number.attr.owner = THIS_MODULE; |
745 | sfp->attr_unit_number.attr.name = "unit_number"; | 800 | sfp->attr_unit_number.attr.name = "unit_number"; |
746 | sfp->attr_unit_number.attr.mode = S_IRUGO; | 801 | sfp->attr_unit_number.attr.mode = S_IRUGO; |
747 | sfp->attr_unit_number.show = unit_number_show; | 802 | sfp->attr_unit_number.show = unit_number_show; |
748 | sfp->attr_unit_number.store = NULL; | 803 | sfp->attr_unit_number.store = NULL; |
749 | class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); | 804 | ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); |
805 | if (ret < 0) { | ||
806 | printk(KERN_WARNING "%s: class_device_create_file error: %d\n", | ||
807 | __FUNCTION__, ret); | ||
808 | } else { | ||
809 | sfp->unit_number_created_ok = !0; | ||
810 | } | ||
750 | 811 | ||
751 | pvr2_sysfs_add_controls(sfp); | 812 | pvr2_sysfs_add_controls(sfp); |
752 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC | 813 | #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index f1fd69e7f119..d73cff1970ae 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -997,9 +997,9 @@ static int saa7134_alsa_init(void) | |||
997 | struct saa7134_dev *dev = NULL; | 997 | struct saa7134_dev *dev = NULL; |
998 | struct list_head *list; | 998 | struct list_head *list; |
999 | 999 | ||
1000 | if (!dmasound_init && !dmasound_exit) { | 1000 | if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { |
1001 | dmasound_init = alsa_device_init; | 1001 | saa7134_dmasound_init = alsa_device_init; |
1002 | dmasound_exit = alsa_device_exit; | 1002 | saa7134_dmasound_exit = alsa_device_exit; |
1003 | } else { | 1003 | } else { |
1004 | printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); | 1004 | printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); |
1005 | return -EBUSY; | 1005 | return -EBUSY; |
@@ -1036,8 +1036,8 @@ static void saa7134_alsa_exit(void) | |||
1036 | snd_card_free(snd_saa7134_cards[idx]); | 1036 | snd_card_free(snd_saa7134_cards[idx]); |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | dmasound_init = NULL; | 1039 | saa7134_dmasound_init = NULL; |
1040 | dmasound_exit = NULL; | 1040 | saa7134_dmasound_exit = NULL; |
1041 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); | 1041 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); |
1042 | 1042 | ||
1043 | return; | 1043 | return; |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 6e97cc84ba89..be3a81fc90a2 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -95,8 +95,8 @@ LIST_HEAD(saa7134_devlist); | |||
95 | static LIST_HEAD(mops_list); | 95 | static LIST_HEAD(mops_list); |
96 | static unsigned int saa7134_devcount; | 96 | static unsigned int saa7134_devcount; |
97 | 97 | ||
98 | int (*dmasound_init)(struct saa7134_dev *dev); | 98 | int (*saa7134_dmasound_init)(struct saa7134_dev *dev); |
99 | int (*dmasound_exit)(struct saa7134_dev *dev); | 99 | int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); |
100 | 100 | ||
101 | #define dprintk(fmt, arg...) if (core_debug) \ | 101 | #define dprintk(fmt, arg...) if (core_debug) \ |
102 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) | 102 | printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) |
@@ -1008,8 +1008,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1008 | /* check for signal */ | 1008 | /* check for signal */ |
1009 | saa7134_irq_video_intl(dev); | 1009 | saa7134_irq_video_intl(dev); |
1010 | 1010 | ||
1011 | if (dmasound_init && !dev->dmasound.priv_data) { | 1011 | if (saa7134_dmasound_init && !dev->dmasound.priv_data) { |
1012 | dmasound_init(dev); | 1012 | saa7134_dmasound_init(dev); |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | return 0; | 1015 | return 0; |
@@ -1036,8 +1036,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1036 | struct saa7134_mpeg_ops *mops; | 1036 | struct saa7134_mpeg_ops *mops; |
1037 | 1037 | ||
1038 | /* Release DMA sound modules if present */ | 1038 | /* Release DMA sound modules if present */ |
1039 | if (dmasound_exit && dev->dmasound.priv_data) { | 1039 | if (saa7134_dmasound_exit && dev->dmasound.priv_data) { |
1040 | dmasound_exit(dev); | 1040 | saa7134_dmasound_exit(dev); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | /* debugging ... */ | 1043 | /* debugging ... */ |
@@ -1169,8 +1169,8 @@ EXPORT_SYMBOL(saa7134_boards); | |||
1169 | 1169 | ||
1170 | /* ----------------- for the DMA sound modules --------------- */ | 1170 | /* ----------------- for the DMA sound modules --------------- */ |
1171 | 1171 | ||
1172 | EXPORT_SYMBOL(dmasound_init); | 1172 | EXPORT_SYMBOL(saa7134_dmasound_init); |
1173 | EXPORT_SYMBOL(dmasound_exit); | 1173 | EXPORT_SYMBOL(saa7134_dmasound_exit); |
1174 | EXPORT_SYMBOL(saa7134_pgtable_free); | 1174 | EXPORT_SYMBOL(saa7134_pgtable_free); |
1175 | EXPORT_SYMBOL(saa7134_pgtable_build); | 1175 | EXPORT_SYMBOL(saa7134_pgtable_build); |
1176 | EXPORT_SYMBOL(saa7134_pgtable_alloc); | 1176 | EXPORT_SYMBOL(saa7134_pgtable_alloc); |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 3895d05804ae..2e3ba5f31453 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
@@ -993,9 +993,9 @@ static int saa7134_oss_init(void) | |||
993 | struct saa7134_dev *dev = NULL; | 993 | struct saa7134_dev *dev = NULL; |
994 | struct list_head *list; | 994 | struct list_head *list; |
995 | 995 | ||
996 | if (!dmasound_init && !dmasound_exit) { | 996 | if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { |
997 | dmasound_init = oss_device_init; | 997 | saa7134_dmasound_init = oss_device_init; |
998 | dmasound_exit = oss_device_exit; | 998 | saa7134_dmasound_exit = oss_device_exit; |
999 | } else { | 999 | } else { |
1000 | printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n"); | 1000 | printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n"); |
1001 | return -EBUSY; | 1001 | return -EBUSY; |
@@ -1037,8 +1037,8 @@ static void saa7134_oss_exit(void) | |||
1037 | 1037 | ||
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | dmasound_init = NULL; | 1040 | saa7134_dmasound_init = NULL; |
1041 | dmasound_exit = NULL; | 1041 | saa7134_dmasound_exit = NULL; |
1042 | 1042 | ||
1043 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); | 1043 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); |
1044 | 1044 | ||
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index e4156ec9c6d7..8656f2400e18 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | static unsigned int video_debug = 0; | 41 | static unsigned int video_debug = 0; |
42 | static unsigned int gbuffers = 8; | 42 | static unsigned int gbuffers = 8; |
43 | static unsigned int noninterlaced = 0; | 43 | static unsigned int noninterlaced = 1; |
44 | static unsigned int gbufsize = 720*576*4; | 44 | static unsigned int gbufsize = 720*576*4; |
45 | static unsigned int gbufsize_max = 720*576*4; | 45 | static unsigned int gbufsize_max = 720*576*4; |
46 | module_param(video_debug, int, 0644); | 46 | module_param(video_debug, int, 0644); |
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); | |||
48 | module_param(gbuffers, int, 0444); | 48 | module_param(gbuffers, int, 0444); |
49 | MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32"); | 49 | MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32"); |
50 | module_param(noninterlaced, int, 0644); | 50 | module_param(noninterlaced, int, 0644); |
51 | MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced"); | 51 | MODULE_PARM_DESC(noninterlaced,"capture non interlaced video"); |
52 | 52 | ||
53 | #define dprintk(fmt, arg...) if (video_debug) \ | 53 | #define dprintk(fmt, arg...) if (video_debug) \ |
54 | printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) | 54 | printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) |
@@ -2087,7 +2087,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
2087 | struct v4l2_format *f = arg; | 2087 | struct v4l2_format *f = arg; |
2088 | return saa7134_try_fmt(dev,fh,f); | 2088 | return saa7134_try_fmt(dev,fh,f); |
2089 | } | 2089 | } |
2090 | #ifdef HAVE_V4L1 | 2090 | #ifdef CONFIG_V4L1_COMPAT |
2091 | case VIDIOCGMBUF: | 2091 | case VIDIOCGMBUF: |
2092 | { | 2092 | { |
2093 | struct video_mbuf *mbuf = arg; | 2093 | struct video_mbuf *mbuf = arg; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index d5ee99c574cc..c04ce6152fd5 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -586,8 +586,8 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf); | |||
586 | 586 | ||
587 | int saa7134_set_dmabits(struct saa7134_dev *dev); | 587 | int saa7134_set_dmabits(struct saa7134_dev *dev); |
588 | 588 | ||
589 | extern int (*dmasound_init)(struct saa7134_dev *dev); | 589 | extern int (*saa7134_dmasound_init)(struct saa7134_dev *dev); |
590 | extern int (*dmasound_exit)(struct saa7134_dev *dev); | 590 | extern int (*saa7134_dmasound_exit)(struct saa7134_dev *dev); |
591 | 591 | ||
592 | 592 | ||
593 | /* ----------------------------------------------------------- */ | 593 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index b36ba9fa3a28..5686547ba76a 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -2181,7 +2181,6 @@ static struct pci_device_id stradis_pci_tbl[] = { | |||
2181 | { 0 } | 2181 | { 0 } |
2182 | }; | 2182 | }; |
2183 | 2183 | ||
2184 | MODULE_DEVICE_TABLE(pci, stradis_pci_tbl); | ||
2185 | 2184 | ||
2186 | static struct pci_driver stradis_driver = { | 2185 | static struct pci_driver stradis_driver = { |
2187 | .name = "stradis", | 2186 | .name = "stradis", |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index f7eb402d5f2b..40590bae5ff7 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -196,14 +196,6 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
196 | i2c_master_send(c, buffer, 4); | 196 | i2c_master_send(c, buffer, 4); |
197 | default_tuner_init(c); | 197 | default_tuner_init(c); |
198 | break; | 198 | break; |
199 | case TUNER_LG_TDVS_H06XF: | ||
200 | /* Set the Auxiliary Byte. */ | ||
201 | buffer[2] &= ~0x20; | ||
202 | buffer[2] |= 0x18; | ||
203 | buffer[3] = 0x20; | ||
204 | i2c_master_send(c, buffer, 4); | ||
205 | default_tuner_init(c); | ||
206 | break; | ||
207 | case TUNER_PHILIPS_TD1316: | 199 | case TUNER_PHILIPS_TD1316: |
208 | buffer[0] = 0x0b; | 200 | buffer[0] = 0x0b; |
209 | buffer[1] = 0xdc; | 201 | buffer[1] = 0xdc; |
@@ -598,6 +590,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
598 | if (t->standby) | 590 | if (t->standby) |
599 | t->standby (client); | 591 | t->standby (client); |
600 | break; | 592 | break; |
593 | #ifdef CONFIG_VIDEO_V4L1 | ||
601 | case VIDIOCSAUDIO: | 594 | case VIDIOCSAUDIO: |
602 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | 595 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) |
603 | return 0; | 596 | return 0; |
@@ -607,17 +600,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
607 | /* Should be implemented, since bttv calls it */ | 600 | /* Should be implemented, since bttv calls it */ |
608 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); | 601 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); |
609 | break; | 602 | break; |
610 | case TDA9887_SET_CONFIG: | ||
611 | if (t->type == TUNER_TDA9887) { | ||
612 | int *i = arg; | ||
613 | |||
614 | t->tda9887_config = *i; | ||
615 | set_freq(client, t->tv_freq); | ||
616 | } | ||
617 | break; | ||
618 | /* --- v4l ioctls --- */ | ||
619 | /* take care: bttv does userspace copying, we'll get a | ||
620 | kernel pointer here... */ | ||
621 | case VIDIOCSCHAN: | 603 | case VIDIOCSCHAN: |
622 | { | 604 | { |
623 | static const v4l2_std_id map[] = { | 605 | static const v4l2_std_id map[] = { |
@@ -701,7 +683,18 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
701 | ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; | 683 | ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; |
702 | return 0; | 684 | return 0; |
703 | } | 685 | } |
686 | #endif | ||
687 | case TDA9887_SET_CONFIG: | ||
688 | if (t->type == TUNER_TDA9887) { | ||
689 | int *i = arg; | ||
704 | 690 | ||
691 | t->tda9887_config = *i; | ||
692 | set_freq(client, t->tv_freq); | ||
693 | } | ||
694 | break; | ||
695 | /* --- v4l ioctls --- */ | ||
696 | /* take care: bttv does userspace copying, we'll get a | ||
697 | kernel pointer here... */ | ||
705 | case VIDIOC_S_STD: | 698 | case VIDIOC_S_STD: |
706 | { | 699 | { |
707 | v4l2_std_id *id = arg; | 700 | v4l2_std_id *id = arg; |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index d071c5cbf013..abe37cf632c6 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -339,7 +339,20 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
339 | if (4 != (rc = i2c_master_send(c,buffer,4))) | 339 | if (4 != (rc = i2c_master_send(c,buffer,4))) |
340 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 340 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
341 | 341 | ||
342 | if (t->type == TUNER_MICROTUNE_4042FI5) { | 342 | switch (t->type) { |
343 | case TUNER_LG_TDVS_H06XF: | ||
344 | /* Set the Auxiliary Byte. */ | ||
345 | buffer[0] = buffer[2]; | ||
346 | buffer[0] &= ~0x20; | ||
347 | buffer[0] |= 0x18; | ||
348 | buffer[1] = 0x20; | ||
349 | tuner_dbg("tv 0x%02x 0x%02x\n",buffer[0],buffer[1]); | ||
350 | |||
351 | if (2 != (rc = i2c_master_send(c,buffer,2))) | ||
352 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | ||
353 | break; | ||
354 | case TUNER_MICROTUNE_4042FI5: | ||
355 | { | ||
343 | // FIXME - this may also work for other tuners | 356 | // FIXME - this may also work for other tuners |
344 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | 357 | unsigned long timeout = jiffies + msecs_to_jiffies(1); |
345 | u8 status_byte = 0; | 358 | u8 status_byte = 0; |
@@ -364,10 +377,12 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
364 | buffer[2] = config; | 377 | buffer[2] = config; |
365 | buffer[3] = cb; | 378 | buffer[3] = cb; |
366 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 379 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
367 | buffer[0],buffer[1],buffer[2],buffer[3]); | 380 | buffer[0],buffer[1],buffer[2],buffer[3]); |
368 | 381 | ||
369 | if (4 != (rc = i2c_master_send(c,buffer,4))) | 382 | if (4 != (rc = i2c_master_send(c,buffer,4))) |
370 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 383 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
384 | break; | ||
385 | } | ||
371 | } | 386 | } |
372 | } | 387 | } |
373 | 388 | ||
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig index 59fb899f31f3..a0fd82b924f2 100644 --- a/drivers/media/video/usbvideo/Kconfig +++ b/drivers/media/video/usbvideo/Kconfig | |||
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO | |||
3 | 3 | ||
4 | config USB_VICAM | 4 | config USB_VICAM |
5 | tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" | 5 | tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)" |
6 | depends on USB && VIDEO_V4L1 && EXPERIMENTAL | 6 | depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL |
7 | select VIDEO_USBVIDEO | 7 | select VIDEO_USBVIDEO |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have 3com homeconnect camera (vicam). | 9 | Say Y here if you have 3com homeconnect camera (vicam). |
@@ -13,7 +13,7 @@ config USB_VICAM | |||
13 | 13 | ||
14 | config USB_IBMCAM | 14 | config USB_IBMCAM |
15 | tristate "USB IBM (Xirlink) C-it Camera support" | 15 | tristate "USB IBM (Xirlink) C-it Camera support" |
16 | depends on USB && VIDEO_V4L1 | 16 | depends on USB && VIDEO_DEV && VIDEO_V4L1 |
17 | select VIDEO_USBVIDEO | 17 | select VIDEO_USBVIDEO |
18 | ---help--- | 18 | ---help--- |
19 | Say Y here if you want to connect a IBM "C-It" camera, also known as | 19 | Say Y here if you want to connect a IBM "C-It" camera, also known as |
@@ -28,7 +28,7 @@ config USB_IBMCAM | |||
28 | 28 | ||
29 | config USB_KONICAWC | 29 | config USB_KONICAWC |
30 | tristate "USB Konica Webcam support" | 30 | tristate "USB Konica Webcam support" |
31 | depends on USB && VIDEO_V4L1 | 31 | depends on USB && VIDEO_DEV && VIDEO_V4L1 |
32 | select VIDEO_USBVIDEO | 32 | select VIDEO_USBVIDEO |
33 | ---help--- | 33 | ---help--- |
34 | Say Y here if you want support for webcams based on a Konica | 34 | Say Y here if you want support for webcams based on a Konica |
@@ -39,7 +39,7 @@ config USB_KONICAWC | |||
39 | 39 | ||
40 | config USB_QUICKCAM_MESSENGER | 40 | config USB_QUICKCAM_MESSENGER |
41 | tristate "USB Logitech Quickcam Messenger" | 41 | tristate "USB Logitech Quickcam Messenger" |
42 | depends on USB && VIDEO_DEV | 42 | depends on USB && VIDEO_DEV && VIDEO_V4L1 |
43 | select VIDEO_USBVIDEO | 43 | select VIDEO_USBVIDEO |
44 | ---help--- | 44 | ---help--- |
45 | Say Y or M here to enable support for the USB Logitech Quickcam | 45 | Say Y or M here to enable support for the USB Logitech Quickcam |
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index f06dc19e504a..2ecbeffb559e 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c | |||
@@ -202,7 +202,7 @@ static char *v4l2_memory_names[] = { | |||
202 | /* ------------------------------------------------------------------ */ | 202 | /* ------------------------------------------------------------------ */ |
203 | /* debug help functions */ | 203 | /* debug help functions */ |
204 | 204 | ||
205 | #ifdef HAVE_V4L1 | 205 | #ifdef CONFIG_V4L1_COMPAT |
206 | static const char *v4l1_ioctls[] = { | 206 | static const char *v4l1_ioctls[] = { |
207 | [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", | 207 | [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", |
208 | [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", | 208 | [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", |
@@ -301,7 +301,7 @@ static const char *v4l2_ioctls[] = { | |||
301 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 301 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
302 | 302 | ||
303 | static const char *v4l2_int_ioctls[] = { | 303 | static const char *v4l2_int_ioctls[] = { |
304 | #ifdef HAVE_VIDEO_DECODER | 304 | #ifdef CONFIG_V4L1_COMPAT |
305 | [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", | 305 | [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", |
306 | [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", | 306 | [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", |
307 | [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", | 307 | [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", |
@@ -367,7 +367,7 @@ void v4l_printk_ioctl(unsigned int cmd) | |||
367 | (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? | 367 | (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? |
368 | v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); | 368 | v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); |
369 | break; | 369 | break; |
370 | #ifdef HAVE_V4L1 | 370 | #ifdef CONFIG_V4L1_COMPAT |
371 | case 'v': | 371 | case 'v': |
372 | printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", | 372 | printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", |
373 | (_IOC_NR(cmd) < V4L1_IOCTLS) ? | 373 | (_IOC_NR(cmd) < V4L1_IOCTLS) ? |
@@ -414,6 +414,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
414 | printk ("%s: tuner type=%d\n", s, *p); | 414 | printk ("%s: tuner type=%d\n", s, *p); |
415 | break; | 415 | break; |
416 | } | 416 | } |
417 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
417 | case DECODER_SET_VBI_BYPASS: | 418 | case DECODER_SET_VBI_BYPASS: |
418 | case DECODER_ENABLE_OUTPUT: | 419 | case DECODER_ENABLE_OUTPUT: |
419 | case DECODER_GET_STATUS: | 420 | case DECODER_GET_STATUS: |
@@ -424,6 +425,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
424 | case VIDIOCCAPTURE: | 425 | case VIDIOCCAPTURE: |
425 | case VIDIOCSYNC: | 426 | case VIDIOCSYNC: |
426 | case VIDIOCSWRITEMODE: | 427 | case VIDIOCSWRITEMODE: |
428 | #endif | ||
427 | case TUNER_SET_TYPE_ADDR: | 429 | case TUNER_SET_TYPE_ADDR: |
428 | case TUNER_SET_STANDBY: | 430 | case TUNER_SET_STANDBY: |
429 | case TDA9887_SET_CONFIG: | 431 | case TDA9887_SET_CONFIG: |
@@ -755,6 +757,7 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
755 | p->afc); | 757 | p->afc); |
756 | break; | 758 | break; |
757 | } | 759 | } |
760 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
758 | case VIDIOCGVBIFMT: | 761 | case VIDIOCGVBIFMT: |
759 | case VIDIOCSVBIFMT: | 762 | case VIDIOCSVBIFMT: |
760 | { | 763 | { |
@@ -924,6 +927,14 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
924 | p->clipcount); | 927 | p->clipcount); |
925 | break; | 928 | break; |
926 | } | 929 | } |
930 | case VIDIOCGFREQ: | ||
931 | case VIDIOCSFREQ: | ||
932 | { | ||
933 | unsigned long *p=arg; | ||
934 | printk ("%s: value=%lu\n", s, *p); | ||
935 | break; | ||
936 | } | ||
937 | #endif | ||
927 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 938 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
928 | case VIDIOC_INT_I2S_CLOCK_FREQ: | 939 | case VIDIOC_INT_I2S_CLOCK_FREQ: |
929 | case VIDIOC_INT_S_STANDBY: | 940 | case VIDIOC_INT_S_STANDBY: |
@@ -933,13 +944,6 @@ void v4l_printk_ioctl_arg(char *s,unsigned int cmd, void *arg) | |||
933 | printk ("%s: value=%d\n", s, *p); | 944 | printk ("%s: value=%d\n", s, *p); |
934 | break; | 945 | break; |
935 | } | 946 | } |
936 | case VIDIOCGFREQ: | ||
937 | case VIDIOCSFREQ: | ||
938 | { | ||
939 | unsigned long *p=arg; | ||
940 | printk ("%s: value=%lu\n", s, *p); | ||
941 | break; | ||
942 | } | ||
943 | case VIDIOC_G_STD: | 947 | case VIDIOC_G_STD: |
944 | case VIDIOC_S_STD: | 948 | case VIDIOC_S_STD: |
945 | case VIDIOC_QUERYSTD: | 949 | case VIDIOC_QUERYSTD: |
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index b26ebaff226f..0fc90cd393f6 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c | |||
@@ -760,7 +760,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, | |||
760 | ret=vfd->vidioc_overlay(file, fh, *i); | 760 | ret=vfd->vidioc_overlay(file, fh, *i); |
761 | break; | 761 | break; |
762 | } | 762 | } |
763 | #ifdef HAVE_V4L1 | 763 | #ifdef CONFIG_V4L1_COMPAT |
764 | /* --- streaming capture ------------------------------------- */ | 764 | /* --- streaming capture ------------------------------------- */ |
765 | case VIDIOCGMBUF: | 765 | case VIDIOCGMBUF: |
766 | { | 766 | { |
@@ -1512,6 +1512,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1512 | int i=0; | 1512 | int i=0; |
1513 | int base; | 1513 | int base; |
1514 | int end; | 1514 | int end; |
1515 | int ret; | ||
1515 | char *name_base; | 1516 | char *name_base; |
1516 | 1517 | ||
1517 | switch(type) | 1518 | switch(type) |
@@ -1537,6 +1538,8 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1537 | name_base = "radio"; | 1538 | name_base = "radio"; |
1538 | break; | 1539 | break; |
1539 | default: | 1540 | default: |
1541 | printk(KERN_ERR "%s called with unknown type: %d\n", | ||
1542 | __FUNCTION__, type); | ||
1540 | return -1; | 1543 | return -1; |
1541 | } | 1544 | } |
1542 | 1545 | ||
@@ -1571,9 +1574,18 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1571 | vfd->class_dev.class = &video_class; | 1574 | vfd->class_dev.class = &video_class; |
1572 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); | 1575 | vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); |
1573 | sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base); | 1576 | sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base); |
1574 | class_device_register(&vfd->class_dev); | 1577 | ret = class_device_register(&vfd->class_dev); |
1575 | class_device_create_file(&vfd->class_dev, | 1578 | if (ret < 0) { |
1576 | &class_device_attr_name); | 1579 | printk(KERN_ERR "%s: class_device_register failed\n", |
1580 | __FUNCTION__); | ||
1581 | goto fail_minor; | ||
1582 | } | ||
1583 | ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name); | ||
1584 | if (ret < 0) { | ||
1585 | printk(KERN_ERR "%s: class_device_create_file 'name' failed\n", | ||
1586 | __FUNCTION__); | ||
1587 | goto fail_classdev; | ||
1588 | } | ||
1577 | 1589 | ||
1578 | #if 1 | 1590 | #if 1 |
1579 | /* needed until all drivers are fixed */ | 1591 | /* needed until all drivers are fixed */ |
@@ -1583,6 +1595,15 @@ int video_register_device(struct video_device *vfd, int type, int nr) | |||
1583 | "http://lwn.net/Articles/36850/\n", vfd->name); | 1595 | "http://lwn.net/Articles/36850/\n", vfd->name); |
1584 | #endif | 1596 | #endif |
1585 | return 0; | 1597 | return 0; |
1598 | |||
1599 | fail_classdev: | ||
1600 | class_device_unregister(&vfd->class_dev); | ||
1601 | fail_minor: | ||
1602 | mutex_lock(&videodev_lock); | ||
1603 | video_device[vfd->minor] = NULL; | ||
1604 | vfd->minor = -1; | ||
1605 | mutex_unlock(&videodev_lock); | ||
1606 | return ret; | ||
1586 | } | 1607 | } |
1587 | 1608 | ||
1588 | /** | 1609 | /** |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 41d23c8acbd8..38bd0c1018c2 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -986,7 +986,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) | |||
986 | file->f_flags & O_NONBLOCK)); | 986 | file->f_flags & O_NONBLOCK)); |
987 | } | 987 | } |
988 | 988 | ||
989 | #ifdef HAVE_V4L1 | 989 | #ifdef CONFIG_V4L1_COMPAT |
990 | static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) | 990 | static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) |
991 | { | 991 | { |
992 | struct vivi_fh *fh=priv; | 992 | struct vivi_fh *fh=priv; |
@@ -1328,7 +1328,7 @@ static struct video_device vivi = { | |||
1328 | .vidioc_s_ctrl = vidioc_s_ctrl, | 1328 | .vidioc_s_ctrl = vidioc_s_ctrl, |
1329 | .vidioc_streamon = vidioc_streamon, | 1329 | .vidioc_streamon = vidioc_streamon, |
1330 | .vidioc_streamoff = vidioc_streamoff, | 1330 | .vidioc_streamoff = vidioc_streamoff, |
1331 | #ifdef HAVE_V4L1 | 1331 | #ifdef CONFIG_V4L1_COMPAT |
1332 | .vidiocgmbuf = vidiocgmbuf, | 1332 | .vidiocgmbuf = vidiocgmbuf, |
1333 | #endif | 1333 | #endif |
1334 | .tvnorms = tvnorms, | 1334 | .tvnorms = tvnorms, |
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig index bbc229852881..ea31d8470510 100644 --- a/drivers/message/fusion/Kconfig +++ b/drivers/message/fusion/Kconfig | |||
@@ -48,10 +48,8 @@ config FUSION_SAS | |||
48 | List of supported controllers: | 48 | List of supported controllers: |
49 | 49 | ||
50 | LSISAS1064 | 50 | LSISAS1064 |
51 | LSISAS1066 | ||
52 | LSISAS1068 | 51 | LSISAS1068 |
53 | LSISAS1064E | 52 | LSISAS1064E |
54 | LSISAS1066E | ||
55 | LSISAS1068E | 53 | LSISAS1068E |
56 | 54 | ||
57 | config FUSION_MAX_SGE | 55 | config FUSION_MAX_SGE |
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index b114236f4395..341691390e86 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -9,7 +9,6 @@ | |||
9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT | 9 | #EXTRA_CFLAGS += -DMPT_DEBUG_EXIT |
10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL | 10 | #EXTRA_CFLAGS += -DMPT_DEBUG_FAIL |
11 | 11 | ||
12 | |||
13 | # | 12 | # |
14 | # driver/module specifics... | 13 | # driver/module specifics... |
15 | # | 14 | # |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 43308df64623..29d0635cce1d 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) | |||
436 | */ | 436 | */ |
437 | if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { | 437 | if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { |
438 | freereq = 0; | 438 | freereq = 0; |
439 | devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n", | ||
440 | ioc->name, pEvReply)); | ||
441 | } else { | 439 | } else { |
442 | devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", | 440 | devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", |
443 | ioc->name, pEvReply)); | 441 | ioc->name, pEvReply)); |
@@ -678,19 +676,19 @@ int | |||
678 | mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) | 676 | mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx) |
679 | { | 677 | { |
680 | MPT_ADAPTER *ioc; | 678 | MPT_ADAPTER *ioc; |
679 | const struct pci_device_id *id; | ||
681 | 680 | ||
682 | if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) { | 681 | if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) |
683 | return -EINVAL; | 682 | return -EINVAL; |
684 | } | ||
685 | 683 | ||
686 | MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; | 684 | MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; |
687 | 685 | ||
688 | /* call per pci device probe entry point */ | 686 | /* call per pci device probe entry point */ |
689 | list_for_each_entry(ioc, &ioc_list, list) { | 687 | list_for_each_entry(ioc, &ioc_list, list) { |
690 | if(dd_cbfunc->probe) { | 688 | id = ioc->pcidev->driver ? |
691 | dd_cbfunc->probe(ioc->pcidev, | 689 | ioc->pcidev->driver->id_table : NULL; |
692 | ioc->pcidev->driver->id_table); | 690 | if (dd_cbfunc->probe) |
693 | } | 691 | dd_cbfunc->probe(ioc->pcidev, id); |
694 | } | 692 | } |
695 | 693 | ||
696 | return 0; | 694 | return 0; |
@@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) | |||
1056 | 1054 | ||
1057 | dinitprintk((MYIOC_s_INFO_FMT | 1055 | dinitprintk((MYIOC_s_INFO_FMT |
1058 | "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", | 1056 | "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", |
1059 | ioc->name, | 1057 | ioc->name, ioc->HostPageBuffer, |
1060 | ioc->HostPageBuffer, | 1058 | (u32)ioc->HostPageBuffer_dma, |
1061 | ioc->HostPageBuffer_dma, | ||
1062 | host_page_buffer_sz)); | 1059 | host_page_buffer_sz)); |
1063 | ioc->alloc_total += host_page_buffer_sz; | 1060 | ioc->alloc_total += host_page_buffer_sz; |
1064 | ioc->HostPageBuffer_sz = host_page_buffer_sz; | 1061 | ioc->HostPageBuffer_sz = host_page_buffer_sz; |
@@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1380 | printk(KERN_WARNING MYNAM | 1377 | printk(KERN_WARNING MYNAM |
1381 | ": WARNING - %s did not initialize properly! (%d)\n", | 1378 | ": WARNING - %s did not initialize properly! (%d)\n", |
1382 | ioc->name, r); | 1379 | ioc->name, r); |
1380 | |||
1383 | list_del(&ioc->list); | 1381 | list_del(&ioc->list); |
1384 | if (ioc->alt_ioc) | 1382 | if (ioc->alt_ioc) |
1385 | ioc->alt_ioc->alt_ioc = NULL; | 1383 | ioc->alt_ioc->alt_ioc = NULL; |
@@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1762 | * chips (mpt_adapter_disable, | 1760 | * chips (mpt_adapter_disable, |
1763 | * mpt_diag_reset) | 1761 | * mpt_diag_reset) |
1764 | */ | 1762 | */ |
1765 | ioc->cached_fw = NULL; | ||
1766 | ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n", | 1763 | ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n", |
1767 | ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); | 1764 | ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); |
1765 | ioc->alt_ioc->cached_fw = NULL; | ||
1768 | } | 1766 | } |
1769 | } else { | 1767 | } else { |
1770 | printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); | 1768 | printk(KERN_WARNING MYNAM ": firmware upload failure!\n"); |
@@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1885 | /* FIXME? Examine results here? */ | 1883 | /* FIXME? Examine results here? */ |
1886 | } | 1884 | } |
1887 | 1885 | ||
1888 | out: | 1886 | out: |
1889 | if ((ret != 0) && irq_allocated) { | 1887 | if ((ret != 0) && irq_allocated) { |
1890 | free_irq(ioc->pci_irq, ioc); | 1888 | free_irq(ioc->pci_irq, ioc); |
1891 | if (mpt_msi_enable) | 1889 | if (mpt_msi_enable) |
@@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) | |||
2670 | dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", | 2668 | dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n", |
2671 | ioc->name, count)); | 2669 | ioc->name, count)); |
2672 | 2670 | ||
2671 | ioc->aen_event_read_flag=0; | ||
2673 | return r; | 2672 | return r; |
2674 | } | 2673 | } |
2675 | 2674 | ||
@@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) | |||
2737 | if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { | 2736 | if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { |
2738 | ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ | 2737 | ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ |
2739 | ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; | 2738 | ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; |
2739 | ioc->alloc_total += size; | ||
2740 | ioc->alt_ioc->alloc_total -= size; | ||
2740 | } else { | 2741 | } else { |
2741 | if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) ) | 2742 | if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) ) |
2742 | ioc->alloc_total += size; | 2743 | ioc->alloc_total += size; |
@@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) | |||
3166 | static int | 3167 | static int |
3167 | mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | 3168 | mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) |
3168 | { | 3169 | { |
3170 | MPT_ADAPTER *iocp=NULL; | ||
3169 | u32 diag0val; | 3171 | u32 diag0val; |
3170 | u32 doorbell; | 3172 | u32 doorbell; |
3171 | int hard_reset_done = 0; | 3173 | int hard_reset_done = 0; |
@@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3301 | /* FIXME? Examine results here? */ | 3303 | /* FIXME? Examine results here? */ |
3302 | } | 3304 | } |
3303 | 3305 | ||
3304 | if (ioc->cached_fw) { | 3306 | if (ioc->cached_fw) |
3307 | iocp = ioc; | ||
3308 | else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) | ||
3309 | iocp = ioc->alt_ioc; | ||
3310 | if (iocp) { | ||
3305 | /* If the DownloadBoot operation fails, the | 3311 | /* If the DownloadBoot operation fails, the |
3306 | * IOC will be left unusable. This is a fatal error | 3312 | * IOC will be left unusable. This is a fatal error |
3307 | * case. _diag_reset will return < 0 | 3313 | * case. _diag_reset will return < 0 |
3308 | */ | 3314 | */ |
3309 | for (count = 0; count < 30; count ++) { | 3315 | for (count = 0; count < 30; count ++) { |
3310 | diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); | 3316 | diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic); |
3311 | if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { | 3317 | if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { |
3312 | break; | 3318 | break; |
3313 | } | 3319 | } |
3314 | 3320 | ||
3321 | dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n", | ||
3322 | iocp->name, diag0val, count)); | ||
3315 | /* wait 1 sec */ | 3323 | /* wait 1 sec */ |
3316 | if (sleepFlag == CAN_SLEEP) { | 3324 | if (sleepFlag == CAN_SLEEP) { |
3317 | msleep (1000); | 3325 | msleep (1000); |
@@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) | |||
3320 | } | 3328 | } |
3321 | } | 3329 | } |
3322 | if ((count = mpt_downloadboot(ioc, | 3330 | if ((count = mpt_downloadboot(ioc, |
3323 | (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) { | 3331 | (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) { |
3324 | printk(KERN_WARNING MYNAM | 3332 | printk(KERN_WARNING MYNAM |
3325 | ": firmware downloadboot failure (%d)!\n", count); | 3333 | ": firmware downloadboot failure (%d)!\n", count); |
3326 | } | 3334 | } |
@@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) | |||
3907 | 3915 | ||
3908 | if (sleepFlag == CAN_SLEEP) { | 3916 | if (sleepFlag == CAN_SLEEP) { |
3909 | while (--cntdn) { | 3917 | while (--cntdn) { |
3918 | msleep (1); | ||
3910 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); | 3919 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); |
3911 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) | 3920 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) |
3912 | break; | 3921 | break; |
3913 | msleep (1); | ||
3914 | count++; | 3922 | count++; |
3915 | } | 3923 | } |
3916 | } else { | 3924 | } else { |
3917 | while (--cntdn) { | 3925 | while (--cntdn) { |
3926 | mdelay (1); | ||
3918 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); | 3927 | intstat = CHIPREG_READ32(&ioc->chip->IntStatus); |
3919 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) | 3928 | if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) |
3920 | break; | 3929 | break; |
3921 | mdelay (1); | ||
3922 | count++; | 3930 | count++; |
3923 | } | 3931 | } |
3924 | } | 3932 | } |
@@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) | |||
4883 | pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); | 4891 | pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); |
4884 | if (!pIoc4) | 4892 | if (!pIoc4) |
4885 | return; | 4893 | return; |
4894 | ioc->alloc_total += iocpage4sz; | ||
4886 | } else { | 4895 | } else { |
4887 | ioc4_dma = ioc->spi_data.IocPg4_dma; | 4896 | ioc4_dma = ioc->spi_data.IocPg4_dma; |
4888 | iocpage4sz = ioc->spi_data.IocPg4Sz; | 4897 | iocpage4sz = ioc->spi_data.IocPg4Sz; |
@@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) | |||
4899 | } else { | 4908 | } else { |
4900 | pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); | 4909 | pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); |
4901 | ioc->spi_data.pIocPg4 = NULL; | 4910 | ioc->spi_data.pIocPg4 = NULL; |
4911 | ioc->alloc_total -= iocpage4sz; | ||
4902 | } | 4912 | } |
4903 | } | 4913 | } |
4904 | 4914 | ||
@@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) | |||
5030 | EventAck_t *pAck; | 5040 | EventAck_t *pAck; |
5031 | 5041 | ||
5032 | if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { | 5042 | if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { |
5033 | printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK " | 5043 | dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n", |
5034 | "request frame for Event=%x EventContext=%x EventData=%x!\n", | 5044 | ioc->name,__FUNCTION__)); |
5035 | ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext), | ||
5036 | le32_to_cpu(evnp->Data[0])); | ||
5037 | return -1; | 5045 | return -1; |
5038 | } | 5046 | } |
5039 | memset(pAck, 0, sizeof(*pAck)); | ||
5040 | 5047 | ||
5041 | dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name)); | 5048 | devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name)); |
5042 | 5049 | ||
5043 | pAck->Function = MPI_FUNCTION_EVENT_ACK; | 5050 | pAck->Function = MPI_FUNCTION_EVENT_ACK; |
5044 | pAck->ChainOffset = 0; | 5051 | pAck->ChainOffset = 0; |
5052 | pAck->Reserved[0] = pAck->Reserved[1] = 0; | ||
5045 | pAck->MsgFlags = 0; | 5053 | pAck->MsgFlags = 0; |
5054 | pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0; | ||
5046 | pAck->Event = evnp->Event; | 5055 | pAck->Event = evnp->Event; |
5047 | pAck->EventContext = evnp->EventContext; | 5056 | pAck->EventContext = evnp->EventContext; |
5048 | 5057 | ||
@@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5704 | break; | 5713 | break; |
5705 | case MPI_EVENT_EVENT_CHANGE: | 5714 | case MPI_EVENT_EVENT_CHANGE: |
5706 | if (evData0) | 5715 | if (evData0) |
5707 | ds = "Events(ON) Change"; | 5716 | ds = "Events ON"; |
5708 | else | 5717 | else |
5709 | ds = "Events(OFF) Change"; | 5718 | ds = "Events OFF"; |
5710 | break; | 5719 | break; |
5711 | case MPI_EVENT_INTEGRATED_RAID: | 5720 | case MPI_EVENT_INTEGRATED_RAID: |
5712 | { | 5721 | { |
@@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr) | |||
5777 | break; | 5786 | break; |
5778 | case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: | 5787 | case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: |
5779 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5788 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
5780 | "SAS Device Status Change: No Persistancy " | 5789 | "SAS Device Status Change: No Persistancy: id=%d", id); |
5781 | "Added: id=%d", id); | 5790 | break; |
5791 | case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: | ||
5792 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5793 | "SAS Device Status Change: Internal Device Reset : id=%d", id); | ||
5794 | break; | ||
5795 | case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: | ||
5796 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5797 | "SAS Device Status Change: Internal Task Abort : id=%d", id); | ||
5798 | break; | ||
5799 | case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: | ||
5800 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5801 | "SAS Device Status Change: Internal Abort Task Set : id=%d", id); | ||
5802 | break; | ||
5803 | case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: | ||
5804 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5805 | "SAS Device Status Change: Internal Clear Task Set : id=%d", id); | ||
5806 | break; | ||
5807 | case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: | ||
5808 | snprintf(evStr, EVENT_DESCR_STR_SZ, | ||
5809 | "SAS Device Status Change: Internal Query Task : id=%d", id); | ||
5782 | break; | 5810 | break; |
5783 | default: | 5811 | default: |
5784 | snprintf(evStr, EVENT_DESCR_STR_SZ, | 5812 | snprintf(evStr, EVENT_DESCR_STR_SZ, |
@@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
6034 | * @ioc: Pointer to MPT_ADAPTER structure | 6062 | * @ioc: Pointer to MPT_ADAPTER structure |
6035 | * @log_info: U32 LogInfo reply word from the IOC | 6063 | * @log_info: U32 LogInfo reply word from the IOC |
6036 | * | 6064 | * |
6037 | * Refer to lsi/fc_log.h. | 6065 | * Refer to lsi/mpi_log_fc.h. |
6038 | */ | 6066 | */ |
6039 | static void | 6067 | static void |
6040 | mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | 6068 | mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) |
@@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6131 | "Invalid SAS Address", /* 01h */ | 6159 | "Invalid SAS Address", /* 01h */ |
6132 | NULL, /* 02h */ | 6160 | NULL, /* 02h */ |
6133 | "Invalid Page", /* 03h */ | 6161 | "Invalid Page", /* 03h */ |
6134 | NULL, /* 04h */ | 6162 | "Diag Message Error", /* 04h */ |
6135 | "Task Terminated" /* 05h */ | 6163 | "Task Terminated", /* 05h */ |
6164 | "Enclosure Management", /* 06h */ | ||
6165 | "Target Mode" /* 07h */ | ||
6136 | }; | 6166 | }; |
6137 | static char *pl_code_str[] = { | 6167 | static char *pl_code_str[] = { |
6138 | NULL, /* 00h */ | 6168 | NULL, /* 00h */ |
@@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6158 | "IO Executed", /* 14h */ | 6188 | "IO Executed", /* 14h */ |
6159 | "Persistant Reservation Out Not Affiliation Owner", /* 15h */ | 6189 | "Persistant Reservation Out Not Affiliation Owner", /* 15h */ |
6160 | "Open Transmit DMA Abort", /* 16h */ | 6190 | "Open Transmit DMA Abort", /* 16h */ |
6161 | NULL, /* 17h */ | 6191 | "IO Device Missing Delay Retry", /* 17h */ |
6162 | NULL, /* 18h */ | 6192 | NULL, /* 18h */ |
6163 | NULL, /* 19h */ | 6193 | NULL, /* 19h */ |
6164 | NULL, /* 1Ah */ | 6194 | NULL, /* 1Ah */ |
@@ -6238,7 +6268,7 @@ static void | |||
6238 | mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) | 6268 | mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) |
6239 | { | 6269 | { |
6240 | u32 status = ioc_status & MPI_IOCSTATUS_MASK; | 6270 | u32 status = ioc_status & MPI_IOCSTATUS_MASK; |
6241 | char *desc = ""; | 6271 | char *desc = NULL; |
6242 | 6272 | ||
6243 | switch (status) { | 6273 | switch (status) { |
6244 | case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ | 6274 | case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ |
@@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) | |||
6348 | desc = "Others"; | 6378 | desc = "Others"; |
6349 | break; | 6379 | break; |
6350 | } | 6380 | } |
6351 | if (desc != "") | 6381 | if (desc != NULL) |
6352 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); | 6382 | printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc); |
6353 | } | 6383 | } |
6354 | 6384 | ||
@@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory); | |||
6386 | EXPORT_SYMBOL(mpt_free_fw_memory); | 6416 | EXPORT_SYMBOL(mpt_free_fw_memory); |
6387 | EXPORT_SYMBOL(mptbase_sas_persist_operation); | 6417 | EXPORT_SYMBOL(mptbase_sas_persist_operation); |
6388 | 6418 | ||
6389 | |||
6390 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6419 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6391 | /* | 6420 | /* |
6392 | * fusion_init - Fusion MPT base driver initialization routine. | 6421 | * fusion_init - Fusion MPT base driver initialization routine. |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a5ce10b67d02..d4cb144ab402 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -75,8 +75,8 @@ | |||
75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR | 75 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #define MPT_LINUX_VERSION_COMMON "3.04.00" | 78 | #define MPT_LINUX_VERSION_COMMON "3.04.01" |
79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.00" | 79 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.01" |
80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 80 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
81 | 81 | ||
82 | #define show_mptmod_ver(s,ver) \ | 82 | #define show_mptmod_ver(s,ver) \ |
@@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS | |||
307 | u32 HostIndex; /* 50 Host Index register */ | 307 | u32 HostIndex; /* 50 Host Index register */ |
308 | u32 Reserved4[15]; /* 54-8F */ | 308 | u32 Reserved4[15]; /* 54-8F */ |
309 | u32 Fubar; /* 90 For Fubar usage */ | 309 | u32 Fubar; /* 90 For Fubar usage */ |
310 | u32 Reserved5[1050];/* 94-10F8 */ | 310 | u32 Reserved5[1050];/* 94-10F8 */ |
311 | u32 Reset_1078; /* 10FC Reset 1078 */ | 311 | u32 Reset_1078; /* 10FC Reset 1078 */ |
312 | } SYSIF_REGS; | 312 | } SYSIF_REGS; |
313 | 313 | ||
314 | /* | 314 | /* |
@@ -363,6 +363,7 @@ typedef struct _VirtDevice { | |||
363 | #define MPT_TARGET_FLAGS_VALID_56 0x10 | 363 | #define MPT_TARGET_FLAGS_VALID_56 0x10 |
364 | #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 | 364 | #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 |
365 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40 | 365 | #define MPT_TARGET_FLAGS_RAID_COMPONENT 0x40 |
366 | #define MPT_TARGET_FLAGS_LED_ON 0x80 | ||
366 | 367 | ||
367 | /* | 368 | /* |
368 | * /proc/mpt interface | 369 | * /proc/mpt interface |
@@ -634,7 +635,6 @@ typedef struct _MPT_ADAPTER | |||
634 | u16 handle; | 635 | u16 handle; |
635 | int sas_index; /* index refrencing */ | 636 | int sas_index; /* index refrencing */ |
636 | MPT_SAS_MGMT sas_mgmt; | 637 | MPT_SAS_MGMT sas_mgmt; |
637 | int num_ports; | ||
638 | struct work_struct sas_persist_task; | 638 | struct work_struct sas_persist_task; |
639 | 639 | ||
640 | struct work_struct fc_setup_reset_work; | 640 | struct work_struct fc_setup_reset_work; |
@@ -644,7 +644,6 @@ typedef struct _MPT_ADAPTER | |||
644 | struct work_struct fc_rescan_work; | 644 | struct work_struct fc_rescan_work; |
645 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; | 645 | char fc_rescan_work_q_name[KOBJ_NAME_LEN]; |
646 | struct workqueue_struct *fc_rescan_work_q; | 646 | struct workqueue_struct *fc_rescan_work_q; |
647 | u8 port_serial_number; | ||
648 | } MPT_ADAPTER; | 647 | } MPT_ADAPTER; |
649 | 648 | ||
650 | /* | 649 | /* |
@@ -982,7 +981,7 @@ typedef struct _MPT_SCSI_HOST { | |||
982 | wait_queue_head_t scandv_waitq; | 981 | wait_queue_head_t scandv_waitq; |
983 | int scandv_wait_done; | 982 | int scandv_wait_done; |
984 | long last_queue_full; | 983 | long last_queue_full; |
985 | u8 mpt_pq_filter; | 984 | u16 tm_iocstatus; |
986 | } MPT_SCSI_HOST; | 985 | } MPT_SCSI_HOST; |
987 | 986 | ||
988 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 987 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b4967bb8a7d6..30975ccd9947 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -2332,7 +2332,7 @@ done_free_mem: | |||
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2334 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2335 | /* Prototype Routine for the HP HOST INFO command. | 2335 | /* Prototype Routine for the HOST INFO command. |
2336 | * | 2336 | * |
2337 | * Outputs: None. | 2337 | * Outputs: None. |
2338 | * Return: 0 if successful | 2338 | * Return: 0 if successful |
@@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2568 | } | 2568 | } |
2569 | 2569 | ||
2570 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2570 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2571 | /* Prototype Routine for the HP TARGET INFO command. | 2571 | /* Prototype Routine for the TARGET INFO command. |
2572 | * | 2572 | * |
2573 | * Outputs: None. | 2573 | * Outputs: None. |
2574 | * Return: 0 if successful | 2574 | * Return: 0 if successful |
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index a2f8a97992e6..043941882c6e 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h | |||
@@ -354,9 +354,6 @@ struct mpt_ioctl_command32 { | |||
354 | 354 | ||
355 | 355 | ||
356 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 356 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
357 | /* | ||
358 | * HP Specific IOCTL Defines and Structures | ||
359 | */ | ||
360 | 357 | ||
361 | #define CPQFCTS_IOC_MAGIC 'Z' | 358 | #define CPQFCTS_IOC_MAGIC 'Z' |
362 | #define HP_IOC_MAGIC 'Z' | 359 | #define HP_IOC_MAGIC 'Z' |
@@ -364,8 +361,6 @@ struct mpt_ioctl_command32 { | |||
364 | #define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t) | 361 | #define HP_GETHOSTINFO1 _IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t) |
365 | #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) | 362 | #define HP_GETTARGETINFO _IOR(HP_IOC_MAGIC, 21, hp_target_info_t) |
366 | 363 | ||
367 | /* All HP IOCTLs must include this header | ||
368 | */ | ||
369 | typedef struct _hp_header { | 364 | typedef struct _hp_header { |
370 | unsigned int iocnum; | 365 | unsigned int iocnum; |
371 | unsigned int host; | 366 | unsigned int host; |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index a8f2fa985455..90da7d63b08e 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME); | |||
77 | MODULE_LICENSE("GPL"); | 77 | MODULE_LICENSE("GPL"); |
78 | 78 | ||
79 | /* Command line args */ | 79 | /* Command line args */ |
80 | static int mpt_pq_filter = 0; | ||
81 | module_param(mpt_pq_filter, int, 0); | ||
82 | MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); | ||
83 | |||
84 | #define MPTFC_DEV_LOSS_TMO (60) | 80 | #define MPTFC_DEV_LOSS_TMO (60) |
85 | static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */ | 81 | static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */ |
86 | module_param(mptfc_dev_loss_tmo, int, 0); | 82 | module_param(mptfc_dev_loss_tmo, int, 0); |
@@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
513 | 509 | ||
514 | if (vtarget->num_luns == 0) { | 510 | if (vtarget->num_luns == 0) { |
515 | vtarget->ioc_id = hd->ioc->id; | 511 | vtarget->ioc_id = hd->ioc->id; |
516 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | | 512 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES; |
517 | MPT_TARGET_FLAGS_VALID_INQUIRY; | ||
518 | hd->Targets[sdev->id] = vtarget; | 513 | hd->Targets[sdev->id] = vtarget; |
519 | } | 514 | } |
520 | 515 | ||
@@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1129 | hd->timer.data = (unsigned long) hd; | 1124 | hd->timer.data = (unsigned long) hd; |
1130 | hd->timer.function = mptscsih_timer_expired; | 1125 | hd->timer.function = mptscsih_timer_expired; |
1131 | 1126 | ||
1132 | hd->mpt_pq_filter = mpt_pq_filter; | ||
1133 | |||
1134 | ddvprintk((MYIOC_s_INFO_FMT | ||
1135 | "mpt_pq_filter %x\n", | ||
1136 | ioc->name, | ||
1137 | mpt_pq_filter)); | ||
1138 | |||
1139 | init_waitqueue_head(&hd->scandv_waitq); | 1127 | init_waitqueue_head(&hd->scandv_waitq); |
1140 | hd->scandv_wait_done = 0; | 1128 | hd->scandv_wait_done = 0; |
1141 | hd->last_queue_full = 0; | 1129 | hd->last_queue_full = 0; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index f7bd8b11ed3b..f66f2203143a 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -67,20 +67,19 @@ | |||
67 | #define my_VERSION MPT_LINUX_VERSION_COMMON | 67 | #define my_VERSION MPT_LINUX_VERSION_COMMON |
68 | #define MYNAM "mptsas" | 68 | #define MYNAM "mptsas" |
69 | 69 | ||
70 | /* | ||
71 | * Reserved channel for integrated raid | ||
72 | */ | ||
73 | #define MPTSAS_RAID_CHANNEL 1 | ||
74 | |||
70 | MODULE_AUTHOR(MODULEAUTHOR); | 75 | MODULE_AUTHOR(MODULEAUTHOR); |
71 | MODULE_DESCRIPTION(my_NAME); | 76 | MODULE_DESCRIPTION(my_NAME); |
72 | MODULE_LICENSE("GPL"); | 77 | MODULE_LICENSE("GPL"); |
73 | 78 | ||
74 | static int mpt_pq_filter; | ||
75 | module_param(mpt_pq_filter, int, 0); | ||
76 | MODULE_PARM_DESC(mpt_pq_filter, | ||
77 | "Enable peripheral qualifier filter: enable=1 " | ||
78 | "(default=0)"); | ||
79 | |||
80 | static int mpt_pt_clear; | 79 | static int mpt_pt_clear; |
81 | module_param(mpt_pt_clear, int, 0); | 80 | module_param(mpt_pt_clear, int, 0); |
82 | MODULE_PARM_DESC(mpt_pt_clear, | 81 | MODULE_PARM_DESC(mpt_pt_clear, |
83 | "Clear persistency table: enable=1 " | 82 | " Clear persistency table: enable=1 " |
84 | "(default=MPTSCSIH_PT_CLEAR=0)"); | 83 | "(default=MPTSCSIH_PT_CLEAR=0)"); |
85 | 84 | ||
86 | static int mptsasDoneCtx = -1; | 85 | static int mptsasDoneCtx = -1; |
@@ -144,7 +143,6 @@ struct mptsas_devinfo { | |||
144 | * Specific details on ports, wide/narrow | 143 | * Specific details on ports, wide/narrow |
145 | */ | 144 | */ |
146 | struct mptsas_portinfo_details{ | 145 | struct mptsas_portinfo_details{ |
147 | u8 port_id; /* port number provided to transport */ | ||
148 | u16 num_phys; /* number of phys belong to this port */ | 146 | u16 num_phys; /* number of phys belong to this port */ |
149 | u64 phy_bitmask; /* TODO, extend support for 255 phys */ | 147 | u64 phy_bitmask; /* TODO, extend support for 255 phys */ |
150 | struct sas_rphy *rphy; /* transport layer rphy object */ | 148 | struct sas_rphy *rphy; /* transport layer rphy object */ |
@@ -350,10 +348,10 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details) | |||
350 | port_info = port_details->port_info; | 348 | port_info = port_details->port_info; |
351 | phy_info = port_info->phy_info; | 349 | phy_info = port_info->phy_info; |
352 | 350 | ||
353 | dsaswideprintk((KERN_DEBUG "%s: [%p]: port=%02d num_phys=%02d " | 351 | dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d " |
354 | "bitmask=0x%016llX\n", | 352 | "bitmask=0x%016llX\n", |
355 | __FUNCTION__, port_details, port_details->port_id, | 353 | __FUNCTION__, port_details, port_details->num_phys, |
356 | port_details->num_phys, port_details->phy_bitmask)); | 354 | port_details->phy_bitmask)); |
357 | 355 | ||
358 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { | 356 | for (i = 0; i < port_info->num_phys; i++, phy_info++) { |
359 | if(phy_info->port_details != port_details) | 357 | if(phy_info->port_details != port_details) |
@@ -462,9 +460,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
462 | * phy be removed by firmware events. | 460 | * phy be removed by firmware events. |
463 | */ | 461 | */ |
464 | dsaswideprintk((KERN_DEBUG | 462 | dsaswideprintk((KERN_DEBUG |
465 | "%s: [%p]: port=%d deleting phy = %d\n", | 463 | "%s: [%p]: deleting phy = %d\n", |
466 | __FUNCTION__, port_details, | 464 | __FUNCTION__, port_details, i)); |
467 | port_details->port_id, i)); | ||
468 | port_details->num_phys--; | 465 | port_details->num_phys--; |
469 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); | 466 | port_details->phy_bitmask &= ~ (1 << phy_info->phy_id); |
470 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); | 467 | memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo)); |
@@ -493,7 +490,6 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
493 | goto out; | 490 | goto out; |
494 | port_details->num_phys = 1; | 491 | port_details->num_phys = 1; |
495 | port_details->port_info = port_info; | 492 | port_details->port_info = port_info; |
496 | port_details->port_id = ioc->port_serial_number++; | ||
497 | if (phy_info->phy_id < 64 ) | 493 | if (phy_info->phy_id < 64 ) |
498 | port_details->phy_bitmask |= | 494 | port_details->phy_bitmask |= |
499 | (1 << phy_info->phy_id); | 495 | (1 << phy_info->phy_id); |
@@ -525,12 +521,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
525 | mptsas_get_port(phy_info_cmp); | 521 | mptsas_get_port(phy_info_cmp); |
526 | port_details->starget = | 522 | port_details->starget = |
527 | mptsas_get_starget(phy_info_cmp); | 523 | mptsas_get_starget(phy_info_cmp); |
528 | port_details->port_id = | ||
529 | phy_info_cmp->port_details->port_id; | ||
530 | port_details->num_phys = | 524 | port_details->num_phys = |
531 | phy_info_cmp->port_details->num_phys; | 525 | phy_info_cmp->port_details->num_phys; |
532 | // port_info->port_serial_number--; | ||
533 | ioc->port_serial_number--; | ||
534 | if (!phy_info_cmp->port_details->num_phys) | 526 | if (!phy_info_cmp->port_details->num_phys) |
535 | kfree(phy_info_cmp->port_details); | 527 | kfree(phy_info_cmp->port_details); |
536 | } else | 528 | } else |
@@ -554,11 +546,11 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) | |||
554 | if (!port_details) | 546 | if (!port_details) |
555 | continue; | 547 | continue; |
556 | dsaswideprintk((KERN_DEBUG | 548 | dsaswideprintk((KERN_DEBUG |
557 | "%s: [%p]: phy_id=%02d port_id=%02d num_phys=%02d " | 549 | "%s: [%p]: phy_id=%02d num_phys=%02d " |
558 | "bitmask=0x%016llX\n", | 550 | "bitmask=0x%016llX\n", |
559 | __FUNCTION__, | 551 | __FUNCTION__, |
560 | port_details, i, port_details->port_id, | 552 | port_details, i, port_details->num_phys, |
561 | port_details->num_phys, port_details->phy_bitmask)); | 553 | port_details->phy_bitmask)); |
562 | dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", | 554 | dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", |
563 | port_details->port, port_details->rphy)); | 555 | port_details->port, port_details->rphy)); |
564 | } | 556 | } |
@@ -651,16 +643,13 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure, | |||
651 | static int | 643 | static int |
652 | mptsas_slave_configure(struct scsi_device *sdev) | 644 | mptsas_slave_configure(struct scsi_device *sdev) |
653 | { | 645 | { |
654 | struct Scsi_Host *host = sdev->host; | ||
655 | MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; | ||
656 | 646 | ||
657 | /* | 647 | if (sdev->channel == MPTSAS_RAID_CHANNEL) |
658 | * RAID volumes placed beyond the last expected port. | 648 | goto out; |
659 | * Ignore sending sas mode pages in that case.. | 649 | |
660 | */ | 650 | sas_read_port_mode_page(sdev); |
661 | if (sdev->channel < hd->ioc->num_ports) | ||
662 | sas_read_port_mode_page(sdev); | ||
663 | 651 | ||
652 | out: | ||
664 | return mptscsih_slave_configure(sdev); | 653 | return mptscsih_slave_configure(sdev); |
665 | } | 654 | } |
666 | 655 | ||
@@ -689,10 +678,7 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
689 | 678 | ||
690 | hd->Targets[target_id] = vtarget; | 679 | hd->Targets[target_id] = vtarget; |
691 | 680 | ||
692 | /* | 681 | if (starget->channel == MPTSAS_RAID_CHANNEL) |
693 | * RAID volumes placed beyond the last expected port. | ||
694 | */ | ||
695 | if (starget->channel == hd->ioc->num_ports) | ||
696 | goto out; | 682 | goto out; |
697 | 683 | ||
698 | rphy = dev_to_rphy(starget->dev.parent); | 684 | rphy = dev_to_rphy(starget->dev.parent); |
@@ -743,7 +729,7 @@ mptsas_target_destroy(struct scsi_target *starget) | |||
743 | if (!starget->hostdata) | 729 | if (!starget->hostdata) |
744 | return; | 730 | return; |
745 | 731 | ||
746 | if (starget->channel == hd->ioc->num_ports) | 732 | if (starget->channel == MPTSAS_RAID_CHANNEL) |
747 | goto out; | 733 | goto out; |
748 | 734 | ||
749 | rphy = dev_to_rphy(starget->dev.parent); | 735 | rphy = dev_to_rphy(starget->dev.parent); |
@@ -783,10 +769,7 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
783 | starget = scsi_target(sdev); | 769 | starget = scsi_target(sdev); |
784 | vdev->vtarget = starget->hostdata; | 770 | vdev->vtarget = starget->hostdata; |
785 | 771 | ||
786 | /* | 772 | if (sdev->channel == MPTSAS_RAID_CHANNEL) |
787 | * RAID volumes placed beyond the last expected port. | ||
788 | */ | ||
789 | if (sdev->channel == hd->ioc->num_ports) | ||
790 | goto out; | 773 | goto out; |
791 | 774 | ||
792 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); | 775 | rphy = dev_to_rphy(sdev->sdev_target->dev.parent); |
@@ -1608,11 +1591,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1608 | if (phy_info->sas_port_add_phy) { | 1591 | if (phy_info->sas_port_add_phy) { |
1609 | 1592 | ||
1610 | if (!port) { | 1593 | if (!port) { |
1611 | port = sas_port_alloc(dev, | 1594 | port = sas_port_alloc_num(dev); |
1612 | phy_info->port_details->port_id); | ||
1613 | dsaswideprintk((KERN_DEBUG | ||
1614 | "sas_port_alloc: port=%p dev=%p port_id=%d\n", | ||
1615 | port, dev, phy_info->port_details->port_id)); | ||
1616 | if (!port) { | 1595 | if (!port) { |
1617 | error = -ENOMEM; | 1596 | error = -ENOMEM; |
1618 | goto out; | 1597 | goto out; |
@@ -1625,6 +1604,9 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
1625 | goto out; | 1604 | goto out; |
1626 | } | 1605 | } |
1627 | mptsas_set_port(phy_info, port); | 1606 | mptsas_set_port(phy_info, port); |
1607 | dsaswideprintk((KERN_DEBUG | ||
1608 | "sas_port_alloc: port=%p dev=%p port_id=%d\n", | ||
1609 | port, dev, port->port_identifier)); | ||
1628 | } | 1610 | } |
1629 | dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", | 1611 | dsaswideprintk((KERN_DEBUG "sas_port_add_phy: phy_id=%d\n", |
1630 | phy_info->phy_id)); | 1612 | phy_info->phy_id)); |
@@ -1736,7 +1718,6 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
1736 | hba = NULL; | 1718 | hba = NULL; |
1737 | } | 1719 | } |
1738 | mutex_unlock(&ioc->sas_topology_mutex); | 1720 | mutex_unlock(&ioc->sas_topology_mutex); |
1739 | ioc->num_ports = port_info->num_phys; | ||
1740 | 1721 | ||
1741 | for (i = 0; i < port_info->num_phys; i++) { | 1722 | for (i = 0; i < port_info->num_phys; i++) { |
1742 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], | 1723 | mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], |
@@ -1939,7 +1920,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc) | |||
1939 | expander_sas_address) | 1920 | expander_sas_address) |
1940 | continue; | 1921 | continue; |
1941 | #ifdef MPT_DEBUG_SAS_WIDE | 1922 | #ifdef MPT_DEBUG_SAS_WIDE |
1942 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); | 1923 | dev_printk(KERN_DEBUG, &port->dev, |
1924 | "delete port (%d)\n", port->port_identifier); | ||
1943 | #endif | 1925 | #endif |
1944 | sas_port_delete(port); | 1926 | sas_port_delete(port); |
1945 | mptsas_port_delete(phy_info->port_details); | 1927 | mptsas_port_delete(phy_info->port_details); |
@@ -1984,7 +1966,7 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc) | |||
1984 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) | 1966 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) |
1985 | goto out; | 1967 | goto out; |
1986 | for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | 1968 | for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { |
1987 | scsi_add_device(ioc->sh, ioc->num_ports, | 1969 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, |
1988 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); | 1970 | ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0); |
1989 | } | 1971 | } |
1990 | out: | 1972 | out: |
@@ -2185,7 +2167,8 @@ mptsas_hotplug_work(void *arg) | |||
2185 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); | 2167 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); |
2186 | 2168 | ||
2187 | #ifdef MPT_DEBUG_SAS_WIDE | 2169 | #ifdef MPT_DEBUG_SAS_WIDE |
2188 | dev_printk(KERN_DEBUG, &port->dev, "delete\n"); | 2170 | dev_printk(KERN_DEBUG, &port->dev, |
2171 | "delete port (%d)\n", port->port_identifier); | ||
2189 | #endif | 2172 | #endif |
2190 | sas_port_delete(port); | 2173 | sas_port_delete(port); |
2191 | mptsas_port_delete(phy_info->port_details); | 2174 | mptsas_port_delete(phy_info->port_details); |
@@ -2289,35 +2272,26 @@ mptsas_hotplug_work(void *arg) | |||
2289 | mptsas_set_rphy(phy_info, rphy); | 2272 | mptsas_set_rphy(phy_info, rphy); |
2290 | break; | 2273 | break; |
2291 | case MPTSAS_ADD_RAID: | 2274 | case MPTSAS_ADD_RAID: |
2292 | sdev = scsi_device_lookup( | 2275 | sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, |
2293 | ioc->sh, | 2276 | ev->id, 0); |
2294 | ioc->num_ports, | ||
2295 | ev->id, | ||
2296 | 0); | ||
2297 | if (sdev) { | 2277 | if (sdev) { |
2298 | scsi_device_put(sdev); | 2278 | scsi_device_put(sdev); |
2299 | break; | 2279 | break; |
2300 | } | 2280 | } |
2301 | printk(MYIOC_s_INFO_FMT | 2281 | printk(MYIOC_s_INFO_FMT |
2302 | "attaching raid volume, channel %d, id %d\n", | 2282 | "attaching raid volume, channel %d, id %d\n", |
2303 | ioc->name, ioc->num_ports, ev->id); | 2283 | ioc->name, MPTSAS_RAID_CHANNEL, ev->id); |
2304 | scsi_add_device(ioc->sh, | 2284 | scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0); |
2305 | ioc->num_ports, | ||
2306 | ev->id, | ||
2307 | 0); | ||
2308 | mpt_findImVolumes(ioc); | 2285 | mpt_findImVolumes(ioc); |
2309 | break; | 2286 | break; |
2310 | case MPTSAS_DEL_RAID: | 2287 | case MPTSAS_DEL_RAID: |
2311 | sdev = scsi_device_lookup( | 2288 | sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, |
2312 | ioc->sh, | 2289 | ev->id, 0); |
2313 | ioc->num_ports, | ||
2314 | ev->id, | ||
2315 | 0); | ||
2316 | if (!sdev) | 2290 | if (!sdev) |
2317 | break; | 2291 | break; |
2318 | printk(MYIOC_s_INFO_FMT | 2292 | printk(MYIOC_s_INFO_FMT |
2319 | "removing raid volume, channel %d, id %d\n", | 2293 | "removing raid volume, channel %d, id %d\n", |
2320 | ioc->name, ioc->num_ports, ev->id); | 2294 | ioc->name, MPTSAS_RAID_CHANNEL, ev->id); |
2321 | vdevice = sdev->hostdata; | 2295 | vdevice = sdev->hostdata; |
2322 | vdevice->vtarget->deleted = 1; | 2296 | vdevice->vtarget->deleted = 1; |
2323 | mptsas_target_reset(ioc, vdevice->vtarget); | 2297 | mptsas_target_reset(ioc, vdevice->vtarget); |
@@ -2723,7 +2697,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2723 | hd->timer.data = (unsigned long) hd; | 2697 | hd->timer.data = (unsigned long) hd; |
2724 | hd->timer.function = mptscsih_timer_expired; | 2698 | hd->timer.function = mptscsih_timer_expired; |
2725 | 2699 | ||
2726 | hd->mpt_pq_filter = mpt_pq_filter; | ||
2727 | ioc->sas_data.ptClear = mpt_pt_clear; | 2700 | ioc->sas_data.ptClear = mpt_pt_clear; |
2728 | 2701 | ||
2729 | if (ioc->sas_data.ptClear==1) { | 2702 | if (ioc->sas_data.ptClear==1) { |
@@ -2731,12 +2704,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2731 | ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); | 2704 | ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); |
2732 | } | 2705 | } |
2733 | 2706 | ||
2734 | ddvprintk((MYIOC_s_INFO_FMT | ||
2735 | "mpt_pq_filter %x mpt_pq_filter %x\n", | ||
2736 | ioc->name, | ||
2737 | mpt_pq_filter, | ||
2738 | mpt_pq_filter)); | ||
2739 | |||
2740 | init_waitqueue_head(&hd->scandv_waitq); | 2707 | init_waitqueue_head(&hd->scandv_waitq); |
2741 | hd->scandv_wait_done = 0; | 2708 | hd->scandv_wait_done = 0; |
2742 | hd->last_queue_full = 0; | 2709 | hd->last_queue_full = 0; |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 8242b16e3168..30524dc54b16 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -66,6 +66,7 @@ | |||
66 | 66 | ||
67 | #include "mptbase.h" | 67 | #include "mptbase.h" |
68 | #include "mptscsih.h" | 68 | #include "mptscsih.h" |
69 | #include "lsi/mpi_log_sas.h" | ||
69 | 70 | ||
70 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 71 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
71 | #define my_NAME "Fusion MPT SCSI Host driver" | 72 | #define my_NAME "Fusion MPT SCSI Host driver" |
@@ -127,7 +128,7 @@ static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); | |||
127 | static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); | 128 | static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); |
128 | static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); | 129 | static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); |
129 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); | 130 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); |
130 | static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); | 131 | static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); |
131 | 132 | ||
132 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 133 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); |
133 | 134 | ||
@@ -497,6 +498,34 @@ nextSGEset: | |||
497 | return SUCCESS; | 498 | return SUCCESS; |
498 | } /* mptscsih_AddSGE() */ | 499 | } /* mptscsih_AddSGE() */ |
499 | 500 | ||
501 | static void | ||
502 | mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget, | ||
503 | U32 SlotStatus) | ||
504 | { | ||
505 | MPT_FRAME_HDR *mf; | ||
506 | SEPRequest_t *SEPMsg; | ||
507 | |||
508 | if (ioc->bus_type == FC) | ||
509 | return; | ||
510 | |||
511 | if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) { | ||
512 | dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n", | ||
513 | ioc->name,__FUNCTION__)); | ||
514 | return; | ||
515 | } | ||
516 | |||
517 | SEPMsg = (SEPRequest_t *)mf; | ||
518 | SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; | ||
519 | SEPMsg->Bus = vtarget->bus_id; | ||
520 | SEPMsg->TargetID = vtarget->target_id; | ||
521 | SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS; | ||
522 | SEPMsg->SlotStatus = SlotStatus; | ||
523 | devtverboseprintk((MYIOC_s_WARN_FMT | ||
524 | "Sending SEP cmd=%x id=%d bus=%d\n", | ||
525 | ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus)); | ||
526 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
527 | } | ||
528 | |||
500 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 529 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
501 | /* | 530 | /* |
502 | * mptscsih_io_done - Main SCSI IO callback routine registered to | 531 | * mptscsih_io_done - Main SCSI IO callback routine registered to |
@@ -520,6 +549,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
520 | SCSIIORequest_t *pScsiReq; | 549 | SCSIIORequest_t *pScsiReq; |
521 | SCSIIOReply_t *pScsiReply; | 550 | SCSIIOReply_t *pScsiReply; |
522 | u16 req_idx, req_idx_MR; | 551 | u16 req_idx, req_idx_MR; |
552 | VirtDevice *vdev; | ||
553 | VirtTarget *vtarget; | ||
523 | 554 | ||
524 | hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; | 555 | hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; |
525 | 556 | ||
@@ -538,6 +569,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
538 | } | 569 | } |
539 | 570 | ||
540 | sc = hd->ScsiLookup[req_idx]; | 571 | sc = hd->ScsiLookup[req_idx]; |
572 | hd->ScsiLookup[req_idx] = NULL; | ||
541 | if (sc == NULL) { | 573 | if (sc == NULL) { |
542 | MPIHeader_t *hdr = (MPIHeader_t *)mf; | 574 | MPIHeader_t *hdr = (MPIHeader_t *)mf; |
543 | 575 | ||
@@ -553,6 +585,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
553 | return 1; | 585 | return 1; |
554 | } | 586 | } |
555 | 587 | ||
588 | if ((unsigned char *)mf != sc->host_scribble) { | ||
589 | mptscsih_freeChainBuffers(ioc, req_idx); | ||
590 | return 1; | ||
591 | } | ||
592 | |||
593 | sc->host_scribble = NULL; | ||
556 | sc->result = DID_OK << 16; /* Set default reply as OK */ | 594 | sc->result = DID_OK << 16; /* Set default reply as OK */ |
557 | pScsiReq = (SCSIIORequest_t *) mf; | 595 | pScsiReq = (SCSIIORequest_t *) mf; |
558 | pScsiReply = (SCSIIOReply_t *) mr; | 596 | pScsiReply = (SCSIIOReply_t *) mr; |
@@ -640,10 +678,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
640 | 678 | ||
641 | if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) | 679 | if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) |
642 | hd->sel_timeout[pScsiReq->TargetID]++; | 680 | hd->sel_timeout[pScsiReq->TargetID]++; |
681 | |||
682 | vdev = sc->device->hostdata; | ||
683 | if (!vdev) | ||
684 | break; | ||
685 | vtarget = vdev->vtarget; | ||
686 | if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) { | ||
687 | mptscsih_issue_sep_command(ioc, vtarget, | ||
688 | MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED); | ||
689 | vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON; | ||
690 | } | ||
643 | break; | 691 | break; |
644 | 692 | ||
645 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | ||
646 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ | 693 | case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ |
694 | if ( ioc->bus_type == SAS ) { | ||
695 | u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus); | ||
696 | if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { | ||
697 | u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); | ||
698 | log_info &=SAS_LOGINFO_MASK; | ||
699 | if (log_info == SAS_LOGINFO_NEXUS_LOSS) { | ||
700 | sc->result = (DID_BUS_BUSY << 16); | ||
701 | break; | ||
702 | } | ||
703 | } | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * Allow non-SAS & non-NEXUS_LOSS to drop into below code | ||
708 | */ | ||
709 | |||
710 | case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ | ||
647 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ | 711 | case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ |
648 | /* Linux handles an unsolicited DID_RESET better | 712 | /* Linux handles an unsolicited DID_RESET better |
649 | * than an unsolicited DID_ABORT. | 713 | * than an unsolicited DID_ABORT. |
@@ -658,7 +722,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
658 | sc->result=DID_SOFT_ERROR << 16; | 722 | sc->result=DID_SOFT_ERROR << 16; |
659 | else /* Sufficient data transfer occurred */ | 723 | else /* Sufficient data transfer occurred */ |
660 | sc->result = (DID_OK << 16) | scsi_status; | 724 | sc->result = (DID_OK << 16) | scsi_status; |
661 | dreplyprintk((KERN_NOTICE | 725 | dreplyprintk((KERN_NOTICE |
662 | "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); | 726 | "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); |
663 | break; | 727 | break; |
664 | 728 | ||
@@ -784,8 +848,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
784 | sc->request_bufflen, sc->sc_data_direction); | 848 | sc->request_bufflen, sc->sc_data_direction); |
785 | } | 849 | } |
786 | 850 | ||
787 | hd->ScsiLookup[req_idx] = NULL; | ||
788 | |||
789 | sc->scsi_done(sc); /* Issue the command callback */ | 851 | sc->scsi_done(sc); /* Issue the command callback */ |
790 | 852 | ||
791 | /* Free Chain buffers */ | 853 | /* Free Chain buffers */ |
@@ -827,9 +889,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | |||
827 | dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", | 889 | dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", |
828 | mf, SCpnt)); | 890 | mf, SCpnt)); |
829 | 891 | ||
892 | /* Free Chain buffers */ | ||
893 | mptscsih_freeChainBuffers(ioc, ii); | ||
894 | |||
895 | /* Free Message frames */ | ||
896 | mpt_free_msg_frame(ioc, mf); | ||
897 | |||
898 | if ((unsigned char *)mf != SCpnt->host_scribble) | ||
899 | continue; | ||
900 | |||
830 | /* Set status, free OS resources (SG DMA buffers) | 901 | /* Set status, free OS resources (SG DMA buffers) |
831 | * Do OS callback | 902 | * Do OS callback |
832 | * Free driver resources (chain, msg buffers) | ||
833 | */ | 903 | */ |
834 | if (SCpnt->use_sg) { | 904 | if (SCpnt->use_sg) { |
835 | pci_unmap_sg(ioc->pcidev, | 905 | pci_unmap_sg(ioc->pcidev, |
@@ -845,12 +915,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) | |||
845 | SCpnt->result = DID_RESET << 16; | 915 | SCpnt->result = DID_RESET << 16; |
846 | SCpnt->host_scribble = NULL; | 916 | SCpnt->host_scribble = NULL; |
847 | 917 | ||
848 | /* Free Chain buffers */ | ||
849 | mptscsih_freeChainBuffers(ioc, ii); | ||
850 | |||
851 | /* Free Message frames */ | ||
852 | mpt_free_msg_frame(ioc, mf); | ||
853 | |||
854 | SCpnt->scsi_done(SCpnt); /* Issue the command callback */ | 918 | SCpnt->scsi_done(SCpnt); /* Issue the command callback */ |
855 | } | 919 | } |
856 | } | 920 | } |
@@ -887,10 +951,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
887 | if ((sc = hd->ScsiLookup[ii]) != NULL) { | 951 | if ((sc = hd->ScsiLookup[ii]) != NULL) { |
888 | 952 | ||
889 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); | 953 | mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); |
890 | 954 | if (mf == NULL) | |
955 | continue; | ||
891 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", | 956 | dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", |
892 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); | 957 | hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); |
893 | |||
894 | if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) | 958 | if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun))) |
895 | continue; | 959 | continue; |
896 | 960 | ||
@@ -899,6 +963,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice) | |||
899 | hd->ScsiLookup[ii] = NULL; | 963 | hd->ScsiLookup[ii] = NULL; |
900 | mptscsih_freeChainBuffers(hd->ioc, ii); | 964 | mptscsih_freeChainBuffers(hd->ioc, ii); |
901 | mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); | 965 | mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); |
966 | if ((unsigned char *)mf != sc->host_scribble) | ||
967 | continue; | ||
902 | if (sc->use_sg) { | 968 | if (sc->use_sg) { |
903 | pci_unmap_sg(hd->ioc->pcidev, | 969 | pci_unmap_sg(hd->ioc->pcidev, |
904 | (struct scatterlist *) sc->request_buffer, | 970 | (struct scatterlist *) sc->request_buffer, |
@@ -1341,8 +1407,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
1341 | goto fail; | 1407 | goto fail; |
1342 | } | 1408 | } |
1343 | 1409 | ||
1410 | SCpnt->host_scribble = (unsigned char *)mf; | ||
1344 | hd->ScsiLookup[my_idx] = SCpnt; | 1411 | hd->ScsiLookup[my_idx] = SCpnt; |
1345 | SCpnt->host_scribble = NULL; | ||
1346 | 1412 | ||
1347 | mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); | 1413 | mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); |
1348 | dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", | 1414 | dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", |
@@ -1529,6 +1595,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in | |||
1529 | rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); | 1595 | rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); |
1530 | } | 1596 | } |
1531 | 1597 | ||
1598 | /* | ||
1599 | * Check IOCStatus from TM reply message | ||
1600 | */ | ||
1601 | if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS) | ||
1602 | rc = FAILED; | ||
1603 | |||
1532 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); | 1604 | dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); |
1533 | 1605 | ||
1534 | return rc; | 1606 | return rc; |
@@ -1654,6 +1726,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1654 | int scpnt_idx; | 1726 | int scpnt_idx; |
1655 | int retval; | 1727 | int retval; |
1656 | VirtDevice *vdev; | 1728 | VirtDevice *vdev; |
1729 | ulong sn = SCpnt->serial_number; | ||
1657 | 1730 | ||
1658 | /* If we can't locate our host adapter structure, return FAILED status. | 1731 | /* If we can't locate our host adapter structure, return FAILED status. |
1659 | */ | 1732 | */ |
@@ -1707,6 +1780,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1707 | vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, | 1780 | vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, |
1708 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); | 1781 | ctx2abort, mptscsih_get_tm_timeout(hd->ioc)); |
1709 | 1782 | ||
1783 | if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx && | ||
1784 | SCpnt->serial_number == sn) { | ||
1785 | retval = FAILED; | ||
1786 | } | ||
1787 | |||
1710 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1788 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
1711 | hd->ioc->name, | 1789 | hd->ioc->name, |
1712 | ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); | 1790 | ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); |
@@ -2023,6 +2101,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m | |||
2023 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | 2101 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); |
2024 | 2102 | ||
2025 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; | 2103 | iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; |
2104 | hd->tm_iocstatus = iocstatus; | ||
2026 | dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", | 2105 | dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", |
2027 | ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); | 2106 | ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); |
2028 | /* Error? (anything non-zero?) */ | 2107 | /* Error? (anything non-zero?) */ |
@@ -2401,6 +2480,13 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2401 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; | 2480 | ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; |
2402 | 2481 | ||
2403 | ioc->eventContext++; | 2482 | ioc->eventContext++; |
2483 | if (hd->ioc->pcidev->vendor == | ||
2484 | PCI_VENDOR_ID_IBM) { | ||
2485 | mptscsih_issue_sep_command(hd->ioc, | ||
2486 | vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT); | ||
2487 | vdev->vtarget->tflags |= | ||
2488 | MPT_TARGET_FLAGS_LED_ON; | ||
2489 | } | ||
2404 | } | 2490 | } |
2405 | } | 2491 | } |
2406 | } else { | 2492 | } else { |
@@ -2409,7 +2495,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2409 | } | 2495 | } |
2410 | } | 2496 | } |
2411 | 2497 | ||
2412 | static u32 | 2498 | static int |
2413 | SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) | 2499 | SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) |
2414 | { | 2500 | { |
2415 | MPT_SCSI_HOST *hd; | 2501 | MPT_SCSI_HOST *hd; |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 0a1ff762205f..e4cc3dd5fc9f 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE; | |||
83 | module_param(mpt_saf_te, int, 0); | 83 | module_param(mpt_saf_te, int, 0); |
84 | MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)"); | 84 | MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)"); |
85 | 85 | ||
86 | static int mpt_pq_filter = 0; | ||
87 | module_param(mpt_pq_filter, int, 0); | ||
88 | MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); | ||
89 | |||
90 | static void mptspi_write_offset(struct scsi_target *, int); | 86 | static void mptspi_write_offset(struct scsi_target *, int); |
91 | static void mptspi_write_width(struct scsi_target *, int); | 87 | static void mptspi_write_width(struct scsi_target *, int); |
92 | static int mptspi_write_spi_device_pg1(struct scsi_target *, | 88 | static int mptspi_write_spi_device_pg1(struct scsi_target *, |
@@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1047 | hd->timer.function = mptscsih_timer_expired; | 1043 | hd->timer.function = mptscsih_timer_expired; |
1048 | 1044 | ||
1049 | ioc->spi_data.Saf_Te = mpt_saf_te; | 1045 | ioc->spi_data.Saf_Te = mpt_saf_te; |
1050 | hd->mpt_pq_filter = mpt_pq_filter; | ||
1051 | 1046 | ||
1052 | hd->negoNvram = MPT_SCSICFG_USE_NVRAM; | 1047 | hd->negoNvram = MPT_SCSICFG_USE_NVRAM; |
1053 | ddvprintk((MYIOC_s_INFO_FMT | 1048 | ddvprintk((MYIOC_s_INFO_FMT |
1054 | "saf_te %x mpt_pq_filter %x\n", | 1049 | "saf_te %x\n", |
1055 | ioc->name, | 1050 | ioc->name, |
1056 | mpt_saf_te, | 1051 | mpt_saf_te)); |
1057 | mpt_pq_filter)); | ||
1058 | ioc->spi_data.noQas = 0; | 1052 | ioc->spi_data.noQas = 0; |
1059 | 1053 | ||
1060 | init_waitqueue_head(&hd->scandv_waitq); | 1054 | init_waitqueue_head(&hd->scandv_waitq); |
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig index b14e89004c3a..0a0e0cd81a23 100644 --- a/drivers/net/appletalk/Kconfig +++ b/drivers/net/appletalk/Kconfig | |||
@@ -29,7 +29,7 @@ config ATALK | |||
29 | even politically correct people are allowed to say Y here. | 29 | even politically correct people are allowed to say Y here. |
30 | 30 | ||
31 | config DEV_APPLETALK | 31 | config DEV_APPLETALK |
32 | bool "Appletalk interfaces support" | 32 | tristate "Appletalk interfaces support" |
33 | depends on ATALK | 33 | depends on ATALK |
34 | help | 34 | help |
35 | AppleTalk is the protocol that Apple computers can use to communicate | 35 | AppleTalk is the protocol that Apple computers can use to communicate |
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 36d511729f71..2146cf74425e 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c | |||
@@ -132,6 +132,7 @@ static int __init dummy_init_module(void) | |||
132 | for (i = 0; i < numdummies && !err; i++) | 132 | for (i = 0; i < numdummies && !err; i++) |
133 | err = dummy_init_one(i); | 133 | err = dummy_init_one(i); |
134 | if (err) { | 134 | if (err) { |
135 | i--; | ||
135 | while (--i >= 0) | 136 | while (--i >= 0) |
136 | dummy_free_one(i); | 137 | dummy_free_one(i); |
137 | } | 138 | } |
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index f411bbb44f86..d304297c496c 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -110,6 +110,9 @@ struct e1000_adapter; | |||
110 | #define E1000_MIN_RXD 80 | 110 | #define E1000_MIN_RXD 80 |
111 | #define E1000_MAX_82544_RXD 4096 | 111 | #define E1000_MAX_82544_RXD 4096 |
112 | 112 | ||
113 | /* this is the size past which hardware will drop packets when setting LPE=0 */ | ||
114 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 | ||
115 | |||
113 | /* Supported Rx Buffer Sizes */ | 116 | /* Supported Rx Buffer Sizes */ |
114 | #define E1000_RXBUFFER_128 128 /* Used for packet split */ | 117 | #define E1000_RXBUFFER_128 128 /* Used for packet split */ |
115 | #define E1000_RXBUFFER_256 256 /* Used for packet split */ | 118 | #define E1000_RXBUFFER_256 256 /* Used for packet split */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 6d3d41934503..627f224d78bc 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -36,7 +36,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; | |||
36 | #else | 36 | #else |
37 | #define DRIVERNAPI "-NAPI" | 37 | #define DRIVERNAPI "-NAPI" |
38 | #endif | 38 | #endif |
39 | #define DRV_VERSION "7.1.9-k2"DRIVERNAPI | 39 | #define DRV_VERSION "7.1.9-k4"DRIVERNAPI |
40 | char e1000_driver_version[] = DRV_VERSION; | 40 | char e1000_driver_version[] = DRV_VERSION; |
41 | static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; | 41 | static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; |
42 | 42 | ||
@@ -1068,7 +1068,7 @@ e1000_sw_init(struct e1000_adapter *adapter) | |||
1068 | 1068 | ||
1069 | pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); | 1069 | pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); |
1070 | 1070 | ||
1071 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_FRAME_SIZE; | 1071 | adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; |
1072 | adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; | 1072 | adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; |
1073 | hw->max_frame_size = netdev->mtu + | 1073 | hw->max_frame_size = netdev->mtu + |
1074 | ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; | 1074 | ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; |
@@ -3127,7 +3127,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3127 | break; | 3127 | break; |
3128 | } | 3128 | } |
3129 | 3129 | ||
3130 | /* NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN | 3130 | /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN |
3131 | * means we reserve 2 more, this pushes us to allocate from the next | 3131 | * means we reserve 2 more, this pushes us to allocate from the next |
3132 | * larger slab size | 3132 | * larger slab size |
3133 | * i.e. RXBUFFER_2048 --> size-4096 slab */ | 3133 | * i.e. RXBUFFER_2048 --> size-4096 slab */ |
@@ -3148,7 +3148,6 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
3148 | adapter->rx_buffer_len = E1000_RXBUFFER_16384; | 3148 | adapter->rx_buffer_len = E1000_RXBUFFER_16384; |
3149 | 3149 | ||
3150 | /* adjust allocation if LPE protects us, and we aren't using SBP */ | 3150 | /* adjust allocation if LPE protects us, and we aren't using SBP */ |
3151 | #define MAXIMUM_ETHERNET_VLAN_SIZE 1522 | ||
3152 | if (!adapter->hw.tbi_compatibility_on && | 3151 | if (!adapter->hw.tbi_compatibility_on && |
3153 | ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || | 3152 | ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || |
3154 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) | 3153 | (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) |
@@ -3387,8 +3386,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) | |||
3387 | E1000_WRITE_REG(hw, IMC, ~0); | 3386 | E1000_WRITE_REG(hw, IMC, ~0); |
3388 | E1000_WRITE_FLUSH(hw); | 3387 | E1000_WRITE_FLUSH(hw); |
3389 | } | 3388 | } |
3390 | if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) | 3389 | if (likely(netif_rx_schedule_prep(netdev))) |
3391 | __netif_rx_schedule(&adapter->polling_netdev[0]); | 3390 | __netif_rx_schedule(netdev); |
3392 | else | 3391 | else |
3393 | e1000_irq_enable(adapter); | 3392 | e1000_irq_enable(adapter); |
3394 | #else | 3393 | #else |
@@ -3431,34 +3430,26 @@ e1000_clean(struct net_device *poll_dev, int *budget) | |||
3431 | { | 3430 | { |
3432 | struct e1000_adapter *adapter; | 3431 | struct e1000_adapter *adapter; |
3433 | int work_to_do = min(*budget, poll_dev->quota); | 3432 | int work_to_do = min(*budget, poll_dev->quota); |
3434 | int tx_cleaned = 0, i = 0, work_done = 0; | 3433 | int tx_cleaned = 0, work_done = 0; |
3435 | 3434 | ||
3436 | /* Must NOT use netdev_priv macro here. */ | 3435 | /* Must NOT use netdev_priv macro here. */ |
3437 | adapter = poll_dev->priv; | 3436 | adapter = poll_dev->priv; |
3438 | 3437 | ||
3439 | /* Keep link state information with original netdev */ | 3438 | /* Keep link state information with original netdev */ |
3440 | if (!netif_carrier_ok(adapter->netdev)) | 3439 | if (!netif_carrier_ok(poll_dev)) |
3441 | goto quit_polling; | 3440 | goto quit_polling; |
3442 | 3441 | ||
3443 | while (poll_dev != &adapter->polling_netdev[i]) { | 3442 | /* e1000_clean is called per-cpu. This lock protects |
3444 | i++; | 3443 | * tx_ring[0] from being cleaned by multiple cpus |
3445 | BUG_ON(i == adapter->num_rx_queues); | 3444 | * simultaneously. A failure obtaining the lock means |
3445 | * tx_ring[0] is currently being cleaned anyway. */ | ||
3446 | if (spin_trylock(&adapter->tx_queue_lock)) { | ||
3447 | tx_cleaned = e1000_clean_tx_irq(adapter, | ||
3448 | &adapter->tx_ring[0]); | ||
3449 | spin_unlock(&adapter->tx_queue_lock); | ||
3446 | } | 3450 | } |
3447 | 3451 | ||
3448 | if (likely(adapter->num_tx_queues == 1)) { | 3452 | adapter->clean_rx(adapter, &adapter->rx_ring[0], |
3449 | /* e1000_clean is called per-cpu. This lock protects | ||
3450 | * tx_ring[0] from being cleaned by multiple cpus | ||
3451 | * simultaneously. A failure obtaining the lock means | ||
3452 | * tx_ring[0] is currently being cleaned anyway. */ | ||
3453 | if (spin_trylock(&adapter->tx_queue_lock)) { | ||
3454 | tx_cleaned = e1000_clean_tx_irq(adapter, | ||
3455 | &adapter->tx_ring[0]); | ||
3456 | spin_unlock(&adapter->tx_queue_lock); | ||
3457 | } | ||
3458 | } else | ||
3459 | tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]); | ||
3460 | |||
3461 | adapter->clean_rx(adapter, &adapter->rx_ring[i], | ||
3462 | &work_done, work_to_do); | 3453 | &work_done, work_to_do); |
3463 | 3454 | ||
3464 | *budget -= work_done; | 3455 | *budget -= work_done; |
@@ -3466,7 +3457,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) | |||
3466 | 3457 | ||
3467 | /* If no Tx and not enough Rx work done, exit the polling mode */ | 3458 | /* If no Tx and not enough Rx work done, exit the polling mode */ |
3468 | if ((!tx_cleaned && (work_done == 0)) || | 3459 | if ((!tx_cleaned && (work_done == 0)) || |
3469 | !netif_running(adapter->netdev)) { | 3460 | !netif_running(poll_dev)) { |
3470 | quit_polling: | 3461 | quit_polling: |
3471 | netif_rx_complete(poll_dev); | 3462 | netif_rx_complete(poll_dev); |
3472 | e1000_irq_enable(adapter); | 3463 | e1000_irq_enable(adapter); |
@@ -3681,6 +3672,9 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3681 | 3672 | ||
3682 | length = le16_to_cpu(rx_desc->length); | 3673 | length = le16_to_cpu(rx_desc->length); |
3683 | 3674 | ||
3675 | /* adjust length to remove Ethernet CRC */ | ||
3676 | length -= 4; | ||
3677 | |||
3684 | if (unlikely(!(status & E1000_RXD_STAT_EOP))) { | 3678 | if (unlikely(!(status & E1000_RXD_STAT_EOP))) { |
3685 | /* All receives must fit into a single buffer */ | 3679 | /* All receives must fit into a single buffer */ |
3686 | E1000_DBG("%s: Receive packet consumed multiple" | 3680 | E1000_DBG("%s: Receive packet consumed multiple" |
@@ -3714,7 +3708,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
3714 | #define E1000_CB_LENGTH 256 | 3708 | #define E1000_CB_LENGTH 256 |
3715 | if (length < E1000_CB_LENGTH) { | 3709 | if (length < E1000_CB_LENGTH) { |
3716 | struct sk_buff *new_skb = | 3710 | struct sk_buff *new_skb = |
3717 | dev_alloc_skb(length + NET_IP_ALIGN); | 3711 | netdev_alloc_skb(netdev, length + NET_IP_ALIGN); |
3718 | if (new_skb) { | 3712 | if (new_skb) { |
3719 | skb_reserve(new_skb, NET_IP_ALIGN); | 3713 | skb_reserve(new_skb, NET_IP_ALIGN); |
3720 | new_skb->dev = netdev; | 3714 | new_skb->dev = netdev; |
@@ -3885,8 +3879,9 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3885 | pci_dma_sync_single_for_device(pdev, | 3879 | pci_dma_sync_single_for_device(pdev, |
3886 | ps_page_dma->ps_page_dma[0], | 3880 | ps_page_dma->ps_page_dma[0], |
3887 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 3881 | PAGE_SIZE, PCI_DMA_FROMDEVICE); |
3882 | /* remove the CRC */ | ||
3883 | l1 -= 4; | ||
3888 | skb_put(skb, l1); | 3884 | skb_put(skb, l1); |
3889 | length += l1; | ||
3890 | goto copydone; | 3885 | goto copydone; |
3891 | } /* if */ | 3886 | } /* if */ |
3892 | } | 3887 | } |
@@ -3905,6 +3900,10 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3905 | skb->truesize += length; | 3900 | skb->truesize += length; |
3906 | } | 3901 | } |
3907 | 3902 | ||
3903 | /* strip the ethernet crc, problem is we're using pages now so | ||
3904 | * this whole operation can get a little cpu intensive */ | ||
3905 | pskb_trim(skb, skb->len - 4); | ||
3906 | |||
3908 | copydone: | 3907 | copydone: |
3909 | e1000_rx_checksum(adapter, staterr, | 3908 | e1000_rx_checksum(adapter, staterr, |
3910 | le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); | 3909 | le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); |
@@ -3980,7 +3979,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, | |||
3980 | 3979 | ||
3981 | while (cleaned_count--) { | 3980 | while (cleaned_count--) { |
3982 | if (!(skb = buffer_info->skb)) | 3981 | if (!(skb = buffer_info->skb)) |
3983 | skb = dev_alloc_skb(bufsz); | 3982 | skb = netdev_alloc_skb(netdev, bufsz); |
3984 | else { | 3983 | else { |
3985 | skb_trim(skb, 0); | 3984 | skb_trim(skb, 0); |
3986 | goto map_skb; | 3985 | goto map_skb; |
@@ -3998,7 +3997,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, | |||
3998 | DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes " | 3997 | DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes " |
3999 | "at %p\n", bufsz, skb->data); | 3998 | "at %p\n", bufsz, skb->data); |
4000 | /* Try again, without freeing the previous */ | 3999 | /* Try again, without freeing the previous */ |
4001 | skb = dev_alloc_skb(bufsz); | 4000 | skb = netdev_alloc_skb(netdev, bufsz); |
4002 | /* Failed allocation, critical failure */ | 4001 | /* Failed allocation, critical failure */ |
4003 | if (!skb) { | 4002 | if (!skb) { |
4004 | dev_kfree_skb(oldskb); | 4003 | dev_kfree_skb(oldskb); |
@@ -4122,7 +4121,8 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, | |||
4122 | rx_desc->read.buffer_addr[j+1] = ~0; | 4121 | rx_desc->read.buffer_addr[j+1] = ~0; |
4123 | } | 4122 | } |
4124 | 4123 | ||
4125 | skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN); | 4124 | skb = netdev_alloc_skb(netdev, |
4125 | adapter->rx_ps_bsize0 + NET_IP_ALIGN); | ||
4126 | 4126 | ||
4127 | if (unlikely(!skb)) { | 4127 | if (unlikely(!skb)) { |
4128 | adapter->alloc_rx_buff_failed++; | 4128 | adapter->alloc_rx_buff_failed++; |
@@ -4752,6 +4752,7 @@ static void | |||
4752 | e1000_netpoll(struct net_device *netdev) | 4752 | e1000_netpoll(struct net_device *netdev) |
4753 | { | 4753 | { |
4754 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4754 | struct e1000_adapter *adapter = netdev_priv(netdev); |
4755 | |||
4755 | disable_irq(adapter->pdev->irq); | 4756 | disable_irq(adapter->pdev->irq); |
4756 | e1000_intr(adapter->pdev->irq, netdev, NULL); | 4757 | e1000_intr(adapter->pdev->irq, netdev, NULL); |
4757 | e1000_clean_tx_irq(adapter, adapter->tx_ring); | 4758 | e1000_clean_tx_irq(adapter, adapter->tx_ring); |
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 3a42afab5036..43e3f33ed5e2 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -271,6 +271,7 @@ static int __init ifb_init_module(void) | |||
271 | for (i = 0; i < numifbs && !err; i++) | 271 | for (i = 0; i < numifbs && !err; i++) |
272 | err = ifb_init_one(i); | 272 | err = ifb_init_one(i); |
273 | if (err) { | 273 | if (err) { |
274 | i--; | ||
274 | while (--i >= 0) | 275 | while (--i >= 0) |
275 | ifb_free_one(i); | 276 | ifb_free_one(i); |
276 | } | 277 | } |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 07ca9480a6fe..06440a86baef 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -177,6 +177,7 @@ struct myri10ge_priv { | |||
177 | struct work_struct watchdog_work; | 177 | struct work_struct watchdog_work; |
178 | struct timer_list watchdog_timer; | 178 | struct timer_list watchdog_timer; |
179 | int watchdog_tx_done; | 179 | int watchdog_tx_done; |
180 | int watchdog_tx_req; | ||
180 | int watchdog_resets; | 181 | int watchdog_resets; |
181 | int tx_linearized; | 182 | int tx_linearized; |
182 | int pause; | 183 | int pause; |
@@ -448,6 +449,7 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) | |||
448 | struct mcp_gen_header *hdr; | 449 | struct mcp_gen_header *hdr; |
449 | size_t hdr_offset; | 450 | size_t hdr_offset; |
450 | int status; | 451 | int status; |
452 | unsigned i; | ||
451 | 453 | ||
452 | if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { | 454 | if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { |
453 | dev_err(dev, "Unable to load %s firmware image via hotplug\n", | 455 | dev_err(dev, "Unable to load %s firmware image via hotplug\n", |
@@ -479,18 +481,12 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) | |||
479 | goto abort_with_fw; | 481 | goto abort_with_fw; |
480 | 482 | ||
481 | crc = crc32(~0, fw->data, fw->size); | 483 | crc = crc32(~0, fw->data, fw->size); |
482 | if (mgp->tx.boundary == 2048) { | 484 | for (i = 0; i < fw->size; i += 256) { |
483 | /* Avoid PCI burst on chipset with unaligned completions. */ | 485 | myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i, |
484 | int i; | 486 | fw->data + i, |
485 | __iomem u32 *ptr = (__iomem u32 *) (mgp->sram + | 487 | min(256U, (unsigned)(fw->size - i))); |
486 | MYRI10GE_FW_OFFSET); | 488 | mb(); |
487 | for (i = 0; i < fw->size / 4; i++) { | 489 | readb(mgp->sram); |
488 | __raw_writel(((u32 *) fw->data)[i], ptr + i); | ||
489 | wmb(); | ||
490 | } | ||
491 | } else { | ||
492 | myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data, | ||
493 | fw->size); | ||
494 | } | 490 | } |
495 | /* corruption checking is good for parity recovery and buggy chipset */ | 491 | /* corruption checking is good for parity recovery and buggy chipset */ |
496 | memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); | 492 | memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); |
@@ -620,7 +616,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) | |||
620 | return -ENXIO; | 616 | return -ENXIO; |
621 | } | 617 | } |
622 | dev_info(&mgp->pdev->dev, "handoff confirmed\n"); | 618 | dev_info(&mgp->pdev->dev, "handoff confirmed\n"); |
623 | myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); | 619 | myri10ge_dummy_rdma(mgp, 1); |
624 | 620 | ||
625 | return 0; | 621 | return 0; |
626 | } | 622 | } |
@@ -2547,7 +2543,8 @@ static void myri10ge_watchdog_timer(unsigned long arg) | |||
2547 | 2543 | ||
2548 | mgp = (struct myri10ge_priv *)arg; | 2544 | mgp = (struct myri10ge_priv *)arg; |
2549 | if (mgp->tx.req != mgp->tx.done && | 2545 | if (mgp->tx.req != mgp->tx.done && |
2550 | mgp->tx.done == mgp->watchdog_tx_done) | 2546 | mgp->tx.done == mgp->watchdog_tx_done && |
2547 | mgp->watchdog_tx_req != mgp->watchdog_tx_done) | ||
2551 | /* nic seems like it might be stuck.. */ | 2548 | /* nic seems like it might be stuck.. */ |
2552 | schedule_work(&mgp->watchdog_work); | 2549 | schedule_work(&mgp->watchdog_work); |
2553 | else | 2550 | else |
@@ -2556,6 +2553,7 @@ static void myri10ge_watchdog_timer(unsigned long arg) | |||
2556 | jiffies + myri10ge_watchdog_timeout * HZ); | 2553 | jiffies + myri10ge_watchdog_timeout * HZ); |
2557 | 2554 | ||
2558 | mgp->watchdog_tx_done = mgp->tx.done; | 2555 | mgp->watchdog_tx_done = mgp->tx.done; |
2556 | mgp->watchdog_tx_req = mgp->tx.req; | ||
2559 | } | 2557 | } |
2560 | 2558 | ||
2561 | static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 2559 | static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7d5c2233c252..f5aad77288f9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -419,9 +419,8 @@ void phy_start_machine(struct phy_device *phydev, | |||
419 | 419 | ||
420 | /* phy_stop_machine | 420 | /* phy_stop_machine |
421 | * | 421 | * |
422 | * description: Stops the state machine timer, sets the state to | 422 | * description: Stops the state machine timer, sets the state to UP |
423 | * UP (unless it wasn't up yet), and then frees the interrupt, | 423 | * (unless it wasn't up yet). This function must be called BEFORE |
424 | * if it is in use. This function must be called BEFORE | ||
425 | * phy_detach. | 424 | * phy_detach. |
426 | */ | 425 | */ |
427 | void phy_stop_machine(struct phy_device *phydev) | 426 | void phy_stop_machine(struct phy_device *phydev) |
@@ -433,9 +432,6 @@ void phy_stop_machine(struct phy_device *phydev) | |||
433 | phydev->state = PHY_UP; | 432 | phydev->state = PHY_UP; |
434 | spin_unlock(&phydev->lock); | 433 | spin_unlock(&phydev->lock); |
435 | 434 | ||
436 | if (phydev->irq != PHY_POLL) | ||
437 | phy_stop_interrupts(phydev); | ||
438 | |||
439 | phydev->adjust_state = NULL; | 435 | phydev->adjust_state = NULL; |
440 | } | 436 | } |
441 | 437 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e1fe3a0a7b0b..132ed32bce1a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -76,7 +76,7 @@ | |||
76 | #include "s2io.h" | 76 | #include "s2io.h" |
77 | #include "s2io-regs.h" | 77 | #include "s2io-regs.h" |
78 | 78 | ||
79 | #define DRV_VERSION "2.0.14.2" | 79 | #define DRV_VERSION "2.0.15.2" |
80 | 80 | ||
81 | /* S2io Driver name & version. */ | 81 | /* S2io Driver name & version. */ |
82 | static char s2io_driver_name[] = "Neterion"; | 82 | static char s2io_driver_name[] = "Neterion"; |
@@ -370,38 +370,50 @@ static const u64 fix_mac[] = { | |||
370 | END_SIGN | 370 | END_SIGN |
371 | }; | 371 | }; |
372 | 372 | ||
373 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | ||
374 | MODULE_LICENSE("GPL"); | ||
375 | MODULE_VERSION(DRV_VERSION); | ||
376 | |||
377 | |||
373 | /* Module Loadable parameters. */ | 378 | /* Module Loadable parameters. */ |
374 | static unsigned int tx_fifo_num = 1; | 379 | S2IO_PARM_INT(tx_fifo_num, 1); |
375 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | 380 | S2IO_PARM_INT(rx_ring_num, 1); |
376 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; | 381 | |
377 | static unsigned int rx_ring_num = 1; | 382 | |
378 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 383 | S2IO_PARM_INT(rx_ring_mode, 1); |
379 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; | 384 | S2IO_PARM_INT(use_continuous_tx_intrs, 1); |
380 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | 385 | S2IO_PARM_INT(rmac_pause_time, 0x100); |
381 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 386 | S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); |
382 | static unsigned int rx_ring_mode = 1; | 387 | S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); |
383 | static unsigned int use_continuous_tx_intrs = 1; | 388 | S2IO_PARM_INT(shared_splits, 0); |
384 | static unsigned int rmac_pause_time = 0x100; | 389 | S2IO_PARM_INT(tmac_util_period, 5); |
385 | static unsigned int mc_pause_threshold_q0q3 = 187; | 390 | S2IO_PARM_INT(rmac_util_period, 5); |
386 | static unsigned int mc_pause_threshold_q4q7 = 187; | 391 | S2IO_PARM_INT(bimodal, 0); |
387 | static unsigned int shared_splits; | 392 | S2IO_PARM_INT(l3l4hdr_size, 128); |
388 | static unsigned int tmac_util_period = 5; | ||
389 | static unsigned int rmac_util_period = 5; | ||
390 | static unsigned int bimodal = 0; | ||
391 | static unsigned int l3l4hdr_size = 128; | ||
392 | #ifndef CONFIG_S2IO_NAPI | ||
393 | static unsigned int indicate_max_pkts; | ||
394 | #endif | ||
395 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 393 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
396 | static unsigned int rxsync_frequency = 3; | 394 | S2IO_PARM_INT(rxsync_frequency, 3); |
397 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ | 395 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ |
398 | static unsigned int intr_type = 0; | 396 | S2IO_PARM_INT(intr_type, 0); |
399 | /* Large receive offload feature */ | 397 | /* Large receive offload feature */ |
400 | static unsigned int lro = 0; | 398 | S2IO_PARM_INT(lro, 0); |
401 | /* Max pkts to be aggregated by LRO at one time. If not specified, | 399 | /* Max pkts to be aggregated by LRO at one time. If not specified, |
402 | * aggregation happens until we hit max IP pkt size(64K) | 400 | * aggregation happens until we hit max IP pkt size(64K) |
403 | */ | 401 | */ |
404 | static unsigned int lro_max_pkts = 0xFFFF; | 402 | S2IO_PARM_INT(lro_max_pkts, 0xFFFF); |
403 | #ifndef CONFIG_S2IO_NAPI | ||
404 | S2IO_PARM_INT(indicate_max_pkts, 0); | ||
405 | #endif | ||
406 | |||
407 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | ||
408 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; | ||
409 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | ||
410 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; | ||
411 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | ||
412 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | ||
413 | |||
414 | module_param_array(tx_fifo_len, uint, NULL, 0); | ||
415 | module_param_array(rx_ring_sz, uint, NULL, 0); | ||
416 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
405 | 417 | ||
406 | /* | 418 | /* |
407 | * S2IO device table. | 419 | * S2IO device table. |
@@ -464,10 +476,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
464 | size += config->tx_cfg[i].fifo_len; | 476 | size += config->tx_cfg[i].fifo_len; |
465 | } | 477 | } |
466 | if (size > MAX_AVAILABLE_TXDS) { | 478 | if (size > MAX_AVAILABLE_TXDS) { |
467 | DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", | 479 | DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, "); |
468 | __FUNCTION__); | ||
469 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); | 480 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); |
470 | return FAILURE; | 481 | return -EINVAL; |
471 | } | 482 | } |
472 | 483 | ||
473 | lst_size = (sizeof(TxD_t) * config->max_txds); | 484 | lst_size = (sizeof(TxD_t) * config->max_txds); |
@@ -547,6 +558,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
547 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); | 558 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); |
548 | if (!nic->ufo_in_band_v) | 559 | if (!nic->ufo_in_band_v) |
549 | return -ENOMEM; | 560 | return -ENOMEM; |
561 | memset(nic->ufo_in_band_v, 0, size); | ||
550 | 562 | ||
551 | /* Allocation and initialization of RXDs in Rings */ | 563 | /* Allocation and initialization of RXDs in Rings */ |
552 | size = 0; | 564 | size = 0; |
@@ -1213,7 +1225,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1213 | break; | 1225 | break; |
1214 | } | 1226 | } |
1215 | 1227 | ||
1216 | /* Enable Tx FIFO partition 0. */ | 1228 | /* Enable all configured Tx FIFO partitions */ |
1217 | val64 = readq(&bar0->tx_fifo_partition_0); | 1229 | val64 = readq(&bar0->tx_fifo_partition_0); |
1218 | val64 |= (TX_FIFO_PARTITION_EN); | 1230 | val64 |= (TX_FIFO_PARTITION_EN); |
1219 | writeq(val64, &bar0->tx_fifo_partition_0); | 1231 | writeq(val64, &bar0->tx_fifo_partition_0); |
@@ -1650,7 +1662,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1650 | writeq(temp64, &bar0->general_int_mask); | 1662 | writeq(temp64, &bar0->general_int_mask); |
1651 | /* | 1663 | /* |
1652 | * If Hercules adapter enable GPIO otherwise | 1664 | * If Hercules adapter enable GPIO otherwise |
1653 | * disabled all PCIX, Flash, MDIO, IIC and GPIO | 1665 | * disable all PCIX, Flash, MDIO, IIC and GPIO |
1654 | * interrupts for now. | 1666 | * interrupts for now. |
1655 | * TODO | 1667 | * TODO |
1656 | */ | 1668 | */ |
@@ -2119,7 +2131,7 @@ static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, in | |||
2119 | frag->size, PCI_DMA_TODEVICE); | 2131 | frag->size, PCI_DMA_TODEVICE); |
2120 | } | 2132 | } |
2121 | } | 2133 | } |
2122 | txdlp->Host_Control = 0; | 2134 | memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); |
2123 | return(skb); | 2135 | return(skb); |
2124 | } | 2136 | } |
2125 | 2137 | ||
@@ -2371,9 +2383,14 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2371 | skb->data = (void *) (unsigned long)tmp; | 2383 | skb->data = (void *) (unsigned long)tmp; |
2372 | skb->tail = (void *) (unsigned long)tmp; | 2384 | skb->tail = (void *) (unsigned long)tmp; |
2373 | 2385 | ||
2374 | ((RxD3_t*)rxdp)->Buffer0_ptr = | 2386 | if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) |
2375 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | 2387 | ((RxD3_t*)rxdp)->Buffer0_ptr = |
2388 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | ||
2376 | PCI_DMA_FROMDEVICE); | 2389 | PCI_DMA_FROMDEVICE); |
2390 | else | ||
2391 | pci_dma_sync_single_for_device(nic->pdev, | ||
2392 | (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, | ||
2393 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2377 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2394 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
2378 | if (nic->rxd_mode == RXD_MODE_3B) { | 2395 | if (nic->rxd_mode == RXD_MODE_3B) { |
2379 | /* Two buffer mode */ | 2396 | /* Two buffer mode */ |
@@ -2386,10 +2403,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2386 | (nic->pdev, skb->data, dev->mtu + 4, | 2403 | (nic->pdev, skb->data, dev->mtu + 4, |
2387 | PCI_DMA_FROMDEVICE); | 2404 | PCI_DMA_FROMDEVICE); |
2388 | 2405 | ||
2389 | /* Buffer-1 will be dummy buffer not used */ | 2406 | /* Buffer-1 will be dummy buffer. Not used */ |
2390 | ((RxD3_t*)rxdp)->Buffer1_ptr = | 2407 | if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { |
2391 | pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, | 2408 | ((RxD3_t*)rxdp)->Buffer1_ptr = |
2392 | PCI_DMA_FROMDEVICE); | 2409 | pci_map_single(nic->pdev, |
2410 | ba->ba_1, BUF1_LEN, | ||
2411 | PCI_DMA_FROMDEVICE); | ||
2412 | } | ||
2393 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); | 2413 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); |
2394 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 | 2414 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 |
2395 | (dev->mtu + 4); | 2415 | (dev->mtu + 4); |
@@ -2614,23 +2634,23 @@ no_rx: | |||
2614 | } | 2634 | } |
2615 | #endif | 2635 | #endif |
2616 | 2636 | ||
2637 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2617 | /** | 2638 | /** |
2618 | * s2io_netpoll - Rx interrupt service handler for netpoll support | 2639 | * s2io_netpoll - netpoll event handler entry point |
2619 | * @dev : pointer to the device structure. | 2640 | * @dev : pointer to the device structure. |
2620 | * Description: | 2641 | * Description: |
2621 | * Polling 'interrupt' - used by things like netconsole to send skbs | 2642 | * This function will be called by upper layer to check for events on the |
2622 | * without having to re-enable interrupts. It's not called while | 2643 | * interface in situations where interrupts are disabled. It is used for |
2623 | * the interrupt routine is executing. | 2644 | * specific in-kernel networking tasks, such as remote consoles and kernel |
2645 | * debugging over the network (example netdump in RedHat). | ||
2624 | */ | 2646 | */ |
2625 | |||
2626 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2627 | static void s2io_netpoll(struct net_device *dev) | 2647 | static void s2io_netpoll(struct net_device *dev) |
2628 | { | 2648 | { |
2629 | nic_t *nic = dev->priv; | 2649 | nic_t *nic = dev->priv; |
2630 | mac_info_t *mac_control; | 2650 | mac_info_t *mac_control; |
2631 | struct config_param *config; | 2651 | struct config_param *config; |
2632 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2652 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
2633 | u64 val64; | 2653 | u64 val64 = 0xFFFFFFFFFFFFFFFFULL; |
2634 | int i; | 2654 | int i; |
2635 | 2655 | ||
2636 | disable_irq(dev->irq); | 2656 | disable_irq(dev->irq); |
@@ -2639,9 +2659,17 @@ static void s2io_netpoll(struct net_device *dev) | |||
2639 | mac_control = &nic->mac_control; | 2659 | mac_control = &nic->mac_control; |
2640 | config = &nic->config; | 2660 | config = &nic->config; |
2641 | 2661 | ||
2642 | val64 = readq(&bar0->rx_traffic_int); | ||
2643 | writeq(val64, &bar0->rx_traffic_int); | 2662 | writeq(val64, &bar0->rx_traffic_int); |
2663 | writeq(val64, &bar0->tx_traffic_int); | ||
2644 | 2664 | ||
2665 | /* we need to free up the transmitted skbufs or else netpoll will | ||
2666 | * run out of skbs and will fail and eventually netpoll application such | ||
2667 | * as netdump will fail. | ||
2668 | */ | ||
2669 | for (i = 0; i < config->tx_fifo_num; i++) | ||
2670 | tx_intr_handler(&mac_control->fifos[i]); | ||
2671 | |||
2672 | /* check for received packet and indicate up to network */ | ||
2645 | for (i = 0; i < config->rx_ring_num; i++) | 2673 | for (i = 0; i < config->rx_ring_num; i++) |
2646 | rx_intr_handler(&mac_control->rings[i]); | 2674 | rx_intr_handler(&mac_control->rings[i]); |
2647 | 2675 | ||
@@ -2708,7 +2736,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2708 | /* If your are next to put index then it's FIFO full condition */ | 2736 | /* If your are next to put index then it's FIFO full condition */ |
2709 | if ((get_block == put_block) && | 2737 | if ((get_block == put_block) && |
2710 | (get_info.offset + 1) == put_info.offset) { | 2738 | (get_info.offset + 1) == put_info.offset) { |
2711 | DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name); | 2739 | DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); |
2712 | break; | 2740 | break; |
2713 | } | 2741 | } |
2714 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); | 2742 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); |
@@ -2728,18 +2756,15 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2728 | HEADER_SNAP_SIZE, | 2756 | HEADER_SNAP_SIZE, |
2729 | PCI_DMA_FROMDEVICE); | 2757 | PCI_DMA_FROMDEVICE); |
2730 | } else if (nic->rxd_mode == RXD_MODE_3B) { | 2758 | } else if (nic->rxd_mode == RXD_MODE_3B) { |
2731 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2759 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2732 | ((RxD3_t*)rxdp)->Buffer0_ptr, | 2760 | ((RxD3_t*)rxdp)->Buffer0_ptr, |
2733 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2761 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2734 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2762 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2735 | ((RxD3_t*)rxdp)->Buffer1_ptr, | ||
2736 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2737 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2738 | ((RxD3_t*)rxdp)->Buffer2_ptr, | 2763 | ((RxD3_t*)rxdp)->Buffer2_ptr, |
2739 | dev->mtu + 4, | 2764 | dev->mtu + 4, |
2740 | PCI_DMA_FROMDEVICE); | 2765 | PCI_DMA_FROMDEVICE); |
2741 | } else { | 2766 | } else { |
2742 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2767 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2743 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, | 2768 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, |
2744 | PCI_DMA_FROMDEVICE); | 2769 | PCI_DMA_FROMDEVICE); |
2745 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2770 | pci_unmap_single(nic->pdev, (dma_addr_t) |
@@ -3327,7 +3352,7 @@ static void s2io_reset(nic_t * sp) | |||
3327 | 3352 | ||
3328 | /* Clear certain PCI/PCI-X fields after reset */ | 3353 | /* Clear certain PCI/PCI-X fields after reset */ |
3329 | if (sp->device_type == XFRAME_II_DEVICE) { | 3354 | if (sp->device_type == XFRAME_II_DEVICE) { |
3330 | /* Clear parity err detect bit */ | 3355 | /* Clear "detected parity error" bit */ |
3331 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); | 3356 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); |
3332 | 3357 | ||
3333 | /* Clearing PCIX Ecc status register */ | 3358 | /* Clearing PCIX Ecc status register */ |
@@ -3528,7 +3553,7 @@ static void restore_xmsi_data(nic_t *nic) | |||
3528 | u64 val64; | 3553 | u64 val64; |
3529 | int i; | 3554 | int i; |
3530 | 3555 | ||
3531 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3556 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3532 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3557 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3533 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3558 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3534 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); | 3559 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); |
@@ -3547,7 +3572,7 @@ static void store_xmsi_data(nic_t *nic) | |||
3547 | int i; | 3572 | int i; |
3548 | 3573 | ||
3549 | /* Store and display */ | 3574 | /* Store and display */ |
3550 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3575 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3551 | val64 = (BIT(15) | vBIT(i, 26, 6)); | 3576 | val64 = (BIT(15) | vBIT(i, 26, 6)); |
3552 | writeq(val64, &bar0->xmsi_access); | 3577 | writeq(val64, &bar0->xmsi_access); |
3553 | if (wait_for_msix_trans(nic, i)) { | 3578 | if (wait_for_msix_trans(nic, i)) { |
@@ -3808,13 +3833,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3808 | TxD_t *txdp; | 3833 | TxD_t *txdp; |
3809 | TxFIFO_element_t __iomem *tx_fifo; | 3834 | TxFIFO_element_t __iomem *tx_fifo; |
3810 | unsigned long flags; | 3835 | unsigned long flags; |
3811 | #ifdef NETIF_F_TSO | ||
3812 | int mss; | ||
3813 | #endif | ||
3814 | u16 vlan_tag = 0; | 3836 | u16 vlan_tag = 0; |
3815 | int vlan_priority = 0; | 3837 | int vlan_priority = 0; |
3816 | mac_info_t *mac_control; | 3838 | mac_info_t *mac_control; |
3817 | struct config_param *config; | 3839 | struct config_param *config; |
3840 | int offload_type; | ||
3818 | 3841 | ||
3819 | mac_control = &sp->mac_control; | 3842 | mac_control = &sp->mac_control; |
3820 | config = &sp->config; | 3843 | config = &sp->config; |
@@ -3862,13 +3885,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3862 | return 0; | 3885 | return 0; |
3863 | } | 3886 | } |
3864 | 3887 | ||
3865 | txdp->Control_1 = 0; | 3888 | offload_type = s2io_offload_type(skb); |
3866 | txdp->Control_2 = 0; | ||
3867 | #ifdef NETIF_F_TSO | 3889 | #ifdef NETIF_F_TSO |
3868 | mss = skb_shinfo(skb)->gso_size; | 3890 | if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { |
3869 | if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { | ||
3870 | txdp->Control_1 |= TXD_TCP_LSO_EN; | 3891 | txdp->Control_1 |= TXD_TCP_LSO_EN; |
3871 | txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); | 3892 | txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); |
3872 | } | 3893 | } |
3873 | #endif | 3894 | #endif |
3874 | if (skb->ip_summed == CHECKSUM_HW) { | 3895 | if (skb->ip_summed == CHECKSUM_HW) { |
@@ -3886,10 +3907,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3886 | } | 3907 | } |
3887 | 3908 | ||
3888 | frg_len = skb->len - skb->data_len; | 3909 | frg_len = skb->len - skb->data_len; |
3889 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) { | 3910 | if (offload_type == SKB_GSO_UDP) { |
3890 | int ufo_size; | 3911 | int ufo_size; |
3891 | 3912 | ||
3892 | ufo_size = skb_shinfo(skb)->gso_size; | 3913 | ufo_size = s2io_udp_mss(skb); |
3893 | ufo_size &= ~7; | 3914 | ufo_size &= ~7; |
3894 | txdp->Control_1 |= TXD_UFO_EN; | 3915 | txdp->Control_1 |= TXD_UFO_EN; |
3895 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); | 3916 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); |
@@ -3906,16 +3927,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3906 | sp->ufo_in_band_v, | 3927 | sp->ufo_in_band_v, |
3907 | sizeof(u64), PCI_DMA_TODEVICE); | 3928 | sizeof(u64), PCI_DMA_TODEVICE); |
3908 | txdp++; | 3929 | txdp++; |
3909 | txdp->Control_1 = 0; | ||
3910 | txdp->Control_2 = 0; | ||
3911 | } | 3930 | } |
3912 | 3931 | ||
3913 | txdp->Buffer_Pointer = pci_map_single | 3932 | txdp->Buffer_Pointer = pci_map_single |
3914 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 3933 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
3915 | txdp->Host_Control = (unsigned long) skb; | 3934 | txdp->Host_Control = (unsigned long) skb; |
3916 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); | 3935 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); |
3917 | 3936 | if (offload_type == SKB_GSO_UDP) | |
3918 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | ||
3919 | txdp->Control_1 |= TXD_UFO_EN; | 3937 | txdp->Control_1 |= TXD_UFO_EN; |
3920 | 3938 | ||
3921 | frg_cnt = skb_shinfo(skb)->nr_frags; | 3939 | frg_cnt = skb_shinfo(skb)->nr_frags; |
@@ -3930,12 +3948,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3930 | (sp->pdev, frag->page, frag->page_offset, | 3948 | (sp->pdev, frag->page, frag->page_offset, |
3931 | frag->size, PCI_DMA_TODEVICE); | 3949 | frag->size, PCI_DMA_TODEVICE); |
3932 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); | 3950 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); |
3933 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | 3951 | if (offload_type == SKB_GSO_UDP) |
3934 | txdp->Control_1 |= TXD_UFO_EN; | 3952 | txdp->Control_1 |= TXD_UFO_EN; |
3935 | } | 3953 | } |
3936 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; | 3954 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; |
3937 | 3955 | ||
3938 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | 3956 | if (offload_type == SKB_GSO_UDP) |
3939 | frg_cnt++; /* as Txd0 was used for inband header */ | 3957 | frg_cnt++; /* as Txd0 was used for inband header */ |
3940 | 3958 | ||
3941 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 3959 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
@@ -3944,13 +3962,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3944 | 3962 | ||
3945 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 3963 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
3946 | TX_FIFO_LAST_LIST); | 3964 | TX_FIFO_LAST_LIST); |
3947 | 3965 | if (offload_type) | |
3948 | #ifdef NETIF_F_TSO | ||
3949 | if (mss) | ||
3950 | val64 |= TX_FIFO_SPECIAL_FUNC; | ||
3951 | #endif | ||
3952 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | ||
3953 | val64 |= TX_FIFO_SPECIAL_FUNC; | 3966 | val64 |= TX_FIFO_SPECIAL_FUNC; |
3967 | |||
3954 | writeq(val64, &tx_fifo->List_Control); | 3968 | writeq(val64, &tx_fifo->List_Control); |
3955 | 3969 | ||
3956 | mmiowb(); | 3970 | mmiowb(); |
@@ -3984,13 +3998,41 @@ s2io_alarm_handle(unsigned long data) | |||
3984 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 3998 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
3985 | } | 3999 | } |
3986 | 4000 | ||
4001 | static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) | ||
4002 | { | ||
4003 | int rxb_size, level; | ||
4004 | |||
4005 | if (!sp->lro) { | ||
4006 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4007 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4008 | |||
4009 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4010 | int ret; | ||
4011 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4012 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4013 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4014 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4015 | __FUNCTION__); | ||
4016 | clear_bit(0, (&sp->tasklet_status)); | ||
4017 | return -1; | ||
4018 | } | ||
4019 | clear_bit(0, (&sp->tasklet_status)); | ||
4020 | } else if (level == LOW) | ||
4021 | tasklet_schedule(&sp->task); | ||
4022 | |||
4023 | } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4024 | DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); | ||
4025 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4026 | } | ||
4027 | return 0; | ||
4028 | } | ||
4029 | |||
3987 | static irqreturn_t | 4030 | static irqreturn_t |
3988 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | 4031 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) |
3989 | { | 4032 | { |
3990 | struct net_device *dev = (struct net_device *) dev_id; | 4033 | struct net_device *dev = (struct net_device *) dev_id; |
3991 | nic_t *sp = dev->priv; | 4034 | nic_t *sp = dev->priv; |
3992 | int i; | 4035 | int i; |
3993 | int ret; | ||
3994 | mac_info_t *mac_control; | 4036 | mac_info_t *mac_control; |
3995 | struct config_param *config; | 4037 | struct config_param *config; |
3996 | 4038 | ||
@@ -4012,35 +4054,8 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4012 | * reallocate the buffers from the interrupt handler itself, | 4054 | * reallocate the buffers from the interrupt handler itself, |
4013 | * else schedule a tasklet to reallocate the buffers. | 4055 | * else schedule a tasklet to reallocate the buffers. |
4014 | */ | 4056 | */ |
4015 | for (i = 0; i < config->rx_ring_num; i++) { | 4057 | for (i = 0; i < config->rx_ring_num; i++) |
4016 | if (!sp->lro) { | 4058 | s2io_chk_rx_buffers(sp, i); |
4017 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4018 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4019 | |||
4020 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4021 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4022 | dev->name); | ||
4023 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4024 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4025 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4026 | dev->name); | ||
4027 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4028 | clear_bit(0, (&sp->tasklet_status)); | ||
4029 | atomic_dec(&sp->isr_cnt); | ||
4030 | return IRQ_HANDLED; | ||
4031 | } | ||
4032 | clear_bit(0, (&sp->tasklet_status)); | ||
4033 | } else if (level == LOW) { | ||
4034 | tasklet_schedule(&sp->task); | ||
4035 | } | ||
4036 | } | ||
4037 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4038 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4039 | dev->name); | ||
4040 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4041 | break; | ||
4042 | } | ||
4043 | } | ||
4044 | 4059 | ||
4045 | atomic_dec(&sp->isr_cnt); | 4060 | atomic_dec(&sp->isr_cnt); |
4046 | return IRQ_HANDLED; | 4061 | return IRQ_HANDLED; |
@@ -4051,39 +4066,13 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4051 | { | 4066 | { |
4052 | ring_info_t *ring = (ring_info_t *)dev_id; | 4067 | ring_info_t *ring = (ring_info_t *)dev_id; |
4053 | nic_t *sp = ring->nic; | 4068 | nic_t *sp = ring->nic; |
4054 | struct net_device *dev = (struct net_device *) dev_id; | ||
4055 | int rxb_size, level, rng_n; | ||
4056 | 4069 | ||
4057 | atomic_inc(&sp->isr_cnt); | 4070 | atomic_inc(&sp->isr_cnt); |
4058 | rx_intr_handler(ring); | ||
4059 | |||
4060 | rng_n = ring->ring_no; | ||
4061 | if (!sp->lro) { | ||
4062 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4063 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4064 | 4071 | ||
4065 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | 4072 | rx_intr_handler(ring); |
4066 | int ret; | 4073 | s2io_chk_rx_buffers(sp, ring->ring_no); |
4067 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4068 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4069 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4070 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4071 | __FUNCTION__); | ||
4072 | clear_bit(0, (&sp->tasklet_status)); | ||
4073 | return IRQ_HANDLED; | ||
4074 | } | ||
4075 | clear_bit(0, (&sp->tasklet_status)); | ||
4076 | } else if (level == LOW) { | ||
4077 | tasklet_schedule(&sp->task); | ||
4078 | } | ||
4079 | } | ||
4080 | else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4081 | DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); | ||
4082 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4083 | } | ||
4084 | 4074 | ||
4085 | atomic_dec(&sp->isr_cnt); | 4075 | atomic_dec(&sp->isr_cnt); |
4086 | |||
4087 | return IRQ_HANDLED; | 4076 | return IRQ_HANDLED; |
4088 | } | 4077 | } |
4089 | 4078 | ||
@@ -4248,37 +4237,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
4248 | * else schedule a tasklet to reallocate the buffers. | 4237 | * else schedule a tasklet to reallocate the buffers. |
4249 | */ | 4238 | */ |
4250 | #ifndef CONFIG_S2IO_NAPI | 4239 | #ifndef CONFIG_S2IO_NAPI |
4251 | for (i = 0; i < config->rx_ring_num; i++) { | 4240 | for (i = 0; i < config->rx_ring_num; i++) |
4252 | if (!sp->lro) { | 4241 | s2io_chk_rx_buffers(sp, i); |
4253 | int ret; | ||
4254 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4255 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4256 | |||
4257 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4258 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4259 | dev->name); | ||
4260 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4261 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4262 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4263 | dev->name); | ||
4264 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4265 | clear_bit(0, (&sp->tasklet_status)); | ||
4266 | atomic_dec(&sp->isr_cnt); | ||
4267 | writeq(org_mask, &bar0->general_int_mask); | ||
4268 | return IRQ_HANDLED; | ||
4269 | } | ||
4270 | clear_bit(0, (&sp->tasklet_status)); | ||
4271 | } else if (level == LOW) { | ||
4272 | tasklet_schedule(&sp->task); | ||
4273 | } | ||
4274 | } | ||
4275 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4276 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4277 | dev->name); | ||
4278 | DBG_PRINT(ERR_DBG, " in Rx intr!!\n"); | ||
4279 | break; | ||
4280 | } | ||
4281 | } | ||
4282 | #endif | 4242 | #endif |
4283 | writeq(org_mask, &bar0->general_int_mask); | 4243 | writeq(org_mask, &bar0->general_int_mask); |
4284 | atomic_dec(&sp->isr_cnt); | 4244 | atomic_dec(&sp->isr_cnt); |
@@ -4308,6 +4268,8 @@ static void s2io_updt_stats(nic_t *sp) | |||
4308 | if (cnt == 5) | 4268 | if (cnt == 5) |
4309 | break; /* Updt failed */ | 4269 | break; /* Updt failed */ |
4310 | } while(1); | 4270 | } while(1); |
4271 | } else { | ||
4272 | memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); | ||
4311 | } | 4273 | } |
4312 | } | 4274 | } |
4313 | 4275 | ||
@@ -4942,7 +4904,8 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) | |||
4942 | } | 4904 | } |
4943 | static void s2io_vpd_read(nic_t *nic) | 4905 | static void s2io_vpd_read(nic_t *nic) |
4944 | { | 4906 | { |
4945 | u8 vpd_data[256],data; | 4907 | u8 *vpd_data; |
4908 | u8 data; | ||
4946 | int i=0, cnt, fail = 0; | 4909 | int i=0, cnt, fail = 0; |
4947 | int vpd_addr = 0x80; | 4910 | int vpd_addr = 0x80; |
4948 | 4911 | ||
@@ -4955,6 +4918,10 @@ static void s2io_vpd_read(nic_t *nic) | |||
4955 | vpd_addr = 0x50; | 4918 | vpd_addr = 0x50; |
4956 | } | 4919 | } |
4957 | 4920 | ||
4921 | vpd_data = kmalloc(256, GFP_KERNEL); | ||
4922 | if (!vpd_data) | ||
4923 | return; | ||
4924 | |||
4958 | for (i = 0; i < 256; i +=4 ) { | 4925 | for (i = 0; i < 256; i +=4 ) { |
4959 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); | 4926 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); |
4960 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); | 4927 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); |
@@ -4977,6 +4944,7 @@ static void s2io_vpd_read(nic_t *nic) | |||
4977 | memset(nic->product_name, 0, vpd_data[1]); | 4944 | memset(nic->product_name, 0, vpd_data[1]); |
4978 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); | 4945 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); |
4979 | } | 4946 | } |
4947 | kfree(vpd_data); | ||
4980 | } | 4948 | } |
4981 | 4949 | ||
4982 | /** | 4950 | /** |
@@ -5295,7 +5263,7 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
5295 | else | 5263 | else |
5296 | *data = 0; | 5264 | *data = 0; |
5297 | 5265 | ||
5298 | return 0; | 5266 | return *data; |
5299 | } | 5267 | } |
5300 | 5268 | ||
5301 | /** | 5269 | /** |
@@ -5753,6 +5721,19 @@ static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
5753 | return 0; | 5721 | return 0; |
5754 | } | 5722 | } |
5755 | 5723 | ||
5724 | static u32 s2io_ethtool_op_get_tso(struct net_device *dev) | ||
5725 | { | ||
5726 | return (dev->features & NETIF_F_TSO) != 0; | ||
5727 | } | ||
5728 | static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) | ||
5729 | { | ||
5730 | if (data) | ||
5731 | dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); | ||
5732 | else | ||
5733 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
5734 | |||
5735 | return 0; | ||
5736 | } | ||
5756 | 5737 | ||
5757 | static struct ethtool_ops netdev_ethtool_ops = { | 5738 | static struct ethtool_ops netdev_ethtool_ops = { |
5758 | .get_settings = s2io_ethtool_gset, | 5739 | .get_settings = s2io_ethtool_gset, |
@@ -5773,8 +5754,8 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
5773 | .get_sg = ethtool_op_get_sg, | 5754 | .get_sg = ethtool_op_get_sg, |
5774 | .set_sg = ethtool_op_set_sg, | 5755 | .set_sg = ethtool_op_set_sg, |
5775 | #ifdef NETIF_F_TSO | 5756 | #ifdef NETIF_F_TSO |
5776 | .get_tso = ethtool_op_get_tso, | 5757 | .get_tso = s2io_ethtool_op_get_tso, |
5777 | .set_tso = ethtool_op_set_tso, | 5758 | .set_tso = s2io_ethtool_op_set_tso, |
5778 | #endif | 5759 | #endif |
5779 | .get_ufo = ethtool_op_get_ufo, | 5760 | .get_ufo = ethtool_op_get_ufo, |
5780 | .set_ufo = ethtool_op_set_ufo, | 5761 | .set_ufo = ethtool_op_set_ufo, |
@@ -6337,7 +6318,7 @@ static int s2io_card_up(nic_t * sp) | |||
6337 | s2io_set_multicast(dev); | 6318 | s2io_set_multicast(dev); |
6338 | 6319 | ||
6339 | if (sp->lro) { | 6320 | if (sp->lro) { |
6340 | /* Initialize max aggregatable pkts based on MTU */ | 6321 | /* Initialize max aggregatable pkts per session based on MTU */ |
6341 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; | 6322 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; |
6342 | /* Check if we can use(if specified) user provided value */ | 6323 | /* Check if we can use(if specified) user provided value */ |
6343 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) | 6324 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) |
@@ -6438,7 +6419,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
6438 | * @cksum : FCS checksum of the frame. | 6419 | * @cksum : FCS checksum of the frame. |
6439 | * @ring_no : the ring from which this RxD was extracted. | 6420 | * @ring_no : the ring from which this RxD was extracted. |
6440 | * Description: | 6421 | * Description: |
6441 | * This function is called by the Tx interrupt serivce routine to perform | 6422 | * This function is called by the Rx interrupt serivce routine to perform |
6442 | * some OS related operations on the SKB before passing it to the upper | 6423 | * some OS related operations on the SKB before passing it to the upper |
6443 | * layers. It mainly checks if the checksum is OK, if so adds it to the | 6424 | * layers. It mainly checks if the checksum is OK, if so adds it to the |
6444 | * SKBs cksum variable, increments the Rx packet count and passes the SKB | 6425 | * SKBs cksum variable, increments the Rx packet count and passes the SKB |
@@ -6698,33 +6679,6 @@ static void s2io_init_pci(nic_t * sp) | |||
6698 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 6679 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
6699 | } | 6680 | } |
6700 | 6681 | ||
6701 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | ||
6702 | MODULE_LICENSE("GPL"); | ||
6703 | MODULE_VERSION(DRV_VERSION); | ||
6704 | |||
6705 | module_param(tx_fifo_num, int, 0); | ||
6706 | module_param(rx_ring_num, int, 0); | ||
6707 | module_param(rx_ring_mode, int, 0); | ||
6708 | module_param_array(tx_fifo_len, uint, NULL, 0); | ||
6709 | module_param_array(rx_ring_sz, uint, NULL, 0); | ||
6710 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
6711 | module_param(use_continuous_tx_intrs, int, 1); | ||
6712 | module_param(rmac_pause_time, int, 0); | ||
6713 | module_param(mc_pause_threshold_q0q3, int, 0); | ||
6714 | module_param(mc_pause_threshold_q4q7, int, 0); | ||
6715 | module_param(shared_splits, int, 0); | ||
6716 | module_param(tmac_util_period, int, 0); | ||
6717 | module_param(rmac_util_period, int, 0); | ||
6718 | module_param(bimodal, bool, 0); | ||
6719 | module_param(l3l4hdr_size, int , 0); | ||
6720 | #ifndef CONFIG_S2IO_NAPI | ||
6721 | module_param(indicate_max_pkts, int, 0); | ||
6722 | #endif | ||
6723 | module_param(rxsync_frequency, int, 0); | ||
6724 | module_param(intr_type, int, 0); | ||
6725 | module_param(lro, int, 0); | ||
6726 | module_param(lro_max_pkts, int, 0); | ||
6727 | |||
6728 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | 6682 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) |
6729 | { | 6683 | { |
6730 | if ( tx_fifo_num > 8) { | 6684 | if ( tx_fifo_num > 8) { |
@@ -6832,8 +6786,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6832 | } | 6786 | } |
6833 | if (dev_intr_type != MSI_X) { | 6787 | if (dev_intr_type != MSI_X) { |
6834 | if (pci_request_regions(pdev, s2io_driver_name)) { | 6788 | if (pci_request_regions(pdev, s2io_driver_name)) { |
6835 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | 6789 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"); |
6836 | pci_disable_device(pdev); | 6790 | pci_disable_device(pdev); |
6837 | return -ENODEV; | 6791 | return -ENODEV; |
6838 | } | 6792 | } |
6839 | } | 6793 | } |
@@ -6957,7 +6911,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6957 | /* initialize the shared memory used by the NIC and the host */ | 6911 | /* initialize the shared memory used by the NIC and the host */ |
6958 | if (init_shared_mem(sp)) { | 6912 | if (init_shared_mem(sp)) { |
6959 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 6913 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
6960 | __FUNCTION__); | 6914 | dev->name); |
6961 | ret = -ENOMEM; | 6915 | ret = -ENOMEM; |
6962 | goto mem_alloc_failed; | 6916 | goto mem_alloc_failed; |
6963 | } | 6917 | } |
@@ -7094,6 +7048,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7094 | dev->addr_len = ETH_ALEN; | 7048 | dev->addr_len = ETH_ALEN; |
7095 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 7049 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
7096 | 7050 | ||
7051 | /* reset Nic and bring it to known state */ | ||
7052 | s2io_reset(sp); | ||
7053 | |||
7097 | /* | 7054 | /* |
7098 | * Initialize the tasklet status and link state flags | 7055 | * Initialize the tasklet status and link state flags |
7099 | * and the card state parameter | 7056 | * and the card state parameter |
@@ -7131,11 +7088,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7131 | goto register_failed; | 7088 | goto register_failed; |
7132 | } | 7089 | } |
7133 | s2io_vpd_read(sp); | 7090 | s2io_vpd_read(sp); |
7134 | DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); | ||
7135 | DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", | ||
7136 | get_xena_rev_id(sp->pdev), | ||
7137 | s2io_driver_version); | ||
7138 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); | 7091 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); |
7092 | DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, | ||
7093 | sp->product_name, get_xena_rev_id(sp->pdev)); | ||
7094 | DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, | ||
7095 | s2io_driver_version); | ||
7139 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " | 7096 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " |
7140 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | 7097 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, |
7141 | sp->def_mac_addr[0].mac_addr[0], | 7098 | sp->def_mac_addr[0].mac_addr[0], |
@@ -7436,8 +7393,13 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7436 | if (ip->ihl != 5) /* IP has options */ | 7393 | if (ip->ihl != 5) /* IP has options */ |
7437 | return -1; | 7394 | return -1; |
7438 | 7395 | ||
7396 | /* If we see CE codepoint in IP header, packet is not mergeable */ | ||
7397 | if (INET_ECN_is_ce(ipv4_get_dsfield(ip))) | ||
7398 | return -1; | ||
7399 | |||
7400 | /* If we see ECE or CWR flags in TCP header, packet is not mergeable */ | ||
7439 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || | 7401 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || |
7440 | !tcp->ack) { | 7402 | tcp->ece || tcp->cwr || !tcp->ack) { |
7441 | /* | 7403 | /* |
7442 | * Currently recognize only the ack control word and | 7404 | * Currently recognize only the ack control word and |
7443 | * any other control field being set would result in | 7405 | * any other control field being set would result in |
@@ -7591,18 +7553,16 @@ static void queue_rx_frame(struct sk_buff *skb) | |||
7591 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, | 7553 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, |
7592 | u32 tcp_len) | 7554 | u32 tcp_len) |
7593 | { | 7555 | { |
7594 | struct sk_buff *tmp, *first = lro->parent; | 7556 | struct sk_buff *first = lro->parent; |
7595 | 7557 | ||
7596 | first->len += tcp_len; | 7558 | first->len += tcp_len; |
7597 | first->data_len = lro->frags_len; | 7559 | first->data_len = lro->frags_len; |
7598 | skb_pull(skb, (skb->len - tcp_len)); | 7560 | skb_pull(skb, (skb->len - tcp_len)); |
7599 | if ((tmp = skb_shinfo(first)->frag_list)) { | 7561 | if (skb_shinfo(first)->frag_list) |
7600 | while (tmp->next) | 7562 | lro->last_frag->next = skb; |
7601 | tmp = tmp->next; | ||
7602 | tmp->next = skb; | ||
7603 | } | ||
7604 | else | 7563 | else |
7605 | skb_shinfo(first)->frag_list = skb; | 7564 | skb_shinfo(first)->frag_list = skb; |
7565 | lro->last_frag = skb; | ||
7606 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; | 7566 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; |
7607 | return; | 7567 | return; |
7608 | } | 7568 | } |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 217097bc22f1..5ed49c3be1e9 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -719,6 +719,7 @@ struct msix_info_st { | |||
719 | /* Data structure to represent a LRO session */ | 719 | /* Data structure to represent a LRO session */ |
720 | typedef struct lro { | 720 | typedef struct lro { |
721 | struct sk_buff *parent; | 721 | struct sk_buff *parent; |
722 | struct sk_buff *last_frag; | ||
722 | u8 *l2h; | 723 | u8 *l2h; |
723 | struct iphdr *iph; | 724 | struct iphdr *iph; |
724 | struct tcphdr *tcph; | 725 | struct tcphdr *tcph; |
@@ -1011,4 +1012,13 @@ static void clear_lro_session(lro_t *lro); | |||
1011 | static void queue_rx_frame(struct sk_buff *skb); | 1012 | static void queue_rx_frame(struct sk_buff *skb); |
1012 | static void update_L3L4_header(nic_t *sp, lro_t *lro); | 1013 | static void update_L3L4_header(nic_t *sp, lro_t *lro); |
1013 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len); | 1014 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len); |
1015 | |||
1016 | #define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size | ||
1017 | #define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size | ||
1018 | #define s2io_offload_type(skb) skb_shinfo(skb)->gso_type | ||
1019 | |||
1020 | #define S2IO_PARM_INT(X, def_val) \ | ||
1021 | static unsigned int X = def_val;\ | ||
1022 | module_param(X , uint, 0); | ||
1023 | |||
1014 | #endif /* _S2IO_H */ | 1024 | #endif /* _S2IO_H */ |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 82200bfaa8ed..7de9a07b2ac2 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -516,10 +516,7 @@ static int skge_set_pauseparam(struct net_device *dev, | |||
516 | /* Chip internal frequency for clock calculations */ | 516 | /* Chip internal frequency for clock calculations */ |
517 | static inline u32 hwkhz(const struct skge_hw *hw) | 517 | static inline u32 hwkhz(const struct skge_hw *hw) |
518 | { | 518 | { |
519 | if (hw->chip_id == CHIP_ID_GENESIS) | 519 | return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125; |
520 | return 53215; /* or: 53.125 MHz */ | ||
521 | else | ||
522 | return 78215; /* or: 78.125 MHz */ | ||
523 | } | 520 | } |
524 | 521 | ||
525 | /* Chip HZ to microseconds */ | 522 | /* Chip HZ to microseconds */ |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d98f28c34e5c..de91609ca112 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sky2.h" | 50 | #include "sky2.h" |
51 | 51 | ||
52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.4" | 53 | #define DRV_VERSION "1.5" |
54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -2204,9 +2204,6 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2204 | int work_done = 0; | 2204 | int work_done = 0; |
2205 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2205 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2206 | 2206 | ||
2207 | if (!~status) | ||
2208 | goto out; | ||
2209 | |||
2210 | if (status & Y2_IS_HW_ERR) | 2207 | if (status & Y2_IS_HW_ERR) |
2211 | sky2_hw_intr(hw); | 2208 | sky2_hw_intr(hw); |
2212 | 2209 | ||
@@ -2243,7 +2240,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2243 | 2240 | ||
2244 | if (sky2_more_work(hw)) | 2241 | if (sky2_more_work(hw)) |
2245 | return 1; | 2242 | return 1; |
2246 | out: | 2243 | |
2247 | netif_rx_complete(dev0); | 2244 | netif_rx_complete(dev0); |
2248 | 2245 | ||
2249 | sky2_read32(hw, B0_Y2_SP_LISR); | 2246 | sky2_read32(hw, B0_Y2_SP_LISR); |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index fb1d5a8a45cf..647f62e9707d 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); | |||
84 | * | 84 | * |
85 | * returns the content of the specified SMMIO register. | 85 | * returns the content of the specified SMMIO register. |
86 | */ | 86 | */ |
87 | static u32 | 87 | static inline u32 |
88 | spider_net_read_reg(struct spider_net_card *card, u32 reg) | 88 | spider_net_read_reg(struct spider_net_card *card, u32 reg) |
89 | { | 89 | { |
90 | u32 value; | 90 | u32 value; |
@@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg) | |||
101 | * @reg: register to write to | 101 | * @reg: register to write to |
102 | * @value: value to write into the specified SMMIO register | 102 | * @value: value to write into the specified SMMIO register |
103 | */ | 103 | */ |
104 | static void | 104 | static inline void |
105 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) | 105 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) |
106 | { | 106 | { |
107 | value = cpu_to_le32(value); | 107 | value = cpu_to_le32(value); |
@@ -259,39 +259,10 @@ spider_net_get_mac_address(struct net_device *netdev) | |||
259 | * | 259 | * |
260 | * returns the status as in the dmac_cmd_status field of the descriptor | 260 | * returns the status as in the dmac_cmd_status field of the descriptor |
261 | */ | 261 | */ |
262 | static enum spider_net_descr_status | 262 | static inline int |
263 | spider_net_get_descr_status(struct spider_net_descr *descr) | 263 | spider_net_get_descr_status(struct spider_net_descr *descr) |
264 | { | 264 | { |
265 | u32 cmd_status; | 265 | return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; |
266 | |||
267 | cmd_status = descr->dmac_cmd_status; | ||
268 | cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT; | ||
269 | /* no need to mask out any bits, as cmd_status is 32 bits wide only | ||
270 | * (and unsigned) */ | ||
271 | return cmd_status; | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * spider_net_set_descr_status -- sets the status of a descriptor | ||
276 | * @descr: descriptor to change | ||
277 | * @status: status to set in the descriptor | ||
278 | * | ||
279 | * changes the status to the specified value. Doesn't change other bits | ||
280 | * in the status | ||
281 | */ | ||
282 | static void | ||
283 | spider_net_set_descr_status(struct spider_net_descr *descr, | ||
284 | enum spider_net_descr_status status) | ||
285 | { | ||
286 | u32 cmd_status; | ||
287 | /* read the status */ | ||
288 | cmd_status = descr->dmac_cmd_status; | ||
289 | /* clean the upper 4 bits */ | ||
290 | cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO; | ||
291 | /* add the status to it */ | ||
292 | cmd_status |= ((u32)status)<<SPIDER_NET_DESCR_IND_PROC_SHIFT; | ||
293 | /* and write it back */ | ||
294 | descr->dmac_cmd_status = cmd_status; | ||
295 | } | 266 | } |
296 | 267 | ||
297 | /** | 268 | /** |
@@ -328,24 +299,23 @@ spider_net_free_chain(struct spider_net_card *card, | |||
328 | static int | 299 | static int |
329 | spider_net_init_chain(struct spider_net_card *card, | 300 | spider_net_init_chain(struct spider_net_card *card, |
330 | struct spider_net_descr_chain *chain, | 301 | struct spider_net_descr_chain *chain, |
331 | struct spider_net_descr *start_descr, int no) | 302 | struct spider_net_descr *start_descr, |
303 | int direction, int no) | ||
332 | { | 304 | { |
333 | int i; | 305 | int i; |
334 | struct spider_net_descr *descr; | 306 | struct spider_net_descr *descr; |
335 | dma_addr_t buf; | 307 | dma_addr_t buf; |
336 | 308 | ||
337 | atomic_set(&card->rx_chain_refill,0); | ||
338 | |||
339 | descr = start_descr; | 309 | descr = start_descr; |
340 | memset(descr, 0, sizeof(*descr) * no); | 310 | memset(descr, 0, sizeof(*descr) * no); |
341 | 311 | ||
342 | /* set up the hardware pointers in each descriptor */ | 312 | /* set up the hardware pointers in each descriptor */ |
343 | for (i=0; i<no; i++, descr++) { | 313 | for (i=0; i<no; i++, descr++) { |
344 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | 314 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
345 | 315 | ||
346 | buf = pci_map_single(card->pdev, descr, | 316 | buf = pci_map_single(card->pdev, descr, |
347 | SPIDER_NET_DESCR_SIZE, | 317 | SPIDER_NET_DESCR_SIZE, |
348 | PCI_DMA_BIDIRECTIONAL); | 318 | direction); |
349 | 319 | ||
350 | if (buf == DMA_ERROR_CODE) | 320 | if (buf == DMA_ERROR_CODE) |
351 | goto iommu_error; | 321 | goto iommu_error; |
@@ -360,10 +330,11 @@ spider_net_init_chain(struct spider_net_card *card, | |||
360 | start_descr->prev = descr-1; | 330 | start_descr->prev = descr-1; |
361 | 331 | ||
362 | descr = start_descr; | 332 | descr = start_descr; |
363 | for (i=0; i < no; i++, descr++) { | 333 | if (direction == PCI_DMA_FROMDEVICE) |
364 | descr->next_descr_addr = descr->next->bus_addr; | 334 | for (i=0; i < no; i++, descr++) |
365 | } | 335 | descr->next_descr_addr = descr->next->bus_addr; |
366 | 336 | ||
337 | spin_lock_init(&chain->lock); | ||
367 | chain->head = start_descr; | 338 | chain->head = start_descr; |
368 | chain->tail = start_descr; | 339 | chain->tail = start_descr; |
369 | 340 | ||
@@ -375,7 +346,7 @@ iommu_error: | |||
375 | if (descr->bus_addr) | 346 | if (descr->bus_addr) |
376 | pci_unmap_single(card->pdev, descr->bus_addr, | 347 | pci_unmap_single(card->pdev, descr->bus_addr, |
377 | SPIDER_NET_DESCR_SIZE, | 348 | SPIDER_NET_DESCR_SIZE, |
378 | PCI_DMA_BIDIRECTIONAL); | 349 | direction); |
379 | return -ENOMEM; | 350 | return -ENOMEM; |
380 | } | 351 | } |
381 | 352 | ||
@@ -396,7 +367,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
396 | dev_kfree_skb(descr->skb); | 367 | dev_kfree_skb(descr->skb); |
397 | pci_unmap_single(card->pdev, descr->buf_addr, | 368 | pci_unmap_single(card->pdev, descr->buf_addr, |
398 | SPIDER_NET_MAX_FRAME, | 369 | SPIDER_NET_MAX_FRAME, |
399 | PCI_DMA_BIDIRECTIONAL); | 370 | PCI_DMA_FROMDEVICE); |
400 | } | 371 | } |
401 | descr = descr->next; | 372 | descr = descr->next; |
402 | } | 373 | } |
@@ -446,15 +417,16 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
446 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); | 417 | skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); |
447 | /* io-mmu-map the skb */ | 418 | /* io-mmu-map the skb */ |
448 | buf = pci_map_single(card->pdev, descr->skb->data, | 419 | buf = pci_map_single(card->pdev, descr->skb->data, |
449 | SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); | 420 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
450 | descr->buf_addr = buf; | 421 | descr->buf_addr = buf; |
451 | if (buf == DMA_ERROR_CODE) { | 422 | if (buf == DMA_ERROR_CODE) { |
452 | dev_kfree_skb_any(descr->skb); | 423 | dev_kfree_skb_any(descr->skb); |
453 | if (netif_msg_rx_err(card) && net_ratelimit()) | 424 | if (netif_msg_rx_err(card) && net_ratelimit()) |
454 | pr_err("Could not iommu-map rx buffer\n"); | 425 | pr_err("Could not iommu-map rx buffer\n"); |
455 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | 426 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
456 | } else { | 427 | } else { |
457 | descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED; | 428 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
429 | SPIDER_NET_DMAC_NOINTR_COMPLETE; | ||
458 | } | 430 | } |
459 | 431 | ||
460 | return error; | 432 | return error; |
@@ -468,7 +440,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
468 | * chip by writing to the appropriate register. DMA is enabled in | 440 | * chip by writing to the appropriate register. DMA is enabled in |
469 | * spider_net_enable_rxdmac. | 441 | * spider_net_enable_rxdmac. |
470 | */ | 442 | */ |
471 | static void | 443 | static inline void |
472 | spider_net_enable_rxchtails(struct spider_net_card *card) | 444 | spider_net_enable_rxchtails(struct spider_net_card *card) |
473 | { | 445 | { |
474 | /* assume chain is aligned correctly */ | 446 | /* assume chain is aligned correctly */ |
@@ -483,7 +455,7 @@ spider_net_enable_rxchtails(struct spider_net_card *card) | |||
483 | * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN | 455 | * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN |
484 | * in the GDADMACCNTR register | 456 | * in the GDADMACCNTR register |
485 | */ | 457 | */ |
486 | static void | 458 | static inline void |
487 | spider_net_enable_rxdmac(struct spider_net_card *card) | 459 | spider_net_enable_rxdmac(struct spider_net_card *card) |
488 | { | 460 | { |
489 | wmb(); | 461 | wmb(); |
@@ -500,23 +472,24 @@ spider_net_enable_rxdmac(struct spider_net_card *card) | |||
500 | static void | 472 | static void |
501 | spider_net_refill_rx_chain(struct spider_net_card *card) | 473 | spider_net_refill_rx_chain(struct spider_net_card *card) |
502 | { | 474 | { |
503 | struct spider_net_descr_chain *chain; | 475 | struct spider_net_descr_chain *chain = &card->rx_chain; |
504 | 476 | unsigned long flags; | |
505 | chain = &card->rx_chain; | ||
506 | 477 | ||
507 | /* one context doing the refill (and a second context seeing that | 478 | /* one context doing the refill (and a second context seeing that |
508 | * and omitting it) is ok. If called by NAPI, we'll be called again | 479 | * and omitting it) is ok. If called by NAPI, we'll be called again |
509 | * as spider_net_decode_one_descr is called several times. If some | 480 | * as spider_net_decode_one_descr is called several times. If some |
510 | * interrupt calls us, the NAPI is about to clean up anyway. */ | 481 | * interrupt calls us, the NAPI is about to clean up anyway. */ |
511 | if (atomic_inc_return(&card->rx_chain_refill) == 1) | 482 | if (!spin_trylock_irqsave(&chain->lock, flags)) |
512 | while (spider_net_get_descr_status(chain->head) == | 483 | return; |
513 | SPIDER_NET_DESCR_NOT_IN_USE) { | 484 | |
514 | if (spider_net_prepare_rx_descr(card, chain->head)) | 485 | while (spider_net_get_descr_status(chain->head) == |
515 | break; | 486 | SPIDER_NET_DESCR_NOT_IN_USE) { |
516 | chain->head = chain->head->next; | 487 | if (spider_net_prepare_rx_descr(card, chain->head)) |
517 | } | 488 | break; |
489 | chain->head = chain->head->next; | ||
490 | } | ||
518 | 491 | ||
519 | atomic_dec(&card->rx_chain_refill); | 492 | spin_unlock_irqrestore(&chain->lock, flags); |
520 | } | 493 | } |
521 | 494 | ||
522 | /** | 495 | /** |
@@ -554,111 +527,6 @@ error: | |||
554 | } | 527 | } |
555 | 528 | ||
556 | /** | 529 | /** |
557 | * spider_net_release_tx_descr - processes a used tx descriptor | ||
558 | * @card: card structure | ||
559 | * @descr: descriptor to release | ||
560 | * | ||
561 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
562 | */ | ||
563 | static void | ||
564 | spider_net_release_tx_descr(struct spider_net_card *card, | ||
565 | struct spider_net_descr *descr) | ||
566 | { | ||
567 | struct sk_buff *skb; | ||
568 | |||
569 | /* unmap the skb */ | ||
570 | skb = descr->skb; | ||
571 | pci_unmap_single(card->pdev, descr->buf_addr, skb->len, | ||
572 | PCI_DMA_BIDIRECTIONAL); | ||
573 | |||
574 | dev_kfree_skb_any(skb); | ||
575 | |||
576 | /* set status to not used */ | ||
577 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * spider_net_release_tx_chain - processes sent tx descriptors | ||
582 | * @card: adapter structure | ||
583 | * @brutal: if set, don't care about whether descriptor seems to be in use | ||
584 | * | ||
585 | * returns 0 if the tx ring is empty, otherwise 1. | ||
586 | * | ||
587 | * spider_net_release_tx_chain releases the tx descriptors that spider has | ||
588 | * finished with (if non-brutal) or simply release tx descriptors (if brutal). | ||
589 | * If some other context is calling this function, we return 1 so that we're | ||
590 | * scheduled again (if we were scheduled) and will not loose initiative. | ||
591 | */ | ||
592 | static int | ||
593 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | ||
594 | { | ||
595 | struct spider_net_descr_chain *tx_chain = &card->tx_chain; | ||
596 | enum spider_net_descr_status status; | ||
597 | |||
598 | if (atomic_inc_return(&card->tx_chain_release) != 1) { | ||
599 | atomic_dec(&card->tx_chain_release); | ||
600 | return 1; | ||
601 | } | ||
602 | |||
603 | for (;;) { | ||
604 | status = spider_net_get_descr_status(tx_chain->tail); | ||
605 | switch (status) { | ||
606 | case SPIDER_NET_DESCR_CARDOWNED: | ||
607 | if (!brutal) | ||
608 | goto out; | ||
609 | /* fallthrough, if we release the descriptors | ||
610 | * brutally (then we don't care about | ||
611 | * SPIDER_NET_DESCR_CARDOWNED) */ | ||
612 | case SPIDER_NET_DESCR_RESPONSE_ERROR: | ||
613 | case SPIDER_NET_DESCR_PROTECTION_ERROR: | ||
614 | case SPIDER_NET_DESCR_FORCE_END: | ||
615 | if (netif_msg_tx_err(card)) | ||
616 | pr_err("%s: forcing end of tx descriptor " | ||
617 | "with status x%02x\n", | ||
618 | card->netdev->name, status); | ||
619 | card->netdev_stats.tx_dropped++; | ||
620 | break; | ||
621 | |||
622 | case SPIDER_NET_DESCR_COMPLETE: | ||
623 | card->netdev_stats.tx_packets++; | ||
624 | card->netdev_stats.tx_bytes += | ||
625 | tx_chain->tail->skb->len; | ||
626 | break; | ||
627 | |||
628 | default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */ | ||
629 | goto out; | ||
630 | } | ||
631 | spider_net_release_tx_descr(card, tx_chain->tail); | ||
632 | tx_chain->tail = tx_chain->tail->next; | ||
633 | } | ||
634 | out: | ||
635 | atomic_dec(&card->tx_chain_release); | ||
636 | |||
637 | netif_wake_queue(card->netdev); | ||
638 | |||
639 | if (status == SPIDER_NET_DESCR_CARDOWNED) | ||
640 | return 1; | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | /** | ||
645 | * spider_net_cleanup_tx_ring - cleans up the TX ring | ||
646 | * @card: card structure | ||
647 | * | ||
648 | * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use | ||
649 | * interrupts to cleanup our TX ring) and returns sent packets to the stack | ||
650 | * by freeing them | ||
651 | */ | ||
652 | static void | ||
653 | spider_net_cleanup_tx_ring(struct spider_net_card *card) | ||
654 | { | ||
655 | if ( (spider_net_release_tx_chain(card, 0)) && | ||
656 | (card->netdev->flags & IFF_UP) ) { | ||
657 | mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /** | ||
662 | * spider_net_get_multicast_hash - generates hash for multicast filter table | 530 | * spider_net_get_multicast_hash - generates hash for multicast filter table |
663 | * @addr: multicast address | 531 | * @addr: multicast address |
664 | * | 532 | * |
@@ -761,97 +629,6 @@ spider_net_disable_rxdmac(struct spider_net_card *card) | |||
761 | } | 629 | } |
762 | 630 | ||
763 | /** | 631 | /** |
764 | * spider_net_stop - called upon ifconfig down | ||
765 | * @netdev: interface device structure | ||
766 | * | ||
767 | * always returns 0 | ||
768 | */ | ||
769 | int | ||
770 | spider_net_stop(struct net_device *netdev) | ||
771 | { | ||
772 | struct spider_net_card *card = netdev_priv(netdev); | ||
773 | |||
774 | tasklet_kill(&card->rxram_full_tl); | ||
775 | netif_poll_disable(netdev); | ||
776 | netif_carrier_off(netdev); | ||
777 | netif_stop_queue(netdev); | ||
778 | del_timer_sync(&card->tx_timer); | ||
779 | |||
780 | /* disable/mask all interrupts */ | ||
781 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); | ||
782 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); | ||
783 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); | ||
784 | |||
785 | /* free_irq(netdev->irq, netdev);*/ | ||
786 | free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); | ||
787 | |||
788 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
789 | SPIDER_NET_DMA_TX_FEND_VALUE); | ||
790 | |||
791 | /* turn off DMA, force end */ | ||
792 | spider_net_disable_rxdmac(card); | ||
793 | |||
794 | /* release chains */ | ||
795 | spider_net_release_tx_chain(card, 1); | ||
796 | |||
797 | spider_net_free_chain(card, &card->tx_chain); | ||
798 | spider_net_free_chain(card, &card->rx_chain); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * spider_net_get_next_tx_descr - returns the next available tx descriptor | ||
805 | * @card: device structure to get descriptor from | ||
806 | * | ||
807 | * returns the address of the next descriptor, or NULL if not available. | ||
808 | */ | ||
809 | static struct spider_net_descr * | ||
810 | spider_net_get_next_tx_descr(struct spider_net_card *card) | ||
811 | { | ||
812 | /* check, if head points to not-in-use descr */ | ||
813 | if ( spider_net_get_descr_status(card->tx_chain.head) == | ||
814 | SPIDER_NET_DESCR_NOT_IN_USE ) { | ||
815 | return card->tx_chain.head; | ||
816 | } else { | ||
817 | return NULL; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | /** | ||
822 | * spider_net_set_txdescr_cmdstat - sets the tx descriptor command field | ||
823 | * @descr: descriptor structure to fill out | ||
824 | * @skb: packet to consider | ||
825 | * | ||
826 | * fills out the command and status field of the descriptor structure, | ||
827 | * depending on hardware checksum settings. | ||
828 | */ | ||
829 | static void | ||
830 | spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, | ||
831 | struct sk_buff *skb) | ||
832 | { | ||
833 | /* make sure the other fields in the descriptor are written */ | ||
834 | wmb(); | ||
835 | |||
836 | if (skb->ip_summed != CHECKSUM_HW) { | ||
837 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; | ||
838 | return; | ||
839 | } | ||
840 | |||
841 | /* is packet ip? | ||
842 | * if yes: tcp? udp? */ | ||
843 | if (skb->protocol == htons(ETH_P_IP)) { | ||
844 | if (skb->nh.iph->protocol == IPPROTO_TCP) | ||
845 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS; | ||
846 | else if (skb->nh.iph->protocol == IPPROTO_UDP) | ||
847 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS; | ||
848 | else /* the stack should checksum non-tcp and non-udp | ||
849 | packets on his own: NETIF_F_IP_CSUM */ | ||
850 | descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; | ||
851 | } | ||
852 | } | ||
853 | |||
854 | /** | ||
855 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data | 632 | * spider_net_prepare_tx_descr - fill tx descriptor with skb data |
856 | * @card: card structure | 633 | * @card: card structure |
857 | * @descr: descriptor structure to fill out | 634 | * @descr: descriptor structure to fill out |
@@ -864,13 +641,12 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, | |||
864 | */ | 641 | */ |
865 | static int | 642 | static int |
866 | spider_net_prepare_tx_descr(struct spider_net_card *card, | 643 | spider_net_prepare_tx_descr(struct spider_net_card *card, |
867 | struct spider_net_descr *descr, | ||
868 | struct sk_buff *skb) | 644 | struct sk_buff *skb) |
869 | { | 645 | { |
646 | struct spider_net_descr *descr = card->tx_chain.head; | ||
870 | dma_addr_t buf; | 647 | dma_addr_t buf; |
871 | 648 | ||
872 | buf = pci_map_single(card->pdev, skb->data, | 649 | buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); |
873 | skb->len, PCI_DMA_BIDIRECTIONAL); | ||
874 | if (buf == DMA_ERROR_CODE) { | 650 | if (buf == DMA_ERROR_CODE) { |
875 | if (netif_msg_tx_err(card) && net_ratelimit()) | 651 | if (netif_msg_tx_err(card) && net_ratelimit()) |
876 | pr_err("could not iommu-map packet (%p, %i). " | 652 | pr_err("could not iommu-map packet (%p, %i). " |
@@ -880,10 +656,101 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
880 | 656 | ||
881 | descr->buf_addr = buf; | 657 | descr->buf_addr = buf; |
882 | descr->buf_size = skb->len; | 658 | descr->buf_size = skb->len; |
659 | descr->next_descr_addr = 0; | ||
883 | descr->skb = skb; | 660 | descr->skb = skb; |
884 | descr->data_status = 0; | 661 | descr->data_status = 0; |
885 | 662 | ||
886 | spider_net_set_txdescr_cmdstat(descr,skb); | 663 | descr->dmac_cmd_status = |
664 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | ||
665 | if (skb->protocol == htons(ETH_P_IP)) | ||
666 | switch (skb->nh.iph->protocol) { | ||
667 | case IPPROTO_TCP: | ||
668 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; | ||
669 | break; | ||
670 | case IPPROTO_UDP: | ||
671 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; | ||
672 | break; | ||
673 | } | ||
674 | |||
675 | descr->prev->next_descr_addr = descr->bus_addr; | ||
676 | |||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | /** | ||
681 | * spider_net_release_tx_descr - processes a used tx descriptor | ||
682 | * @card: card structure | ||
683 | * @descr: descriptor to release | ||
684 | * | ||
685 | * releases a used tx descriptor (unmapping, freeing of skb) | ||
686 | */ | ||
687 | static inline void | ||
688 | spider_net_release_tx_descr(struct spider_net_card *card) | ||
689 | { | ||
690 | struct spider_net_descr *descr = card->tx_chain.tail; | ||
691 | struct sk_buff *skb; | ||
692 | |||
693 | card->tx_chain.tail = card->tx_chain.tail->next; | ||
694 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | ||
695 | |||
696 | /* unmap the skb */ | ||
697 | skb = descr->skb; | ||
698 | pci_unmap_single(card->pdev, descr->buf_addr, skb->len, | ||
699 | PCI_DMA_TODEVICE); | ||
700 | dev_kfree_skb_any(skb); | ||
701 | } | ||
702 | |||
703 | /** | ||
704 | * spider_net_release_tx_chain - processes sent tx descriptors | ||
705 | * @card: adapter structure | ||
706 | * @brutal: if set, don't care about whether descriptor seems to be in use | ||
707 | * | ||
708 | * returns 0 if the tx ring is empty, otherwise 1. | ||
709 | * | ||
710 | * spider_net_release_tx_chain releases the tx descriptors that spider has | ||
711 | * finished with (if non-brutal) or simply release tx descriptors (if brutal). | ||
712 | * If some other context is calling this function, we return 1 so that we're | ||
713 | * scheduled again (if we were scheduled) and will not loose initiative. | ||
714 | */ | ||
715 | static int | ||
716 | spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | ||
717 | { | ||
718 | struct spider_net_descr_chain *chain = &card->tx_chain; | ||
719 | int status; | ||
720 | |||
721 | spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); | ||
722 | |||
723 | while (chain->tail != chain->head) { | ||
724 | status = spider_net_get_descr_status(chain->tail); | ||
725 | switch (status) { | ||
726 | case SPIDER_NET_DESCR_COMPLETE: | ||
727 | card->netdev_stats.tx_packets++; | ||
728 | card->netdev_stats.tx_bytes += chain->tail->skb->len; | ||
729 | break; | ||
730 | |||
731 | case SPIDER_NET_DESCR_CARDOWNED: | ||
732 | if (!brutal) | ||
733 | return 1; | ||
734 | /* fallthrough, if we release the descriptors | ||
735 | * brutally (then we don't care about | ||
736 | * SPIDER_NET_DESCR_CARDOWNED) */ | ||
737 | |||
738 | case SPIDER_NET_DESCR_RESPONSE_ERROR: | ||
739 | case SPIDER_NET_DESCR_PROTECTION_ERROR: | ||
740 | case SPIDER_NET_DESCR_FORCE_END: | ||
741 | if (netif_msg_tx_err(card)) | ||
742 | pr_err("%s: forcing end of tx descriptor " | ||
743 | "with status x%02x\n", | ||
744 | card->netdev->name, status); | ||
745 | card->netdev_stats.tx_errors++; | ||
746 | break; | ||
747 | |||
748 | default: | ||
749 | card->netdev_stats.tx_dropped++; | ||
750 | return 1; | ||
751 | } | ||
752 | spider_net_release_tx_descr(card); | ||
753 | } | ||
887 | 754 | ||
888 | return 0; | 755 | return 0; |
889 | } | 756 | } |
@@ -896,18 +763,32 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
896 | * spider_net_kick_tx_dma writes the current tx chain head as start address | 763 | * spider_net_kick_tx_dma writes the current tx chain head as start address |
897 | * of the tx descriptor chain and enables the transmission DMA engine | 764 | * of the tx descriptor chain and enables the transmission DMA engine |
898 | */ | 765 | */ |
899 | static void | 766 | static inline void |
900 | spider_net_kick_tx_dma(struct spider_net_card *card, | 767 | spider_net_kick_tx_dma(struct spider_net_card *card) |
901 | struct spider_net_descr *descr) | ||
902 | { | 768 | { |
903 | /* this is the only descriptor in the output chain. | 769 | struct spider_net_descr *descr; |
904 | * Enable TX DMA */ | ||
905 | 770 | ||
906 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | 771 | if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) & |
907 | descr->bus_addr); | 772 | SPIDER_NET_TX_DMA_EN) |
773 | goto out; | ||
908 | 774 | ||
909 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 775 | descr = card->tx_chain.tail; |
910 | SPIDER_NET_DMA_TX_VALUE); | 776 | for (;;) { |
777 | if (spider_net_get_descr_status(descr) == | ||
778 | SPIDER_NET_DESCR_CARDOWNED) { | ||
779 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | ||
780 | descr->bus_addr); | ||
781 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
782 | SPIDER_NET_DMA_TX_VALUE); | ||
783 | break; | ||
784 | } | ||
785 | if (descr == card->tx_chain.head) | ||
786 | break; | ||
787 | descr = descr->next; | ||
788 | } | ||
789 | |||
790 | out: | ||
791 | mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); | ||
911 | } | 792 | } |
912 | 793 | ||
913 | /** | 794 | /** |
@@ -915,47 +796,69 @@ spider_net_kick_tx_dma(struct spider_net_card *card, | |||
915 | * @skb: packet to send out | 796 | * @skb: packet to send out |
916 | * @netdev: interface device structure | 797 | * @netdev: interface device structure |
917 | * | 798 | * |
918 | * returns 0 on success, <0 on failure | 799 | * returns 0 on success, !0 on failure |
919 | */ | 800 | */ |
920 | static int | 801 | static int |
921 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | 802 | spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) |
922 | { | 803 | { |
923 | struct spider_net_card *card = netdev_priv(netdev); | 804 | struct spider_net_card *card = netdev_priv(netdev); |
924 | struct spider_net_descr *descr; | 805 | struct spider_net_descr_chain *chain = &card->tx_chain; |
806 | struct spider_net_descr *descr = chain->head; | ||
807 | unsigned long flags; | ||
925 | int result; | 808 | int result; |
926 | 809 | ||
810 | spin_lock_irqsave(&chain->lock, flags); | ||
811 | |||
927 | spider_net_release_tx_chain(card, 0); | 812 | spider_net_release_tx_chain(card, 0); |
928 | 813 | ||
929 | descr = spider_net_get_next_tx_descr(card); | 814 | if (chain->head->next == chain->tail->prev) { |
815 | card->netdev_stats.tx_dropped++; | ||
816 | result = NETDEV_TX_LOCKED; | ||
817 | goto out; | ||
818 | } | ||
930 | 819 | ||
931 | if (!descr) | 820 | if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { |
932 | goto error; | 821 | result = NETDEV_TX_LOCKED; |
822 | goto out; | ||
823 | } | ||
933 | 824 | ||
934 | result = spider_net_prepare_tx_descr(card, descr, skb); | 825 | if (spider_net_prepare_tx_descr(card, skb) != 0) { |
935 | if (result) | 826 | card->netdev_stats.tx_dropped++; |
936 | goto error; | 827 | result = NETDEV_TX_BUSY; |
828 | goto out; | ||
829 | } | ||
830 | |||
831 | result = NETDEV_TX_OK; | ||
937 | 832 | ||
833 | spider_net_kick_tx_dma(card); | ||
938 | card->tx_chain.head = card->tx_chain.head->next; | 834 | card->tx_chain.head = card->tx_chain.head->next; |
939 | 835 | ||
940 | if (spider_net_get_descr_status(descr->prev) != | 836 | out: |
941 | SPIDER_NET_DESCR_CARDOWNED) { | 837 | spin_unlock_irqrestore(&chain->lock, flags); |
942 | /* make sure the current descriptor is in memory. Then | 838 | netif_wake_queue(netdev); |
943 | * kicking it on again makes sense, if the previous is not | 839 | return result; |
944 | * card-owned anymore. Check the previous descriptor twice | 840 | } |
945 | * to omit an mb() in heavy traffic cases */ | ||
946 | mb(); | ||
947 | if (spider_net_get_descr_status(descr->prev) != | ||
948 | SPIDER_NET_DESCR_CARDOWNED) | ||
949 | spider_net_kick_tx_dma(card, descr); | ||
950 | } | ||
951 | 841 | ||
952 | mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); | 842 | /** |
843 | * spider_net_cleanup_tx_ring - cleans up the TX ring | ||
844 | * @card: card structure | ||
845 | * | ||
846 | * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use | ||
847 | * interrupts to cleanup our TX ring) and returns sent packets to the stack | ||
848 | * by freeing them | ||
849 | */ | ||
850 | static void | ||
851 | spider_net_cleanup_tx_ring(struct spider_net_card *card) | ||
852 | { | ||
853 | unsigned long flags; | ||
953 | 854 | ||
954 | return NETDEV_TX_OK; | 855 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
955 | 856 | ||
956 | error: | 857 | if ((spider_net_release_tx_chain(card, 0) != 0) && |
957 | card->netdev_stats.tx_dropped++; | 858 | (card->netdev->flags & IFF_UP)) |
958 | return NETDEV_TX_BUSY; | 859 | spider_net_kick_tx_dma(card); |
860 | |||
861 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | ||
959 | } | 862 | } |
960 | 863 | ||
961 | /** | 864 | /** |
@@ -1002,7 +905,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
1002 | 905 | ||
1003 | /* unmap descriptor */ | 906 | /* unmap descriptor */ |
1004 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, | 907 | pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, |
1005 | PCI_DMA_BIDIRECTIONAL); | 908 | PCI_DMA_FROMDEVICE); |
1006 | 909 | ||
1007 | /* the cases we'll throw away the packet immediately */ | 910 | /* the cases we'll throw away the packet immediately */ |
1008 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { | 911 | if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { |
@@ -1067,14 +970,11 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
1067 | static int | 970 | static int |
1068 | spider_net_decode_one_descr(struct spider_net_card *card, int napi) | 971 | spider_net_decode_one_descr(struct spider_net_card *card, int napi) |
1069 | { | 972 | { |
1070 | enum spider_net_descr_status status; | 973 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1071 | struct spider_net_descr *descr; | 974 | struct spider_net_descr *descr = chain->tail; |
1072 | struct spider_net_descr_chain *chain; | 975 | int status; |
1073 | int result; | 976 | int result; |
1074 | 977 | ||
1075 | chain = &card->rx_chain; | ||
1076 | descr = chain->tail; | ||
1077 | |||
1078 | status = spider_net_get_descr_status(descr); | 978 | status = spider_net_get_descr_status(descr); |
1079 | 979 | ||
1080 | if (status == SPIDER_NET_DESCR_CARDOWNED) { | 980 | if (status == SPIDER_NET_DESCR_CARDOWNED) { |
@@ -1103,7 +1003,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) | |||
1103 | card->netdev->name, status); | 1003 | card->netdev->name, status); |
1104 | card->netdev_stats.rx_dropped++; | 1004 | card->netdev_stats.rx_dropped++; |
1105 | pci_unmap_single(card->pdev, descr->buf_addr, | 1005 | pci_unmap_single(card->pdev, descr->buf_addr, |
1106 | SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); | 1006 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
1107 | dev_kfree_skb_irq(descr->skb); | 1007 | dev_kfree_skb_irq(descr->skb); |
1108 | goto refill; | 1008 | goto refill; |
1109 | } | 1009 | } |
@@ -1119,7 +1019,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) | |||
1119 | /* ok, we've got a packet in descr */ | 1019 | /* ok, we've got a packet in descr */ |
1120 | result = spider_net_pass_skb_up(descr, card, napi); | 1020 | result = spider_net_pass_skb_up(descr, card, napi); |
1121 | refill: | 1021 | refill: |
1122 | spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); | 1022 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1123 | /* change the descriptor state: */ | 1023 | /* change the descriptor state: */ |
1124 | if (!napi) | 1024 | if (!napi) |
1125 | spider_net_refill_rx_chain(card); | 1025 | spider_net_refill_rx_chain(card); |
@@ -1291,21 +1191,6 @@ spider_net_set_mac(struct net_device *netdev, void *p) | |||
1291 | } | 1191 | } |
1292 | 1192 | ||
1293 | /** | 1193 | /** |
1294 | * spider_net_enable_txdmac - enables a TX DMA controller | ||
1295 | * @card: card structure | ||
1296 | * | ||
1297 | * spider_net_enable_txdmac enables the TX DMA controller by setting the | ||
1298 | * descriptor chain tail address | ||
1299 | */ | ||
1300 | static void | ||
1301 | spider_net_enable_txdmac(struct spider_net_card *card) | ||
1302 | { | ||
1303 | /* assume chain is aligned correctly */ | ||
1304 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | ||
1305 | card->tx_chain.tail->bus_addr); | ||
1306 | } | ||
1307 | |||
1308 | /** | ||
1309 | * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt | 1194 | * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt |
1310 | * @card: card structure | 1195 | * @card: card structure |
1311 | * | 1196 | * |
@@ -1653,7 +1538,6 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1653 | { SPIDER_NET_GMRWOLCTRL, 0 }, | 1538 | { SPIDER_NET_GMRWOLCTRL, 0 }, |
1654 | { SPIDER_NET_GTESTMD, 0x10000000 }, | 1539 | { SPIDER_NET_GTESTMD, 0x10000000 }, |
1655 | { SPIDER_NET_GTTQMSK, 0x00400040 }, | 1540 | { SPIDER_NET_GTTQMSK, 0x00400040 }, |
1656 | { SPIDER_NET_GTESTMD, 0 }, | ||
1657 | 1541 | ||
1658 | { SPIDER_NET_GMACINTEN, 0 }, | 1542 | { SPIDER_NET_GMACINTEN, 0 }, |
1659 | 1543 | ||
@@ -1692,9 +1576,6 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1692 | 1576 | ||
1693 | spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); | 1577 | spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); |
1694 | 1578 | ||
1695 | /* set chain tail adress for TX chain */ | ||
1696 | spider_net_enable_txdmac(card); | ||
1697 | |||
1698 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, | 1579 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, |
1699 | SPIDER_NET_LENLMT_VALUE); | 1580 | SPIDER_NET_LENLMT_VALUE); |
1700 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, | 1581 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, |
@@ -1709,6 +1590,9 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1709 | SPIDER_NET_INT1_MASK_VALUE); | 1590 | SPIDER_NET_INT1_MASK_VALUE); |
1710 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, | 1591 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, |
1711 | SPIDER_NET_INT2_MASK_VALUE); | 1592 | SPIDER_NET_INT2_MASK_VALUE); |
1593 | |||
1594 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
1595 | SPIDER_NET_GDTDCEIDIS); | ||
1712 | } | 1596 | } |
1713 | 1597 | ||
1714 | /** | 1598 | /** |
@@ -1728,10 +1612,12 @@ spider_net_open(struct net_device *netdev) | |||
1728 | 1612 | ||
1729 | result = -ENOMEM; | 1613 | result = -ENOMEM; |
1730 | if (spider_net_init_chain(card, &card->tx_chain, | 1614 | if (spider_net_init_chain(card, &card->tx_chain, |
1731 | card->descr, tx_descriptors)) | 1615 | card->descr, |
1616 | PCI_DMA_TODEVICE, tx_descriptors)) | ||
1732 | goto alloc_tx_failed; | 1617 | goto alloc_tx_failed; |
1733 | if (spider_net_init_chain(card, &card->rx_chain, | 1618 | if (spider_net_init_chain(card, &card->rx_chain, |
1734 | card->descr + tx_descriptors, rx_descriptors)) | 1619 | card->descr + tx_descriptors, |
1620 | PCI_DMA_FROMDEVICE, rx_descriptors)) | ||
1735 | goto alloc_rx_failed; | 1621 | goto alloc_rx_failed; |
1736 | 1622 | ||
1737 | /* allocate rx skbs */ | 1623 | /* allocate rx skbs */ |
@@ -1938,7 +1824,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) | |||
1938 | /* empty sequencer data */ | 1824 | /* empty sequencer data */ |
1939 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; | 1825 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; |
1940 | sequencer++) { | 1826 | sequencer++) { |
1941 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | 1827 | spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + |
1942 | sequencer * 8, 0x0); | 1828 | sequencer * 8, 0x0); |
1943 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { | 1829 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { |
1944 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | 1830 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + |
@@ -1955,6 +1841,49 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) | |||
1955 | } | 1841 | } |
1956 | 1842 | ||
1957 | /** | 1843 | /** |
1844 | * spider_net_stop - called upon ifconfig down | ||
1845 | * @netdev: interface device structure | ||
1846 | * | ||
1847 | * always returns 0 | ||
1848 | */ | ||
1849 | int | ||
1850 | spider_net_stop(struct net_device *netdev) | ||
1851 | { | ||
1852 | struct spider_net_card *card = netdev_priv(netdev); | ||
1853 | |||
1854 | tasklet_kill(&card->rxram_full_tl); | ||
1855 | netif_poll_disable(netdev); | ||
1856 | netif_carrier_off(netdev); | ||
1857 | netif_stop_queue(netdev); | ||
1858 | del_timer_sync(&card->tx_timer); | ||
1859 | |||
1860 | /* disable/mask all interrupts */ | ||
1861 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); | ||
1862 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); | ||
1863 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); | ||
1864 | |||
1865 | /* free_irq(netdev->irq, netdev);*/ | ||
1866 | free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); | ||
1867 | |||
1868 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | ||
1869 | SPIDER_NET_DMA_TX_FEND_VALUE); | ||
1870 | |||
1871 | /* turn off DMA, force end */ | ||
1872 | spider_net_disable_rxdmac(card); | ||
1873 | |||
1874 | /* release chains */ | ||
1875 | if (spin_trylock(&card->tx_chain.lock)) { | ||
1876 | spider_net_release_tx_chain(card, 1); | ||
1877 | spin_unlock(&card->tx_chain.lock); | ||
1878 | } | ||
1879 | |||
1880 | spider_net_free_chain(card, &card->tx_chain); | ||
1881 | spider_net_free_chain(card, &card->rx_chain); | ||
1882 | |||
1883 | return 0; | ||
1884 | } | ||
1885 | |||
1886 | /** | ||
1958 | * spider_net_tx_timeout_task - task scheduled by the watchdog timeout | 1887 | * spider_net_tx_timeout_task - task scheduled by the watchdog timeout |
1959 | * function (to be called not under interrupt status) | 1888 | * function (to be called not under interrupt status) |
1960 | * @data: data, is interface device structure | 1889 | * @data: data, is interface device structure |
@@ -1982,7 +1911,7 @@ spider_net_tx_timeout_task(void *data) | |||
1982 | goto out; | 1911 | goto out; |
1983 | 1912 | ||
1984 | spider_net_open(netdev); | 1913 | spider_net_open(netdev); |
1985 | spider_net_kick_tx_dma(card, card->tx_chain.head); | 1914 | spider_net_kick_tx_dma(card); |
1986 | netif_device_attach(netdev); | 1915 | netif_device_attach(netdev); |
1987 | 1916 | ||
1988 | out: | 1917 | out: |
@@ -2065,7 +1994,6 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2065 | 1994 | ||
2066 | pci_set_drvdata(card->pdev, netdev); | 1995 | pci_set_drvdata(card->pdev, netdev); |
2067 | 1996 | ||
2068 | atomic_set(&card->tx_chain_release,0); | ||
2069 | card->rxram_full_tl.data = (unsigned long) card; | 1997 | card->rxram_full_tl.data = (unsigned long) card; |
2070 | card->rxram_full_tl.func = | 1998 | card->rxram_full_tl.func = |
2071 | (void (*)(unsigned long)) spider_net_handle_rxram_full; | 1999 | (void (*)(unsigned long)) spider_net_handle_rxram_full; |
@@ -2079,7 +2007,7 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2079 | 2007 | ||
2080 | spider_net_setup_netdev_ops(netdev); | 2008 | spider_net_setup_netdev_ops(netdev); |
2081 | 2009 | ||
2082 | netdev->features = NETIF_F_HW_CSUM; | 2010 | netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; |
2083 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | | 2011 | /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | |
2084 | * NETIF_F_HW_VLAN_FILTER */ | 2012 | * NETIF_F_HW_VLAN_FILTER */ |
2085 | 2013 | ||
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 3b8d951cf73c..f6dcf180ae3d 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h | |||
@@ -208,7 +208,10 @@ extern char spider_net_driver_name[]; | |||
208 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 | 208 | #define SPIDER_NET_DMA_RX_VALUE 0x80000000 |
209 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 | 209 | #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 |
210 | /* to set TX_DMA_EN */ | 210 | /* to set TX_DMA_EN */ |
211 | #define SPIDER_NET_DMA_TX_VALUE 0x80000000 | 211 | #define SPIDER_NET_TX_DMA_EN 0x80000000 |
212 | #define SPIDER_NET_GDTDCEIDIS 0x00000002 | ||
213 | #define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ | ||
214 | SPIDER_NET_GDTDCEIDIS | ||
212 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 | 215 | #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 |
213 | 216 | ||
214 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ | 217 | /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ |
@@ -329,55 +332,23 @@ enum spider_net_int2_status { | |||
329 | (~SPIDER_NET_TXINT) & \ | 332 | (~SPIDER_NET_TXINT) & \ |
330 | (~SPIDER_NET_RXINT) ) | 333 | (~SPIDER_NET_RXINT) ) |
331 | 334 | ||
332 | #define SPIDER_NET_GPREXEC 0x80000000 | 335 | #define SPIDER_NET_GPREXEC 0x80000000 |
333 | #define SPIDER_NET_GPRDAT_MASK 0x0000ffff | 336 | #define SPIDER_NET_GPRDAT_MASK 0x0000ffff |
334 | 337 | ||
335 | /* descriptor bits | 338 | #define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 |
336 | * | 339 | #define SPIDER_NET_DMAC_NOCS 0x00040000 |
337 | * 1010 descriptor ready | 340 | #define SPIDER_NET_DMAC_TCP 0x00020000 |
338 | * 0 descr in middle of chain | 341 | #define SPIDER_NET_DMAC_UDP 0x00030000 |
339 | * 000 fixed to 0 | 342 | #define SPIDER_NET_TXDCEST 0x08000000 |
340 | * | 343 | |
341 | * 0 no interrupt on completion | 344 | #define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 |
342 | * 000 fixed to 0 | 345 | #define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ |
343 | * 1 no ipsec processing | 346 | #define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ |
344 | * 1 last descriptor for this frame | 347 | #define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */ |
345 | * 00 no checksum | 348 | #define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */ |
346 | * 10 tcp checksum | 349 | #define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ |
347 | * 11 udp checksum | 350 | #define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ |
348 | * | 351 | #define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 |
349 | * 00 fixed to 0 | ||
350 | * 0 fixed to 0 | ||
351 | * 0 no interrupt on response errors | ||
352 | * 0 no interrupt on invalid descr | ||
353 | * 0 no interrupt on dma process termination | ||
354 | * 0 no interrupt on descr chain end | ||
355 | * 0 no interrupt on descr complete | ||
356 | * | ||
357 | * 000 fixed to 0 | ||
358 | * 0 response error interrupt status | ||
359 | * 0 invalid descr status | ||
360 | * 0 dma termination status | ||
361 | * 0 descr chain end status | ||
362 | * 0 descr complete status */ | ||
363 | #define SPIDER_NET_DMAC_CMDSTAT_NOCS 0xa00c0000 | ||
364 | #define SPIDER_NET_DMAC_CMDSTAT_TCPCS 0xa00e0000 | ||
365 | #define SPIDER_NET_DMAC_CMDSTAT_UDPCS 0xa00f0000 | ||
366 | #define SPIDER_NET_DESCR_IND_PROC_SHIFT 28 | ||
367 | #define SPIDER_NET_DESCR_IND_PROC_MASKO 0x0fffffff | ||
368 | |||
369 | /* descr ready, descr is in middle of chain, get interrupt on completion */ | ||
370 | #define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 | ||
371 | |||
372 | enum spider_net_descr_status { | ||
373 | SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ | ||
374 | SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ | ||
375 | SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ | ||
376 | SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */ | ||
377 | SPIDER_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ | ||
378 | SPIDER_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ | ||
379 | SPIDER_NET_DESCR_NOT_IN_USE /* any other value */ | ||
380 | }; | ||
381 | 352 | ||
382 | struct spider_net_descr { | 353 | struct spider_net_descr { |
383 | /* as defined by the hardware */ | 354 | /* as defined by the hardware */ |
@@ -398,7 +369,7 @@ struct spider_net_descr { | |||
398 | } __attribute__((aligned(32))); | 369 | } __attribute__((aligned(32))); |
399 | 370 | ||
400 | struct spider_net_descr_chain { | 371 | struct spider_net_descr_chain { |
401 | /* we walk from tail to head */ | 372 | spinlock_t lock; |
402 | struct spider_net_descr *head; | 373 | struct spider_net_descr *head; |
403 | struct spider_net_descr *tail; | 374 | struct spider_net_descr *tail; |
404 | }; | 375 | }; |
@@ -453,8 +424,6 @@ struct spider_net_card { | |||
453 | 424 | ||
454 | struct spider_net_descr_chain tx_chain; | 425 | struct spider_net_descr_chain tx_chain; |
455 | struct spider_net_descr_chain rx_chain; | 426 | struct spider_net_descr_chain rx_chain; |
456 | atomic_t rx_chain_refill; | ||
457 | atomic_t tx_chain_release; | ||
458 | 427 | ||
459 | struct net_device_stats netdev_stats; | 428 | struct net_device_stats netdev_stats; |
460 | 429 | ||
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 8673fd4c08c7..c6f5bc3c042f 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -3255,12 +3255,7 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) | |||
3255 | } | 3255 | } |
3256 | 3256 | ||
3257 | static struct pci_device_id happymeal_pci_ids[] = { | 3257 | static struct pci_device_id happymeal_pci_ids[] = { |
3258 | { | 3258 | { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) }, |
3259 | .vendor = PCI_VENDOR_ID_SUN, | ||
3260 | .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, | ||
3261 | .subvendor = PCI_ANY_ID, | ||
3262 | .subdevice = PCI_ANY_ID, | ||
3263 | }, | ||
3264 | { } /* Terminating entry */ | 3259 | { } /* Terminating entry */ |
3265 | }; | 3260 | }; |
3266 | 3261 | ||
@@ -3275,7 +3270,7 @@ static struct pci_driver hme_pci_driver = { | |||
3275 | 3270 | ||
3276 | static int __init happy_meal_pci_init(void) | 3271 | static int __init happy_meal_pci_init(void) |
3277 | { | 3272 | { |
3278 | return pci_module_init(&hme_pci_driver); | 3273 | return pci_register_driver(&hme_pci_driver); |
3279 | } | 3274 | } |
3280 | 3275 | ||
3281 | static void happy_meal_pci_exit(void) | 3276 | static void happy_meal_pci_exit(void) |
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 1ef9fd39a79a..0e3fdf7c6dd3 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
@@ -1537,7 +1537,7 @@ static int __init sparc_lance_init(void) | |||
1537 | { | 1537 | { |
1538 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | 1538 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || |
1539 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | 1539 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { |
1540 | memset(&sun4_sdev, 0, sizeof(sdev)); | 1540 | memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); |
1541 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | 1541 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; |
1542 | sun4_sdev.irqs[0] = 6; | 1542 | sun4_sdev.irqs[0] = 6; |
1543 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); | 1543 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); |
@@ -1547,16 +1547,16 @@ static int __init sparc_lance_init(void) | |||
1547 | 1547 | ||
1548 | static int __exit sunlance_sun4_remove(void) | 1548 | static int __exit sunlance_sun4_remove(void) |
1549 | { | 1549 | { |
1550 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); | 1550 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); |
1551 | struct net_device *net_dev = lp->dev; | 1551 | struct net_device *net_dev = lp->dev; |
1552 | 1552 | ||
1553 | unregister_netdevice(net_dev); | 1553 | unregister_netdevice(net_dev); |
1554 | 1554 | ||
1555 | lance_free_hwresources(root_lance_dev); | 1555 | lance_free_hwresources(lp); |
1556 | 1556 | ||
1557 | free_netdev(net_dev); | 1557 | free_netdev(net_dev); |
1558 | 1558 | ||
1559 | dev_set_drvdata(&sun4_sdev->dev, NULL); | 1559 | dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); |
1560 | 1560 | ||
1561 | return 0; | 1561 | return 0; |
1562 | } | 1562 | } |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ce6f3be86da0..6f97962dd06b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.62" | 71 | #define DRV_MODULE_VERSION "3.64" |
72 | #define DRV_MODULE_RELDATE "June 30, 2006" | 72 | #define DRV_MODULE_RELDATE "July 31, 2006" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -3097,7 +3097,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key, | |||
3097 | * Callers depend upon this behavior and assume that | 3097 | * Callers depend upon this behavior and assume that |
3098 | * we leave everything unchanged if we fail. | 3098 | * we leave everything unchanged if we fail. |
3099 | */ | 3099 | */ |
3100 | skb = dev_alloc_skb(skb_size); | 3100 | skb = netdev_alloc_skb(tp->dev, skb_size); |
3101 | if (skb == NULL) | 3101 | if (skb == NULL) |
3102 | return -ENOMEM; | 3102 | return -ENOMEM; |
3103 | 3103 | ||
@@ -3270,7 +3270,7 @@ static int tg3_rx(struct tg3 *tp, int budget) | |||
3270 | tg3_recycle_rx(tp, opaque_key, | 3270 | tg3_recycle_rx(tp, opaque_key, |
3271 | desc_idx, *post_ptr); | 3271 | desc_idx, *post_ptr); |
3272 | 3272 | ||
3273 | copy_skb = dev_alloc_skb(len + 2); | 3273 | copy_skb = netdev_alloc_skb(tp->dev, len + 2); |
3274 | if (copy_skb == NULL) | 3274 | if (copy_skb == NULL) |
3275 | goto drop_it_no_recycle; | 3275 | goto drop_it_no_recycle; |
3276 | 3276 | ||
@@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3590 | static int tg3_init_hw(struct tg3 *, int); | 3590 | static int tg3_init_hw(struct tg3 *, int); |
3591 | static int tg3_halt(struct tg3 *, int, int); | 3591 | static int tg3_halt(struct tg3 *, int, int); |
3592 | 3592 | ||
3593 | /* Restart hardware after configuration changes, self-test, etc. | ||
3594 | * Invoked with tp->lock held. | ||
3595 | */ | ||
3596 | static int tg3_restart_hw(struct tg3 *tp, int reset_phy) | ||
3597 | { | ||
3598 | int err; | ||
3599 | |||
3600 | err = tg3_init_hw(tp, reset_phy); | ||
3601 | if (err) { | ||
3602 | printk(KERN_ERR PFX "%s: Failed to re-initialize device, " | ||
3603 | "aborting.\n", tp->dev->name); | ||
3604 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
3605 | tg3_full_unlock(tp); | ||
3606 | del_timer_sync(&tp->timer); | ||
3607 | tp->irq_sync = 0; | ||
3608 | netif_poll_enable(tp->dev); | ||
3609 | dev_close(tp->dev); | ||
3610 | tg3_full_lock(tp, 0); | ||
3611 | } | ||
3612 | return err; | ||
3613 | } | ||
3614 | |||
3593 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3615 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3594 | static void tg3_poll_controller(struct net_device *dev) | 3616 | static void tg3_poll_controller(struct net_device *dev) |
3595 | { | 3617 | { |
@@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data) | |||
3630 | } | 3652 | } |
3631 | 3653 | ||
3632 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); | 3654 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
3633 | tg3_init_hw(tp, 1); | 3655 | if (tg3_init_hw(tp, 1)) |
3656 | goto out; | ||
3634 | 3657 | ||
3635 | tg3_netif_start(tp); | 3658 | tg3_netif_start(tp); |
3636 | 3659 | ||
3637 | if (restart_timer) | 3660 | if (restart_timer) |
3638 | mod_timer(&tp->timer, jiffies + 1); | 3661 | mod_timer(&tp->timer, jiffies + 1); |
3639 | 3662 | ||
3663 | out: | ||
3640 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | 3664 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; |
3641 | 3665 | ||
3642 | tg3_full_unlock(tp); | 3666 | tg3_full_unlock(tp); |
@@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, | |||
4124 | static int tg3_change_mtu(struct net_device *dev, int new_mtu) | 4148 | static int tg3_change_mtu(struct net_device *dev, int new_mtu) |
4125 | { | 4149 | { |
4126 | struct tg3 *tp = netdev_priv(dev); | 4150 | struct tg3 *tp = netdev_priv(dev); |
4151 | int err; | ||
4127 | 4152 | ||
4128 | if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) | 4153 | if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) |
4129 | return -EINVAL; | 4154 | return -EINVAL; |
@@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
4144 | 4169 | ||
4145 | tg3_set_mtu(dev, tp, new_mtu); | 4170 | tg3_set_mtu(dev, tp, new_mtu); |
4146 | 4171 | ||
4147 | tg3_init_hw(tp, 0); | 4172 | err = tg3_restart_hw(tp, 0); |
4148 | 4173 | ||
4149 | tg3_netif_start(tp); | 4174 | if (!err) |
4175 | tg3_netif_start(tp); | ||
4150 | 4176 | ||
4151 | tg3_full_unlock(tp); | 4177 | tg3_full_unlock(tp); |
4152 | 4178 | ||
4153 | return 0; | 4179 | return err; |
4154 | } | 4180 | } |
4155 | 4181 | ||
4156 | /* Free up pending packets in all rx/tx rings. | 4182 | /* Free up pending packets in all rx/tx rings. |
@@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp) | |||
4232 | * end up in the driver. tp->{tx,}lock are held and thus | 4258 | * end up in the driver. tp->{tx,}lock are held and thus |
4233 | * we may not sleep. | 4259 | * we may not sleep. |
4234 | */ | 4260 | */ |
4235 | static void tg3_init_rings(struct tg3 *tp) | 4261 | static int tg3_init_rings(struct tg3 *tp) |
4236 | { | 4262 | { |
4237 | u32 i; | 4263 | u32 i; |
4238 | 4264 | ||
@@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp) | |||
4281 | 4307 | ||
4282 | /* Now allocate fresh SKBs for each rx ring. */ | 4308 | /* Now allocate fresh SKBs for each rx ring. */ |
4283 | for (i = 0; i < tp->rx_pending; i++) { | 4309 | for (i = 0; i < tp->rx_pending; i++) { |
4284 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, | 4310 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) { |
4285 | -1, i) < 0) | 4311 | printk(KERN_WARNING PFX |
4312 | "%s: Using a smaller RX standard ring, " | ||
4313 | "only %d out of %d buffers were allocated " | ||
4314 | "successfully.\n", | ||
4315 | tp->dev->name, i, tp->rx_pending); | ||
4316 | if (i == 0) | ||
4317 | return -ENOMEM; | ||
4318 | tp->rx_pending = i; | ||
4286 | break; | 4319 | break; |
4320 | } | ||
4287 | } | 4321 | } |
4288 | 4322 | ||
4289 | if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { | 4323 | if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { |
4290 | for (i = 0; i < tp->rx_jumbo_pending; i++) { | 4324 | for (i = 0; i < tp->rx_jumbo_pending; i++) { |
4291 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, | 4325 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, |
4292 | -1, i) < 0) | 4326 | -1, i) < 0) { |
4327 | printk(KERN_WARNING PFX | ||
4328 | "%s: Using a smaller RX jumbo ring, " | ||
4329 | "only %d out of %d buffers were " | ||
4330 | "allocated successfully.\n", | ||
4331 | tp->dev->name, i, tp->rx_jumbo_pending); | ||
4332 | if (i == 0) { | ||
4333 | tg3_free_rings(tp); | ||
4334 | return -ENOMEM; | ||
4335 | } | ||
4336 | tp->rx_jumbo_pending = i; | ||
4293 | break; | 4337 | break; |
4338 | } | ||
4294 | } | 4339 | } |
4295 | } | 4340 | } |
4341 | return 0; | ||
4296 | } | 4342 | } |
4297 | 4343 | ||
4298 | /* | 4344 | /* |
@@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5815 | { | 5861 | { |
5816 | struct tg3 *tp = netdev_priv(dev); | 5862 | struct tg3 *tp = netdev_priv(dev); |
5817 | struct sockaddr *addr = p; | 5863 | struct sockaddr *addr = p; |
5864 | int err = 0; | ||
5818 | 5865 | ||
5819 | if (!is_valid_ether_addr(addr->sa_data)) | 5866 | if (!is_valid_ether_addr(addr->sa_data)) |
5820 | return -EINVAL; | 5867 | return -EINVAL; |
@@ -5832,9 +5879,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5832 | tg3_full_lock(tp, 1); | 5879 | tg3_full_lock(tp, 1); |
5833 | 5880 | ||
5834 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 5881 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
5835 | tg3_init_hw(tp, 0); | 5882 | err = tg3_restart_hw(tp, 0); |
5836 | 5883 | if (!err) | |
5837 | tg3_netif_start(tp); | 5884 | tg3_netif_start(tp); |
5838 | tg3_full_unlock(tp); | 5885 | tg3_full_unlock(tp); |
5839 | } else { | 5886 | } else { |
5840 | spin_lock_bh(&tp->lock); | 5887 | spin_lock_bh(&tp->lock); |
@@ -5842,7 +5889,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5842 | spin_unlock_bh(&tp->lock); | 5889 | spin_unlock_bh(&tp->lock); |
5843 | } | 5890 | } |
5844 | 5891 | ||
5845 | return 0; | 5892 | return err; |
5846 | } | 5893 | } |
5847 | 5894 | ||
5848 | /* tp->lock is held. */ | 5895 | /* tp->lock is held. */ |
@@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
5942 | * can only do this after the hardware has been | 5989 | * can only do this after the hardware has been |
5943 | * successfully reset. | 5990 | * successfully reset. |
5944 | */ | 5991 | */ |
5945 | tg3_init_rings(tp); | 5992 | err = tg3_init_rings(tp); |
5993 | if (err) | ||
5994 | return err; | ||
5946 | 5995 | ||
5947 | /* This value is determined during the probe time DMA | 5996 | /* This value is determined during the probe time DMA |
5948 | * engine test, tg3_test_dma. | 5997 | * engine test, tg3_test_dma. |
@@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * | |||
7956 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | 8005 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) |
7957 | { | 8006 | { |
7958 | struct tg3 *tp = netdev_priv(dev); | 8007 | struct tg3 *tp = netdev_priv(dev); |
7959 | int irq_sync = 0; | 8008 | int irq_sync = 0, err = 0; |
7960 | 8009 | ||
7961 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || | 8010 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || |
7962 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || | 8011 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || |
@@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7980 | 8029 | ||
7981 | if (netif_running(dev)) { | 8030 | if (netif_running(dev)) { |
7982 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8031 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7983 | tg3_init_hw(tp, 1); | 8032 | err = tg3_restart_hw(tp, 1); |
7984 | tg3_netif_start(tp); | 8033 | if (!err) |
8034 | tg3_netif_start(tp); | ||
7985 | } | 8035 | } |
7986 | 8036 | ||
7987 | tg3_full_unlock(tp); | 8037 | tg3_full_unlock(tp); |
7988 | 8038 | ||
7989 | return 0; | 8039 | return err; |
7990 | } | 8040 | } |
7991 | 8041 | ||
7992 | static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 8042 | static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
@@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
8001 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 8051 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
8002 | { | 8052 | { |
8003 | struct tg3 *tp = netdev_priv(dev); | 8053 | struct tg3 *tp = netdev_priv(dev); |
8004 | int irq_sync = 0; | 8054 | int irq_sync = 0, err = 0; |
8005 | 8055 | ||
8006 | if (netif_running(dev)) { | 8056 | if (netif_running(dev)) { |
8007 | tg3_netif_stop(tp); | 8057 | tg3_netif_stop(tp); |
@@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
8025 | 8075 | ||
8026 | if (netif_running(dev)) { | 8076 | if (netif_running(dev)) { |
8027 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8077 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
8028 | tg3_init_hw(tp, 1); | 8078 | err = tg3_restart_hw(tp, 1); |
8029 | tg3_netif_start(tp); | 8079 | if (!err) |
8080 | tg3_netif_start(tp); | ||
8030 | } | 8081 | } |
8031 | 8082 | ||
8032 | tg3_full_unlock(tp); | 8083 | tg3_full_unlock(tp); |
8033 | 8084 | ||
8034 | return 0; | 8085 | return err; |
8035 | } | 8086 | } |
8036 | 8087 | ||
8037 | static u32 tg3_get_rx_csum(struct net_device *dev) | 8088 | static u32 tg3_get_rx_csum(struct net_device *dev) |
@@ -8567,7 +8618,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
8567 | err = -EIO; | 8618 | err = -EIO; |
8568 | 8619 | ||
8569 | tx_len = 1514; | 8620 | tx_len = 1514; |
8570 | skb = dev_alloc_skb(tx_len); | 8621 | skb = netdev_alloc_skb(tp->dev, tx_len); |
8571 | if (!skb) | 8622 | if (!skb) |
8572 | return -ENOMEM; | 8623 | return -ENOMEM; |
8573 | 8624 | ||
@@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
8666 | if (!netif_running(tp->dev)) | 8717 | if (!netif_running(tp->dev)) |
8667 | return TG3_LOOPBACK_FAILED; | 8718 | return TG3_LOOPBACK_FAILED; |
8668 | 8719 | ||
8669 | tg3_reset_hw(tp, 1); | 8720 | err = tg3_reset_hw(tp, 1); |
8721 | if (err) | ||
8722 | return TG3_LOOPBACK_FAILED; | ||
8670 | 8723 | ||
8671 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) | 8724 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) |
8672 | err |= TG3_MAC_LOOPBACK_FAILED; | 8725 | err |= TG3_MAC_LOOPBACK_FAILED; |
@@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
8740 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8793 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
8741 | if (netif_running(dev)) { | 8794 | if (netif_running(dev)) { |
8742 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 8795 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
8743 | tg3_init_hw(tp, 1); | 8796 | if (!tg3_restart_hw(tp, 1)) |
8744 | tg3_netif_start(tp); | 8797 | tg3_netif_start(tp); |
8745 | } | 8798 | } |
8746 | 8799 | ||
8747 | tg3_full_unlock(tp); | 8800 | tg3_full_unlock(tp); |
@@ -11699,7 +11752,8 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
11699 | tg3_full_lock(tp, 0); | 11752 | tg3_full_lock(tp, 0); |
11700 | 11753 | ||
11701 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11754 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
11702 | tg3_init_hw(tp, 1); | 11755 | if (tg3_restart_hw(tp, 1)) |
11756 | goto out; | ||
11703 | 11757 | ||
11704 | tp->timer.expires = jiffies + tp->timer_offset; | 11758 | tp->timer.expires = jiffies + tp->timer_offset; |
11705 | add_timer(&tp->timer); | 11759 | add_timer(&tp->timer); |
@@ -11707,6 +11761,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
11707 | netif_device_attach(dev); | 11761 | netif_device_attach(dev); |
11708 | tg3_netif_start(tp); | 11762 | tg3_netif_start(tp); |
11709 | 11763 | ||
11764 | out: | ||
11710 | tg3_full_unlock(tp); | 11765 | tg3_full_unlock(tp); |
11711 | } | 11766 | } |
11712 | 11767 | ||
@@ -11733,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev) | |||
11733 | tg3_full_lock(tp, 0); | 11788 | tg3_full_lock(tp, 0); |
11734 | 11789 | ||
11735 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11790 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
11736 | tg3_init_hw(tp, 1); | 11791 | err = tg3_restart_hw(tp, 1); |
11792 | if (err) | ||
11793 | goto out; | ||
11737 | 11794 | ||
11738 | tp->timer.expires = jiffies + tp->timer_offset; | 11795 | tp->timer.expires = jiffies + tp->timer_offset; |
11739 | add_timer(&tp->timer); | 11796 | add_timer(&tp->timer); |
11740 | 11797 | ||
11741 | tg3_netif_start(tp); | 11798 | tg3_netif_start(tp); |
11742 | 11799 | ||
11800 | out: | ||
11743 | tg3_full_unlock(tp); | 11801 | tg3_full_unlock(tp); |
11744 | 11802 | ||
11745 | return 0; | 11803 | return err; |
11746 | } | 11804 | } |
11747 | 11805 | ||
11748 | static struct pci_driver tg3_driver = { | 11806 | static struct pci_driver tg3_driver = { |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f5b0078eb4ad..aa9cd92f46b2 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -2742,7 +2742,7 @@ static u32 check_connection_type(struct mac_regs __iomem * regs) | |||
2742 | 2742 | ||
2743 | if (PHYSR0 & PHYSR0_SPDG) | 2743 | if (PHYSR0 & PHYSR0_SPDG) |
2744 | status |= VELOCITY_SPEED_1000; | 2744 | status |= VELOCITY_SPEED_1000; |
2745 | if (PHYSR0 & PHYSR0_SPD10) | 2745 | else if (PHYSR0 & PHYSR0_SPD10) |
2746 | status |= VELOCITY_SPEED_10; | 2746 | status |= VELOCITY_SPEED_10; |
2747 | else | 2747 | else |
2748 | status |= VELOCITY_SPEED_100; | 2748 | status |= VELOCITY_SPEED_100; |
@@ -2851,8 +2851,17 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd | |||
2851 | u32 status; | 2851 | u32 status; |
2852 | status = check_connection_type(vptr->mac_regs); | 2852 | status = check_connection_type(vptr->mac_regs); |
2853 | 2853 | ||
2854 | cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; | 2854 | cmd->supported = SUPPORTED_TP | |
2855 | if (status & VELOCITY_SPEED_100) | 2855 | SUPPORTED_Autoneg | |
2856 | SUPPORTED_10baseT_Half | | ||
2857 | SUPPORTED_10baseT_Full | | ||
2858 | SUPPORTED_100baseT_Half | | ||
2859 | SUPPORTED_100baseT_Full | | ||
2860 | SUPPORTED_1000baseT_Half | | ||
2861 | SUPPORTED_1000baseT_Full; | ||
2862 | if (status & VELOCITY_SPEED_1000) | ||
2863 | cmd->speed = SPEED_1000; | ||
2864 | else if (status & VELOCITY_SPEED_100) | ||
2856 | cmd->speed = SPEED_100; | 2865 | cmd->speed = SPEED_100; |
2857 | else | 2866 | else |
2858 | cmd->speed = SPEED_10; | 2867 | cmd->speed = SPEED_10; |
@@ -2896,7 +2905,7 @@ static u32 velocity_get_link(struct net_device *dev) | |||
2896 | { | 2905 | { |
2897 | struct velocity_info *vptr = netdev_priv(dev); | 2906 | struct velocity_info *vptr = netdev_priv(dev); |
2898 | struct mac_regs __iomem * regs = vptr->mac_regs; | 2907 | struct mac_regs __iomem * regs = vptr->mac_regs; |
2899 | return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; | 2908 | return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; |
2900 | } | 2909 | } |
2901 | 2910 | ||
2902 | static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 2911 | static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 2c09ec908a3f..435e91ec4620 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c | |||
@@ -197,7 +197,6 @@ static int c101_open(struct net_device *dev) | |||
197 | sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); | 197 | sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); |
198 | 198 | ||
199 | set_carrier(port); | 199 | set_carrier(port); |
200 | printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port)); | ||
201 | 200 | ||
202 | /* enable MSCI1 CDCD interrupt */ | 201 | /* enable MSCI1 CDCD interrupt */ |
203 | sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port); | 202 | sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port); |
@@ -449,4 +448,5 @@ module_exit(c101_cleanup); | |||
449 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | 448 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); |
450 | MODULE_DESCRIPTION("Moxa C101 serial port driver"); | 449 | MODULE_DESCRIPTION("Moxa C101 serial port driver"); |
451 | MODULE_LICENSE("GPL v2"); | 450 | MODULE_LICENSE("GPL v2"); |
452 | module_param(hw, charp, 0444); /* hw=irq,ram:irq,... */ | 451 | module_param(hw, charp, 0444); |
452 | MODULE_PARM_DESC(hw, "irq,ram:irq,..."); | ||
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index b81263eaede0..fbaab5bf71eb 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c | |||
@@ -107,6 +107,7 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
107 | dev->hard_header = NULL; | 107 | dev->hard_header = NULL; |
108 | dev->type = ARPHRD_PPP; | 108 | dev->type = ARPHRD_PPP; |
109 | dev->addr_len = 0; | 109 | dev->addr_len = 0; |
110 | netif_dormant_off(dev); | ||
110 | return 0; | 111 | return 0; |
111 | } | 112 | } |
112 | 113 | ||
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c index 9456d31cb1c1..f15aa6ba77f1 100644 --- a/drivers/net/wan/hdlc_raw.c +++ b/drivers/net/wan/hdlc_raw.c | |||
@@ -82,6 +82,7 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
82 | dev->type = ARPHRD_RAWHDLC; | 82 | dev->type = ARPHRD_RAWHDLC; |
83 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | 83 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; |
84 | dev->addr_len = 0; | 84 | dev->addr_len = 0; |
85 | netif_dormant_off(dev); | ||
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
87 | 88 | ||
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c index b1285cc8fee6..d1884987f94e 100644 --- a/drivers/net/wan/hdlc_raw_eth.c +++ b/drivers/net/wan/hdlc_raw_eth.c | |||
@@ -100,6 +100,7 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
100 | dev->tx_queue_len = old_qlen; | 100 | dev->tx_queue_len = old_qlen; |
101 | memcpy(dev->dev_addr, "\x00\x01", 2); | 101 | memcpy(dev->dev_addr, "\x00\x01", 2); |
102 | get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); | 102 | get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); |
103 | netif_dormant_off(dev); | ||
103 | return 0; | 104 | return 0; |
104 | } | 105 | } |
105 | 106 | ||
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index 07e5eef1fe0f..a867fb411f89 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c | |||
@@ -212,6 +212,7 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) | |||
212 | dev->hard_header = NULL; | 212 | dev->hard_header = NULL; |
213 | dev->type = ARPHRD_X25; | 213 | dev->type = ARPHRD_X25; |
214 | dev->addr_len = 0; | 214 | dev->addr_len = 0; |
215 | netif_dormant_off(dev); | ||
215 | return 0; | 216 | return 0; |
216 | } | 217 | } |
217 | 218 | ||
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index e013b817cab8..dcf46add3adf 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c | |||
@@ -564,4 +564,5 @@ module_exit(n2_cleanup); | |||
564 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); | 564 | MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); |
565 | MODULE_DESCRIPTION("RISCom/N2 serial port driver"); | 565 | MODULE_DESCRIPTION("RISCom/N2 serial port driver"); |
566 | MODULE_LICENSE("GPL v2"); | 566 | MODULE_LICENSE("GPL v2"); |
567 | module_param(hw, charp, 0444); /* hw=io,irq,ram,ports:io,irq,... */ | 567 | module_param(hw, charp, 0444); |
568 | MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,..."); | ||
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index fa9d2c4edc93..2e8ac995d56f 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -447,6 +447,7 @@ config AIRO_CS | |||
447 | tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" | 447 | tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" |
448 | depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) | 448 | depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) |
449 | select CRYPTO | 449 | select CRYPTO |
450 | select CRYPTO_AES | ||
450 | ---help--- | 451 | ---help--- |
451 | This is the standard Linux driver to support Cisco/Aironet PCMCIA | 452 | This is the standard Linux driver to support Cisco/Aironet PCMCIA |
452 | 802.11 wireless cards. This driver is the same as the Aironet | 453 | 802.11 wireless cards. This driver is the same as the Aironet |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 3889f79e7128..df317c1e12a8 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -3701,7 +3701,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, | |||
3701 | } | 3701 | } |
3702 | if (sec->flags & SEC_AUTH_MODE) { | 3702 | if (sec->flags & SEC_AUTH_MODE) { |
3703 | secinfo->auth_mode = sec->auth_mode; | 3703 | secinfo->auth_mode = sec->auth_mode; |
3704 | dprintk(", .auth_mode = %d\n", sec->auth_mode); | 3704 | dprintk(", .auth_mode = %d", sec->auth_mode); |
3705 | } | 3705 | } |
3706 | dprintk("\n"); | 3706 | dprintk("\n"); |
3707 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && | 3707 | if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index d6ed5781b93a..317ace7f9aae 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -2875,7 +2875,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, | |||
2875 | if (orinoco_lock(priv, &flags) != 0) | 2875 | if (orinoco_lock(priv, &flags) != 0) |
2876 | return -EBUSY; | 2876 | return -EBUSY; |
2877 | 2877 | ||
2878 | if (erq->pointer) { | 2878 | if (erq->length > 0) { |
2879 | if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) | 2879 | if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) |
2880 | index = priv->tx_key; | 2880 | index = priv->tx_key; |
2881 | 2881 | ||
@@ -2918,7 +2918,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, | |||
2918 | if (erq->flags & IW_ENCODE_RESTRICTED) | 2918 | if (erq->flags & IW_ENCODE_RESTRICTED) |
2919 | restricted = 1; | 2919 | restricted = 1; |
2920 | 2920 | ||
2921 | if (erq->pointer) { | 2921 | if (erq->pointer && erq->length > 0) { |
2922 | priv->keys[index].len = cpu_to_le16(xlen); | 2922 | priv->keys[index].len = cpu_to_le16(xlen); |
2923 | memset(priv->keys[index].data, 0, | 2923 | memset(priv->keys[index].data, 0, |
2924 | sizeof(priv->keys[index].data)); | 2924 | sizeof(priv->keys[index].data)); |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 662ecc8a33ff..c52e9bcf8d02 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -1820,6 +1820,8 @@ static int zd1201_probe(struct usb_interface *interface, | |||
1820 | zd->dev->name); | 1820 | zd->dev->name); |
1821 | 1821 | ||
1822 | usb_set_intfdata(interface, zd); | 1822 | usb_set_intfdata(interface, zd); |
1823 | zd1201_enable(zd); /* zd1201 likes to startup enabled, */ | ||
1824 | zd1201_disable(zd); /* interfering with all the wifis in range */ | ||
1823 | return 0; | 1825 | return 0; |
1824 | 1826 | ||
1825 | err_net: | 1827 | err_net: |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index efc9c4bd826f..da9d06bdb818 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -797,7 +797,7 @@ static int zd1211_hw_init_hmac(struct zd_chip *chip) | |||
797 | { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, | 797 | { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, |
798 | { CR_ZD1211_RETRY_MAX, 0x2 }, | 798 | { CR_ZD1211_RETRY_MAX, 0x2 }, |
799 | { CR_SNIFFER_ON, 0 }, | 799 | { CR_SNIFFER_ON, 0 }, |
800 | { CR_RX_FILTER, AP_RX_FILTER }, | 800 | { CR_RX_FILTER, STA_RX_FILTER }, |
801 | { CR_GROUP_HASH_P1, 0x00 }, | 801 | { CR_GROUP_HASH_P1, 0x00 }, |
802 | { CR_GROUP_HASH_P2, 0x80000000 }, | 802 | { CR_GROUP_HASH_P2, 0x80000000 }, |
803 | { CR_REG1, 0xa4 }, | 803 | { CR_REG1, 0xa4 }, |
@@ -844,7 +844,7 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip) | |||
844 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, | 844 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, |
845 | { CR_ZD1211B_TXOP, 0x01800824 }, | 845 | { CR_ZD1211B_TXOP, 0x01800824 }, |
846 | { CR_SNIFFER_ON, 0 }, | 846 | { CR_SNIFFER_ON, 0 }, |
847 | { CR_RX_FILTER, AP_RX_FILTER }, | 847 | { CR_RX_FILTER, STA_RX_FILTER }, |
848 | { CR_GROUP_HASH_P1, 0x00 }, | 848 | { CR_GROUP_HASH_P1, 0x00 }, |
849 | { CR_GROUP_HASH_P2, 0x80000000 }, | 849 | { CR_GROUP_HASH_P2, 0x80000000 }, |
850 | { CR_REG1, 0xa4 }, | 850 | { CR_REG1, 0xa4 }, |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 805121093ab5..069d2b467339 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -461,10 +461,15 @@ | |||
461 | 461 | ||
462 | #define CR_RX_FILTER CTL_REG(0x068c) | 462 | #define CR_RX_FILTER CTL_REG(0x068c) |
463 | #define RX_FILTER_ASSOC_RESPONSE 0x0002 | 463 | #define RX_FILTER_ASSOC_RESPONSE 0x0002 |
464 | #define RX_FILTER_REASSOC_RESPONSE 0x0008 | ||
464 | #define RX_FILTER_PROBE_RESPONSE 0x0020 | 465 | #define RX_FILTER_PROBE_RESPONSE 0x0020 |
465 | #define RX_FILTER_BEACON 0x0100 | 466 | #define RX_FILTER_BEACON 0x0100 |
467 | #define RX_FILTER_DISASSOC 0x0400 | ||
466 | #define RX_FILTER_AUTH 0x0800 | 468 | #define RX_FILTER_AUTH 0x0800 |
467 | /* Sniff modus sets filter to 0xfffff */ | 469 | #define AP_RX_FILTER 0x0400feff |
470 | #define STA_RX_FILTER 0x0000ffff | ||
471 | |||
472 | /* Monitor mode sets filter to 0xfffff */ | ||
468 | 473 | ||
469 | #define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) | 474 | #define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) |
470 | #define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694) | 475 | #define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694) |
@@ -546,9 +551,6 @@ | |||
546 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) | 551 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) |
547 | #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) | 552 | #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) |
548 | 553 | ||
549 | #define AP_RX_FILTER 0x0400feff | ||
550 | #define STA_RX_FILTER 0x0000ffff | ||
551 | |||
552 | #define CWIN_SIZE 0x007f043f | 554 | #define CWIN_SIZE 0x007f043f |
553 | 555 | ||
554 | 556 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 3bdc54d128d0..d6f3e02a0b54 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -108,7 +108,9 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) | |||
108 | if (r) | 108 | if (r) |
109 | goto disable_int; | 109 | goto disable_int; |
110 | 110 | ||
111 | r = zd_set_encryption_type(chip, NO_WEP); | 111 | /* We must inform the device that we are doing encryption/decryption in |
112 | * software at the moment. */ | ||
113 | r = zd_set_encryption_type(chip, ENC_SNIFFER); | ||
112 | if (r) | 114 | if (r) |
113 | goto disable_int; | 115 | goto disable_int; |
114 | 116 | ||
@@ -136,10 +138,8 @@ static int reset_mode(struct zd_mac *mac) | |||
136 | { | 138 | { |
137 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | 139 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); |
138 | struct zd_ioreq32 ioreqs[3] = { | 140 | struct zd_ioreq32 ioreqs[3] = { |
139 | { CR_RX_FILTER, RX_FILTER_BEACON|RX_FILTER_PROBE_RESPONSE| | 141 | { CR_RX_FILTER, STA_RX_FILTER }, |
140 | RX_FILTER_AUTH|RX_FILTER_ASSOC_RESPONSE }, | ||
141 | { CR_SNIFFER_ON, 0U }, | 142 | { CR_SNIFFER_ON, 0U }, |
142 | { CR_ENCRYPTION_TYPE, NO_WEP }, | ||
143 | }; | 143 | }; |
144 | 144 | ||
145 | if (ieee->iw_mode == IW_MODE_MONITOR) { | 145 | if (ieee->iw_mode == IW_MODE_MONITOR) { |
@@ -713,10 +713,10 @@ static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) | |||
713 | struct zd_rt_hdr { | 713 | struct zd_rt_hdr { |
714 | struct ieee80211_radiotap_header rt_hdr; | 714 | struct ieee80211_radiotap_header rt_hdr; |
715 | u8 rt_flags; | 715 | u8 rt_flags; |
716 | u8 rt_rate; | ||
716 | u16 rt_channel; | 717 | u16 rt_channel; |
717 | u16 rt_chbitmask; | 718 | u16 rt_chbitmask; |
718 | u16 rt_rate; | 719 | } __attribute__((packed)); |
719 | }; | ||
720 | 720 | ||
721 | static void fill_rt_header(void *buffer, struct zd_mac *mac, | 721 | static void fill_rt_header(void *buffer, struct zd_mac *mac, |
722 | const struct ieee80211_rx_stats *stats, | 722 | const struct ieee80211_rx_stats *stats, |
@@ -735,14 +735,14 @@ static void fill_rt_header(void *buffer, struct zd_mac *mac, | |||
735 | if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) | 735 | if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) |
736 | hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; | 736 | hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; |
737 | 737 | ||
738 | hdr->rt_rate = stats->rate / 5; | ||
739 | |||
738 | /* FIXME: 802.11a */ | 740 | /* FIXME: 802.11a */ |
739 | hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( | 741 | hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( |
740 | _zd_chip_get_channel(&mac->chip))); | 742 | _zd_chip_get_channel(&mac->chip))); |
741 | hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | | 743 | hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | |
742 | ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == | 744 | ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == |
743 | ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); | 745 | ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); |
744 | |||
745 | hdr->rt_rate = stats->rate / 5; | ||
746 | } | 746 | } |
747 | 747 | ||
748 | /* Returns 1 if the data packet is for us and 0 otherwise. */ | 748 | /* Returns 1 if the data packet is for us and 0 otherwise. */ |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 72f90525bf68..6320984126c7 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -323,7 +323,6 @@ static void disable_read_regs_int(struct zd_usb *usb) | |||
323 | { | 323 | { |
324 | struct zd_usb_interrupt *intr = &usb->intr; | 324 | struct zd_usb_interrupt *intr = &usb->intr; |
325 | 325 | ||
326 | ZD_ASSERT(in_interrupt()); | ||
327 | spin_lock(&intr->lock); | 326 | spin_lock(&intr->lock); |
328 | intr->read_regs_enabled = 0; | 327 | intr->read_regs_enabled = 0; |
329 | spin_unlock(&intr->lock); | 328 | spin_unlock(&intr->lock); |
@@ -545,11 +544,11 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | |||
545 | * be padded. Unaligned access might also happen if the length_info | 544 | * be padded. Unaligned access might also happen if the length_info |
546 | * structure is not present. | 545 | * structure is not present. |
547 | */ | 546 | */ |
548 | if (get_unaligned(&length_info->tag) == RX_LENGTH_INFO_TAG) { | 547 | if (get_unaligned(&length_info->tag) == cpu_to_le16(RX_LENGTH_INFO_TAG)) |
548 | { | ||
549 | unsigned int l, k, n; | 549 | unsigned int l, k, n; |
550 | for (i = 0, l = 0;; i++) { | 550 | for (i = 0, l = 0;; i++) { |
551 | k = le16_to_cpu(get_unaligned( | 551 | k = le16_to_cpu(get_unaligned(&length_info->length[i])); |
552 | &length_info->length[i])); | ||
553 | n = l+k; | 552 | n = l+k; |
554 | if (n > length) | 553 | if (n > length) |
555 | return; | 554 | return; |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 34de5697983d..e2fef60c2d06 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -27,8 +27,7 @@ | |||
27 | * along with this program; if not, write to the Free Software | 27 | * along with this program; if not, write to the Free Software |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
29 | * | 29 | * |
30 | * Send feedback to <gregkh@us.ibm.com>, | 30 | * Send feedback to <kristen.c.accardi@intel.com> |
31 | * <t-kochi@bq.jp.nec.com> | ||
32 | * | 31 | * |
33 | */ | 32 | */ |
34 | 33 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ef95d12fb32c..ae67a8f55ba1 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * along with this program; if not, write to the Free Software | 26 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
28 | * | 28 | * |
29 | * Send feedback to <t-kochi@bq.jp.nec.com> | 29 | * Send feedback to <kristen.c.accardi@intel.com> |
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 50bfc1b2f3bf..478d0d28f7ad 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -30,23 +30,6 @@ MODULE_LICENSE("GPL"); | |||
30 | /* global data */ | 30 | /* global data */ |
31 | static const char device_name[] = "pcieport-driver"; | 31 | static const char device_name[] = "pcieport-driver"; |
32 | 32 | ||
33 | static int pcie_portdrv_save_config(struct pci_dev *dev) | ||
34 | { | ||
35 | return pci_save_state(dev); | ||
36 | } | ||
37 | |||
38 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | ||
39 | { | ||
40 | int retval; | ||
41 | |||
42 | pci_restore_state(dev); | ||
43 | retval = pci_enable_device(dev); | ||
44 | if (retval) | ||
45 | return retval; | ||
46 | pci_set_master(dev); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | /* | 33 | /* |
51 | * pcie_portdrv_probe - Probe PCI-Express port devices | 34 | * pcie_portdrv_probe - Probe PCI-Express port devices |
52 | * @dev: PCI-Express port device being probed | 35 | * @dev: PCI-Express port device being probed |
@@ -73,8 +56,10 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
73 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", | 56 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", |
74 | __FUNCTION__, dev->device, dev->vendor); | 57 | __FUNCTION__, dev->device, dev->vendor); |
75 | } | 58 | } |
76 | if (pcie_port_device_register(dev)) | 59 | if (pcie_port_device_register(dev)) { |
60 | pci_disable_device(dev); | ||
77 | return -ENOMEM; | 61 | return -ENOMEM; |
62 | } | ||
78 | 63 | ||
79 | return 0; | 64 | return 0; |
80 | } | 65 | } |
@@ -86,6 +71,23 @@ static void pcie_portdrv_remove (struct pci_dev *dev) | |||
86 | } | 71 | } |
87 | 72 | ||
88 | #ifdef CONFIG_PM | 73 | #ifdef CONFIG_PM |
74 | static int pcie_portdrv_save_config(struct pci_dev *dev) | ||
75 | { | ||
76 | return pci_save_state(dev); | ||
77 | } | ||
78 | |||
79 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | ||
80 | { | ||
81 | int retval; | ||
82 | |||
83 | pci_restore_state(dev); | ||
84 | retval = pci_enable_device(dev); | ||
85 | if (retval) | ||
86 | return retval; | ||
87 | pci_set_master(dev); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
89 | static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) | 91 | static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) |
90 | { | 92 | { |
91 | int ret = pcie_port_device_suspend(dev, state); | 93 | int ret = pcie_port_device_suspend(dev, state); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e3c78c39b7e4..fb08bc951ac0 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -990,6 +990,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
990 | case 0x8070: /* P4G8X Deluxe */ | 990 | case 0x8070: /* P4G8X Deluxe */ |
991 | asus_hides_smbus = 1; | 991 | asus_hides_smbus = 1; |
992 | } | 992 | } |
993 | if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) | ||
994 | switch (dev->subsystem_device) { | ||
995 | case 0x80c9: /* PU-DLS */ | ||
996 | asus_hides_smbus = 1; | ||
997 | } | ||
993 | if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) | 998 | if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) |
994 | switch (dev->subsystem_device) { | 999 | switch (dev->subsystem_device) { |
995 | case 0x1751: /* M2N notebook */ | 1000 | case 0x1751: /* M2N notebook */ |
@@ -1058,6 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asu | |||
1058 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); | 1063 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); |
1059 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); | 1064 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); |
1060 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); | 1065 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); |
1066 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge ); | ||
1061 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); | 1067 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); |
1062 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); | 1068 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); |
1063 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); | 1069 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); |
@@ -1081,6 +1087,7 @@ static void __init asus_hides_smbus_lpc(struct pci_dev *dev) | |||
1081 | } | 1087 | } |
1082 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); | 1088 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); |
1083 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); | 1089 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); |
1090 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); | ||
1084 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1091 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); |
1085 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1092 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
1086 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1093 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 622b3f8ba820..d529462d1b53 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -41,7 +41,7 @@ pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) | |||
41 | * in the global list of PCI buses. If the bus is found, a pointer to its | 41 | * in the global list of PCI buses. If the bus is found, a pointer to its |
42 | * data structure is returned. If no bus is found, %NULL is returned. | 42 | * data structure is returned. If no bus is found, %NULL is returned. |
43 | */ | 43 | */ |
44 | struct pci_bus * __devinit pci_find_bus(int domain, int busnr) | 44 | struct pci_bus * pci_find_bus(int domain, int busnr) |
45 | { | 45 | { |
46 | struct pci_bus *bus = NULL; | 46 | struct pci_bus *bus = NULL; |
47 | struct pci_bus *tmp_bus; | 47 | struct pci_bus *tmp_bus; |
@@ -61,7 +61,7 @@ struct pci_bus * __devinit pci_find_bus(int domain, int busnr) | |||
61 | * @from: Previous PCI bus found, or %NULL for new search. | 61 | * @from: Previous PCI bus found, or %NULL for new search. |
62 | * | 62 | * |
63 | * Iterates through the list of known PCI busses. A new search is | 63 | * Iterates through the list of known PCI busses. A new search is |
64 | * initiated by passing %NULL to the @from argument. Otherwise if | 64 | * initiated by passing %NULL as the @from argument. Otherwise if |
65 | * @from is not %NULL, searches continue from next device on the | 65 | * @from is not %NULL, searches continue from next device on the |
66 | * global list. | 66 | * global list. |
67 | */ | 67 | */ |
@@ -148,13 +148,14 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
148 | * @from: Previous PCI device found in search, or %NULL for new search. | 148 | * @from: Previous PCI device found in search, or %NULL for new search. |
149 | * | 149 | * |
150 | * Iterates through the list of known PCI devices. If a PCI device is | 150 | * Iterates through the list of known PCI devices. If a PCI device is |
151 | * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its | 151 | * found with a matching @vendor, @device, @ss_vendor and @ss_device, a |
152 | * device structure is returned. Otherwise, %NULL is returned. | 152 | * pointer to its device structure is returned. Otherwise, %NULL is returned. |
153 | * A new search is initiated by passing %NULL to the @from argument. | 153 | * A new search is initiated by passing %NULL as the @from argument. |
154 | * Otherwise if @from is not %NULL, searches continue from next device on the global list. | 154 | * Otherwise if @from is not %NULL, searches continue from next device |
155 | * on the global list. | ||
155 | * | 156 | * |
156 | * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as | 157 | * NOTE: Do not use this function any more; use pci_get_subsys() instead, as |
157 | * the pci device returned by this function can disappear at any moment in | 158 | * the PCI device returned by this function can disappear at any moment in |
158 | * time. | 159 | * time. |
159 | */ | 160 | */ |
160 | static struct pci_dev * pci_find_subsys(unsigned int vendor, | 161 | static struct pci_dev * pci_find_subsys(unsigned int vendor, |
@@ -191,14 +192,15 @@ exit: | |||
191 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | 192 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
192 | * @from: Previous PCI device found in search, or %NULL for new search. | 193 | * @from: Previous PCI device found in search, or %NULL for new search. |
193 | * | 194 | * |
194 | * Iterates through the list of known PCI devices. If a PCI device is | 195 | * Iterates through the list of known PCI devices. If a PCI device is found |
195 | * found with a matching @vendor and @device, a pointer to its device structure is | 196 | * with a matching @vendor and @device, a pointer to its device structure is |
196 | * returned. Otherwise, %NULL is returned. | 197 | * returned. Otherwise, %NULL is returned. |
197 | * A new search is initiated by passing %NULL to the @from argument. | 198 | * A new search is initiated by passing %NULL as the @from argument. |
198 | * Otherwise if @from is not %NULL, searches continue from next device on the global list. | 199 | * Otherwise if @from is not %NULL, searches continue from next device |
200 | * on the global list. | ||
199 | * | 201 | * |
200 | * NOTE: Do not use this function anymore, use pci_get_device() instead, as | 202 | * NOTE: Do not use this function any more; use pci_get_device() instead, as |
201 | * the pci device returned by this function can disappear at any moment in | 203 | * the PCI device returned by this function can disappear at any moment in |
202 | * time. | 204 | * time. |
203 | */ | 205 | */ |
204 | struct pci_dev * | 206 | struct pci_dev * |
@@ -215,11 +217,11 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev * | |||
215 | * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids | 217 | * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids |
216 | * @from: Previous PCI device found in search, or %NULL for new search. | 218 | * @from: Previous PCI device found in search, or %NULL for new search. |
217 | * | 219 | * |
218 | * Iterates through the list of known PCI devices. If a PCI device is | 220 | * Iterates through the list of known PCI devices. If a PCI device is found |
219 | * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its | 221 | * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its |
220 | * device structure is returned, and the reference count to the device is | 222 | * device structure is returned, and the reference count to the device is |
221 | * incremented. Otherwise, %NULL is returned. A new search is initiated by | 223 | * incremented. Otherwise, %NULL is returned. A new search is initiated by |
222 | * passing %NULL to the @from argument. Otherwise if @from is not %NULL, | 224 | * passing %NULL as the @from argument. Otherwise if @from is not %NULL, |
223 | * searches continue from next device on the global list. | 225 | * searches continue from next device on the global list. |
224 | * The reference count for @from is always decremented if it is not %NULL. | 226 | * The reference count for @from is always decremented if it is not %NULL. |
225 | */ | 227 | */ |
@@ -262,7 +264,7 @@ exit: | |||
262 | * found with a matching @vendor and @device, the reference count to the | 264 | * found with a matching @vendor and @device, the reference count to the |
263 | * device is incremented and a pointer to its device structure is returned. | 265 | * device is incremented and a pointer to its device structure is returned. |
264 | * Otherwise, %NULL is returned. A new search is initiated by passing %NULL | 266 | * Otherwise, %NULL is returned. A new search is initiated by passing %NULL |
265 | * to the @from argument. Otherwise if @from is not %NULL, searches continue | 267 | * as the @from argument. Otherwise if @from is not %NULL, searches continue |
266 | * from next device on the global list. The reference count for @from is | 268 | * from next device on the global list. The reference count for @from is |
267 | * always decremented if it is not %NULL. | 269 | * always decremented if it is not %NULL. |
268 | */ | 270 | */ |
@@ -279,11 +281,13 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) | |||
279 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | 281 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
280 | * @from: Previous PCI device found in search, or %NULL for new search. | 282 | * @from: Previous PCI device found in search, or %NULL for new search. |
281 | * | 283 | * |
282 | * Iterates through the list of known PCI devices in the reverse order of pci_find_device(). | 284 | * Iterates through the list of known PCI devices in the reverse order of |
285 | * pci_find_device(). | ||
283 | * If a PCI device is found with a matching @vendor and @device, a pointer to | 286 | * If a PCI device is found with a matching @vendor and @device, a pointer to |
284 | * its device structure is returned. Otherwise, %NULL is returned. | 287 | * its device structure is returned. Otherwise, %NULL is returned. |
285 | * A new search is initiated by passing %NULL to the @from argument. | 288 | * A new search is initiated by passing %NULL as the @from argument. |
286 | * Otherwise if @from is not %NULL, searches continue from previous device on the global list. | 289 | * Otherwise if @from is not %NULL, searches continue from previous device |
290 | * on the global list. | ||
287 | */ | 291 | */ |
288 | struct pci_dev * | 292 | struct pci_dev * |
289 | pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) | 293 | pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) |
@@ -317,7 +321,7 @@ exit: | |||
317 | * found with a matching @class, the reference count to the device is | 321 | * found with a matching @class, the reference count to the device is |
318 | * incremented and a pointer to its device structure is returned. | 322 | * incremented and a pointer to its device structure is returned. |
319 | * Otherwise, %NULL is returned. | 323 | * Otherwise, %NULL is returned. |
320 | * A new search is initiated by passing %NULL to the @from argument. | 324 | * A new search is initiated by passing %NULL as the @from argument. |
321 | * Otherwise if @from is not %NULL, searches continue from next device | 325 | * Otherwise if @from is not %NULL, searches continue from next device |
322 | * on the global list. The reference count for @from is always decremented | 326 | * on the global list. The reference count for @from is always decremented |
323 | * if it is not %NULL. | 327 | * if it is not %NULL. |
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 738b1ef595a3..9ad18e62658d 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -601,12 +601,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
601 | ret = CS_BAD_ARGS; | 601 | ret = CS_BAD_ARGS; |
602 | else { | 602 | else { |
603 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); | 603 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); |
604 | if (p_dev == NULL) | 604 | ret = pccard_get_configuration_info(s, p_dev, &buf->config); |
605 | ret = CS_BAD_ARGS; | 605 | pcmcia_put_dev(p_dev); |
606 | else { | ||
607 | ret = pccard_get_configuration_info(s, p_dev, &buf->config); | ||
608 | pcmcia_put_dev(p_dev); | ||
609 | } | ||
610 | } | 606 | } |
611 | break; | 607 | break; |
612 | case DS_GET_FIRST_TUPLE: | 608 | case DS_GET_FIRST_TUPLE: |
@@ -636,12 +632,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
636 | ret = CS_BAD_ARGS; | 632 | ret = CS_BAD_ARGS; |
637 | else { | 633 | else { |
638 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); | 634 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); |
639 | if (p_dev == NULL) | 635 | ret = pccard_get_status(s, p_dev, &buf->status); |
640 | ret = CS_BAD_ARGS; | 636 | pcmcia_put_dev(p_dev); |
641 | else { | ||
642 | ret = pccard_get_status(s, p_dev, &buf->status); | ||
643 | pcmcia_put_dev(p_dev); | ||
644 | } | ||
645 | } | 637 | } |
646 | break; | 638 | break; |
647 | case DS_VALIDATE_CIS: | 639 | case DS_VALIDATE_CIS: |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 7bf25b88ea31..c8323399e9e4 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -245,10 +245,17 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, | |||
245 | return CS_SUCCESS; | 245 | return CS_SUCCESS; |
246 | } | 246 | } |
247 | 247 | ||
248 | /* !!! This is a hack !!! */ | 248 | config->Attributes = c->Attributes | CONF_VALID_CLIENT; |
249 | memcpy(&config->Attributes, &c->Attributes, sizeof(config_t)); | 249 | config->Vcc = s->socket.Vcc; |
250 | config->Attributes |= CONF_VALID_CLIENT; | 250 | config->Vpp1 = config->Vpp2 = s->socket.Vpp; |
251 | config->CardValues = c->CardValues; | 251 | config->IntType = c->IntType; |
252 | config->ConfigBase = c->ConfigBase; | ||
253 | config->Status = c->Status; | ||
254 | config->Pin = c->Pin; | ||
255 | config->Copy = c->Copy; | ||
256 | config->Option = c->Option; | ||
257 | config->ExtStatus = c->ExtStatus; | ||
258 | config->Present = config->CardValues = c->CardValues; | ||
252 | config->IRQAttributes = c->irq.Attributes; | 259 | config->IRQAttributes = c->irq.Attributes; |
253 | config->AssignedIRQ = s->irq.AssignedIRQ; | 260 | config->AssignedIRQ = s->irq.AssignedIRQ; |
254 | config->BasePort1 = c->io.BasePort1; | 261 | config->BasePort1 = c->io.BasePort1; |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 3163e3d73da1..9d8b415eca79 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -265,8 +265,8 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
265 | pnp_printf(buffer," disabled\n"); | 265 | pnp_printf(buffer," disabled\n"); |
266 | else | 266 | else |
267 | pnp_printf(buffer," 0x%llx-0x%llx\n", | 267 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
268 | pnp_port_start(dev, i), | 268 | (unsigned long long)pnp_port_start(dev, i), |
269 | pnp_port_end(dev, i)); | 269 | (unsigned long long)pnp_port_end(dev, i)); |
270 | } | 270 | } |
271 | } | 271 | } |
272 | for (i = 0; i < PNP_MAX_MEM; i++) { | 272 | for (i = 0; i < PNP_MAX_MEM; i++) { |
@@ -276,8 +276,8 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
276 | pnp_printf(buffer," disabled\n"); | 276 | pnp_printf(buffer," disabled\n"); |
277 | else | 277 | else |
278 | pnp_printf(buffer," 0x%llx-0x%llx\n", | 278 | pnp_printf(buffer," 0x%llx-0x%llx\n", |
279 | pnp_mem_start(dev, i), | 279 | (unsigned long long)pnp_mem_start(dev, i), |
280 | pnp_mem_end(dev, i)); | 280 | (unsigned long long)pnp_mem_end(dev, i)); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | for (i = 0; i < PNP_MAX_IRQ; i++) { | 283 | for (i = 0; i < PNP_MAX_IRQ; i++) { |
@@ -287,7 +287,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
287 | pnp_printf(buffer," disabled\n"); | 287 | pnp_printf(buffer," disabled\n"); |
288 | else | 288 | else |
289 | pnp_printf(buffer," %lld\n", | 289 | pnp_printf(buffer," %lld\n", |
290 | pnp_irq(dev, i)); | 290 | (unsigned long long)pnp_irq(dev, i)); |
291 | } | 291 | } |
292 | } | 292 | } |
293 | for (i = 0; i < PNP_MAX_DMA; i++) { | 293 | for (i = 0; i < PNP_MAX_DMA; i++) { |
@@ -297,7 +297,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at | |||
297 | pnp_printf(buffer," disabled\n"); | 297 | pnp_printf(buffer," disabled\n"); |
298 | else | 298 | else |
299 | pnp_printf(buffer," %lld\n", | 299 | pnp_printf(buffer," %lld\n", |
300 | pnp_dma(dev, i)); | 300 | (unsigned long long)pnp_dma(dev, i)); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | ret = (buffer->curr - buf); | 303 | ret = (buffer->curr - buf); |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 212268881857..dc79b0a0059f 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -173,6 +173,9 @@ pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, | |||
173 | return; | 173 | return; |
174 | } | 174 | } |
175 | 175 | ||
176 | if (p->producer_consumer == ACPI_PRODUCER) | ||
177 | return; | ||
178 | |||
176 | if (p->resource_type == ACPI_MEMORY_RANGE) | 179 | if (p->resource_type == ACPI_MEMORY_RANGE) |
177 | pnpacpi_parse_allocated_memresource(res_table, | 180 | pnpacpi_parse_allocated_memresource(res_table, |
178 | p->minimum, p->address_length); | 181 | p->minimum, p->address_length); |
@@ -252,9 +255,14 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
252 | break; | 255 | break; |
253 | 256 | ||
254 | case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: | 257 | case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: |
258 | if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER) | ||
259 | return AE_OK; | ||
255 | break; | 260 | break; |
256 | 261 | ||
257 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: | 262 | case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: |
263 | if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER) | ||
264 | return AE_OK; | ||
265 | |||
258 | for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { | 266 | for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { |
259 | pnpacpi_parse_allocated_irqresource(res_table, | 267 | pnpacpi_parse_allocated_irqresource(res_table, |
260 | res->data.extended_irq.interrupts[i], | 268 | res->data.extended_irq.interrupts[i], |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index b154b3f52cbe..551f58e29810 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -346,7 +346,7 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node) | |||
346 | dev->flags = node->flags; | 346 | dev->flags = node->flags; |
347 | if (!(dev->flags & PNPBIOS_NO_CONFIG)) | 347 | if (!(dev->flags & PNPBIOS_NO_CONFIG)) |
348 | dev->capabilities |= PNP_CONFIGURABLE; | 348 | dev->capabilities |= PNP_CONFIGURABLE; |
349 | if (!(dev->flags & PNPBIOS_NO_DISABLE)) | 349 | if (!(dev->flags & PNPBIOS_NO_DISABLE) && pnpbios_is_dynamic(dev)) |
350 | dev->capabilities |= PNP_DISABLE; | 350 | dev->capabilities |= PNP_DISABLE; |
351 | dev->capabilities |= PNP_READ; | 351 | dev->capabilities |= PNP_READ; |
352 | if (pnpbios_is_dynamic(dev)) | 352 | if (pnpbios_is_dynamic(dev)) |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 4cd879cb9bdd..1140302ff11d 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -304,6 +304,7 @@ static int __init xpram_setup_sizes(unsigned long pages) | |||
304 | { | 304 | { |
305 | unsigned long mem_needed; | 305 | unsigned long mem_needed; |
306 | unsigned long mem_auto; | 306 | unsigned long mem_auto; |
307 | unsigned long long size; | ||
307 | int mem_auto_no; | 308 | int mem_auto_no; |
308 | int i; | 309 | int i; |
309 | 310 | ||
@@ -321,9 +322,19 @@ static int __init xpram_setup_sizes(unsigned long pages) | |||
321 | mem_needed = 0; | 322 | mem_needed = 0; |
322 | mem_auto_no = 0; | 323 | mem_auto_no = 0; |
323 | for (i = 0; i < xpram_devs; i++) { | 324 | for (i = 0; i < xpram_devs; i++) { |
324 | if (sizes[i]) | 325 | if (sizes[i]) { |
325 | xpram_sizes[i] = | 326 | size = simple_strtoull(sizes[i], &sizes[i], 0); |
326 | (memparse(sizes[i], &sizes[i]) + 3) & -4UL; | 327 | switch (sizes[i][0]) { |
328 | case 'g': | ||
329 | case 'G': | ||
330 | size <<= 20; | ||
331 | break; | ||
332 | case 'm': | ||
333 | case 'M': | ||
334 | size <<= 10; | ||
335 | } | ||
336 | xpram_sizes[i] = (size + 3) & -4UL; | ||
337 | } | ||
327 | if (xpram_sizes[i]) | 338 | if (xpram_sizes[i]) |
328 | mem_needed += xpram_sizes[i]; | 339 | mem_needed += xpram_sizes[i]; |
329 | else | 340 | else |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 95e285b2e25c..7a84014f2037 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -1106,10 +1106,10 @@ raw3270_delete_device(struct raw3270 *rp) | |||
1106 | 1106 | ||
1107 | /* Remove from device chain. */ | 1107 | /* Remove from device chain. */ |
1108 | mutex_lock(&raw3270_mutex); | 1108 | mutex_lock(&raw3270_mutex); |
1109 | if (rp->clttydev) | 1109 | if (rp->clttydev && !IS_ERR(rp->clttydev)) |
1110 | class_device_destroy(class3270, | 1110 | class_device_destroy(class3270, |
1111 | MKDEV(IBM_TTY3270_MAJOR, rp->minor)); | 1111 | MKDEV(IBM_TTY3270_MAJOR, rp->minor)); |
1112 | if (rp->cltubdev) | 1112 | if (rp->cltubdev && !IS_ERR(rp->cltubdev)) |
1113 | class_device_destroy(class3270, | 1113 | class_device_destroy(class3270, |
1114 | MKDEV(IBM_FS3270_MAJOR, rp->minor)); | 1114 | MKDEV(IBM_FS3270_MAJOR, rp->minor)); |
1115 | list_del_init(&rp->list); | 1115 | list_del_init(&rp->list); |
@@ -1173,21 +1173,37 @@ static struct attribute_group raw3270_attr_group = { | |||
1173 | .attrs = raw3270_attrs, | 1173 | .attrs = raw3270_attrs, |
1174 | }; | 1174 | }; |
1175 | 1175 | ||
1176 | static void | 1176 | static int raw3270_create_attributes(struct raw3270 *rp) |
1177 | raw3270_create_attributes(struct raw3270 *rp) | ||
1178 | { | 1177 | { |
1179 | //FIXME: check return code | 1178 | int rc; |
1180 | sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); | 1179 | |
1181 | rp->clttydev = | 1180 | rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); |
1182 | class_device_create(class3270, NULL, | 1181 | if (rc) |
1183 | MKDEV(IBM_TTY3270_MAJOR, rp->minor), | 1182 | goto out; |
1184 | &rp->cdev->dev, "tty%s", | 1183 | |
1185 | rp->cdev->dev.bus_id); | 1184 | rp->clttydev = class_device_create(class3270, NULL, |
1186 | rp->cltubdev = | 1185 | MKDEV(IBM_TTY3270_MAJOR, rp->minor), |
1187 | class_device_create(class3270, NULL, | 1186 | &rp->cdev->dev, "tty%s", |
1188 | MKDEV(IBM_FS3270_MAJOR, rp->minor), | 1187 | rp->cdev->dev.bus_id); |
1189 | &rp->cdev->dev, "tub%s", | 1188 | if (IS_ERR(rp->clttydev)) { |
1190 | rp->cdev->dev.bus_id); | 1189 | rc = PTR_ERR(rp->clttydev); |
1190 | goto out_ttydev; | ||
1191 | } | ||
1192 | |||
1193 | rp->cltubdev = class_device_create(class3270, NULL, | ||
1194 | MKDEV(IBM_FS3270_MAJOR, rp->minor), | ||
1195 | &rp->cdev->dev, "tub%s", | ||
1196 | rp->cdev->dev.bus_id); | ||
1197 | if (!IS_ERR(rp->cltubdev)) | ||
1198 | goto out; | ||
1199 | |||
1200 | rc = PTR_ERR(rp->cltubdev); | ||
1201 | class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); | ||
1202 | |||
1203 | out_ttydev: | ||
1204 | sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group); | ||
1205 | out: | ||
1206 | return rc; | ||
1191 | } | 1207 | } |
1192 | 1208 | ||
1193 | /* | 1209 | /* |
@@ -1255,7 +1271,9 @@ raw3270_set_online (struct ccw_device *cdev) | |||
1255 | rc = raw3270_reset_device(rp); | 1271 | rc = raw3270_reset_device(rp); |
1256 | if (rc) | 1272 | if (rc) |
1257 | goto failure; | 1273 | goto failure; |
1258 | raw3270_create_attributes(rp); | 1274 | rc = raw3270_create_attributes(rp); |
1275 | if (rc) | ||
1276 | goto failure; | ||
1259 | set_bit(RAW3270_FLAGS_READY, &rp->flags); | 1277 | set_bit(RAW3270_FLAGS_READY, &rp->flags); |
1260 | mutex_lock(&raw3270_mutex); | 1278 | mutex_lock(&raw3270_mutex); |
1261 | list_for_each_entry(np, &raw3270_notifier, list) | 1279 | list_for_each_entry(np, &raw3270_notifier, list) |
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index a5c68e60fcf4..643b6d078563 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c | |||
@@ -76,14 +76,22 @@ struct tape_class_device *register_tape_dev( | |||
76 | device, | 76 | device, |
77 | "%s", tcd->device_name | 77 | "%s", tcd->device_name |
78 | ); | 78 | ); |
79 | sysfs_create_link( | 79 | rc = PTR_ERR(tcd->class_device); |
80 | if (rc) | ||
81 | goto fail_with_cdev; | ||
82 | rc = sysfs_create_link( | ||
80 | &device->kobj, | 83 | &device->kobj, |
81 | &tcd->class_device->kobj, | 84 | &tcd->class_device->kobj, |
82 | tcd->mode_name | 85 | tcd->mode_name |
83 | ); | 86 | ); |
87 | if (rc) | ||
88 | goto fail_with_class_device; | ||
84 | 89 | ||
85 | return tcd; | 90 | return tcd; |
86 | 91 | ||
92 | fail_with_class_device: | ||
93 | class_device_destroy(tape_class, tcd->char_device->dev); | ||
94 | |||
87 | fail_with_cdev: | 95 | fail_with_cdev: |
88 | cdev_del(tcd->char_device); | 96 | cdev_del(tcd->char_device); |
89 | 97 | ||
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 122b4d8965c3..2826aed91043 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -543,20 +543,24 @@ int | |||
543 | tape_generic_probe(struct ccw_device *cdev) | 543 | tape_generic_probe(struct ccw_device *cdev) |
544 | { | 544 | { |
545 | struct tape_device *device; | 545 | struct tape_device *device; |
546 | int ret; | ||
546 | 547 | ||
547 | device = tape_alloc_device(); | 548 | device = tape_alloc_device(); |
548 | if (IS_ERR(device)) | 549 | if (IS_ERR(device)) |
549 | return -ENODEV; | 550 | return -ENODEV; |
550 | PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); | 551 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); |
552 | ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); | ||
553 | if (ret) { | ||
554 | tape_put_device(device); | ||
555 | PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id); | ||
556 | return ret; | ||
557 | } | ||
551 | cdev->dev.driver_data = device; | 558 | cdev->dev.driver_data = device; |
559 | cdev->handler = __tape_do_irq; | ||
552 | device->cdev = cdev; | 560 | device->cdev = cdev; |
553 | device->cdev_id = busid_to_int(cdev->dev.bus_id); | 561 | device->cdev_id = busid_to_int(cdev->dev.bus_id); |
554 | cdev->handler = __tape_do_irq; | 562 | PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); |
555 | 563 | return ret; | |
556 | ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); | ||
557 | sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); | ||
558 | |||
559 | return 0; | ||
560 | } | 564 | } |
561 | 565 | ||
562 | static inline void | 566 | static inline void |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index f26a2ee3aad8..3cba6c9fab11 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -152,7 +152,6 @@ ccwgroup_create(struct device *root, | |||
152 | struct ccwgroup_device *gdev; | 152 | struct ccwgroup_device *gdev; |
153 | int i; | 153 | int i; |
154 | int rc; | 154 | int rc; |
155 | int del_drvdata; | ||
156 | 155 | ||
157 | if (argc > 256) /* disallow dumb users */ | 156 | if (argc > 256) /* disallow dumb users */ |
158 | return -EINVAL; | 157 | return -EINVAL; |
@@ -163,7 +162,6 @@ ccwgroup_create(struct device *root, | |||
163 | 162 | ||
164 | atomic_set(&gdev->onoff, 0); | 163 | atomic_set(&gdev->onoff, 0); |
165 | 164 | ||
166 | del_drvdata = 0; | ||
167 | for (i = 0; i < argc; i++) { | 165 | for (i = 0; i < argc; i++) { |
168 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); | 166 | gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); |
169 | 167 | ||
@@ -180,10 +178,8 @@ ccwgroup_create(struct device *root, | |||
180 | rc = -EINVAL; | 178 | rc = -EINVAL; |
181 | goto free_dev; | 179 | goto free_dev; |
182 | } | 180 | } |
183 | } | ||
184 | for (i = 0; i < argc; i++) | ||
185 | gdev->cdev[i]->dev.driver_data = gdev; | 181 | gdev->cdev[i]->dev.driver_data = gdev; |
186 | del_drvdata = 1; | 182 | } |
187 | 183 | ||
188 | gdev->creator_id = creator_id; | 184 | gdev->creator_id = creator_id; |
189 | gdev->count = argc; | 185 | gdev->count = argc; |
@@ -226,9 +222,9 @@ error: | |||
226 | free_dev: | 222 | free_dev: |
227 | for (i = 0; i < argc; i++) | 223 | for (i = 0; i < argc; i++) |
228 | if (gdev->cdev[i]) { | 224 | if (gdev->cdev[i]) { |
229 | put_device(&gdev->cdev[i]->dev); | 225 | if (gdev->cdev[i]->dev.driver_data == gdev) |
230 | if (del_drvdata) | ||
231 | gdev->cdev[i]->dev.driver_data = NULL; | 226 | gdev->cdev[i]->dev.driver_data = NULL; |
227 | put_device(&gdev->cdev[i]->dev); | ||
232 | } | 228 | } |
233 | kfree(gdev); | 229 | kfree(gdev); |
234 | return rc; | 230 | return rc; |
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 0df3af1f08de..828b2d334f0a 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c | |||
@@ -1068,6 +1068,7 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, | |||
1068 | if (count) { | 1068 | if (count) { |
1069 | interval = cmb_data->last_update - | 1069 | interval = cmb_data->last_update - |
1070 | cdev->private->cmb_start_time; | 1070 | cdev->private->cmb_start_time; |
1071 | interval = (interval * 1000) >> 12; | ||
1071 | interval /= count; | 1072 | interval /= count; |
1072 | } else | 1073 | } else |
1073 | interval = -1; | 1074 | interval = -1; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index ac6e0c7e43d9..7a39e0b0386c 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -152,7 +152,8 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) | |||
152 | if (cdev->private->iretry) { | 152 | if (cdev->private->iretry) { |
153 | cdev->private->iretry--; | 153 | cdev->private->iretry--; |
154 | ret = cio_halt(sch); | 154 | ret = cio_halt(sch); |
155 | return (ret == 0) ? -EBUSY : ret; | 155 | if (ret != -EBUSY) |
156 | return (ret == 0) ? -EBUSY : ret; | ||
156 | } | 157 | } |
157 | /* halt io unsuccessful. */ | 158 | /* halt io unsuccessful. */ |
158 | cdev->private->iretry = 255; /* 255 clear retries. */ | 159 | cdev->private->iretry = 255; /* 255 clear retries. */ |
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 20c8eb16f464..8a4b58120146 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c | |||
@@ -2686,9 +2686,17 @@ static struct attribute_group ctc_attr_group = { | |||
2686 | static int | 2686 | static int |
2687 | ctc_add_attributes(struct device *dev) | 2687 | ctc_add_attributes(struct device *dev) |
2688 | { | 2688 | { |
2689 | device_create_file(dev, &dev_attr_loglevel); | 2689 | int rc; |
2690 | device_create_file(dev, &dev_attr_stats); | 2690 | |
2691 | return 0; | 2691 | rc = device_create_file(dev, &dev_attr_loglevel); |
2692 | if (rc) | ||
2693 | goto out; | ||
2694 | rc = device_create_file(dev, &dev_attr_stats); | ||
2695 | if (!rc) | ||
2696 | goto out; | ||
2697 | device_remove_file(dev, &dev_attr_loglevel); | ||
2698 | out: | ||
2699 | return rc; | ||
2692 | } | 2700 | } |
2693 | 2701 | ||
2694 | static void | 2702 | static void |
@@ -2901,7 +2909,12 @@ ctc_new_device(struct ccwgroup_device *cgdev) | |||
2901 | goto out; | 2909 | goto out; |
2902 | } | 2910 | } |
2903 | 2911 | ||
2904 | ctc_add_attributes(&cgdev->dev); | 2912 | if (ctc_add_attributes(&cgdev->dev)) { |
2913 | ctc_netdev_unregister(dev); | ||
2914 | dev->priv = NULL; | ||
2915 | ctc_free_netdevice(dev, 1); | ||
2916 | goto out; | ||
2917 | } | ||
2905 | 2918 | ||
2906 | strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name)); | 2919 | strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name)); |
2907 | 2920 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 103c41470bd2..5fff1f93973a 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -8451,10 +8451,11 @@ __qeth_reboot_event_card(struct device *dev, void *data) | |||
8451 | static int | 8451 | static int |
8452 | qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) | 8452 | qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) |
8453 | { | 8453 | { |
8454 | int ret; | ||
8454 | 8455 | ||
8455 | driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, | 8456 | ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, |
8456 | __qeth_reboot_event_card); | 8457 | __qeth_reboot_event_card); |
8457 | return NOTIFY_DONE; | 8458 | return ret ? NOTIFY_BAD : NOTIFY_DONE; |
8458 | } | 8459 | } |
8459 | 8460 | ||
8460 | 8461 | ||
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index 16b59773c0bb..935952ef88f1 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c | |||
@@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus) | |||
233 | sbus->ofdev.node = dp; | 233 | sbus->ofdev.node = dp; |
234 | sbus->ofdev.dev.parent = NULL; | 234 | sbus->ofdev.dev.parent = NULL; |
235 | sbus->ofdev.dev.bus = &sbus_bus_type; | 235 | sbus->ofdev.dev.bus = &sbus_bus_type; |
236 | strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name); | 236 | sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); |
237 | 237 | ||
238 | if (of_device_register(&sbus->ofdev) != 0) | 238 | if (of_device_register(&sbus->ofdev) != 0) |
239 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | 239 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", |
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index c690c2b89e41..acf292736b4e 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c | |||
@@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) { | |||
3451 | for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, | 3451 | for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, |
3452 | cmd_dataout += 4, ++i) { | 3452 | cmd_dataout += 4, ++i) { |
3453 | u32 vbuf = cmd->use_sg | 3453 | u32 vbuf = cmd->use_sg |
3454 | ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+ | 3454 | ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+ |
3455 | ((struct scatterlist *)cmd->buffer)[i].offset | 3455 | ((struct scatterlist *)cmd->request_buffer)[i].offset |
3456 | : (u32)(cmd->request_buffer); | 3456 | : (u32)(cmd->request_buffer); |
3457 | u32 bbuf = virt_to_bus((void *)vbuf); | 3457 | u32 bbuf = virt_to_bus((void *)vbuf); |
3458 | u32 count = cmd->use_sg ? | 3458 | u32 count = cmd->use_sg ? |
3459 | ((struct scatterlist *)cmd->buffer)[i].length : | 3459 | ((struct scatterlist *)cmd->request_buffer)[i].length : |
3460 | cmd->request_bufflen; | 3460 | cmd->request_bufflen; |
3461 | 3461 | ||
3462 | /* | 3462 | /* |
@@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { | |||
5417 | 5417 | ||
5418 | if ((buffers = cmd->use_sg)) { | 5418 | if ((buffers = cmd->use_sg)) { |
5419 | for (offset = 0, | 5419 | for (offset = 0, |
5420 | segment = (struct scatterlist *) cmd->buffer; | 5420 | segment = (struct scatterlist *) cmd->request_buffer; |
5421 | buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && | 5421 | buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && |
5422 | (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length))))); | 5422 | (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length))))); |
5423 | --buffers, offset += segment->length, ++segment) | 5423 | --buffers, offset += segment->length, ++segment) |
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 8a4659e94105..bdc6bb262bce 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c | |||
@@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) | |||
911 | sp->SCp.ptr = | 911 | sp->SCp.ptr = |
912 | (char *) virt_to_phys(sp->request_buffer); | 912 | (char *) virt_to_phys(sp->request_buffer); |
913 | } else { | 913 | } else { |
914 | sp->SCp.buffer = (struct scatterlist *) sp->buffer; | 914 | sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; |
915 | sp->SCp.buffers_residual = sp->use_sg - 1; | 915 | sp->SCp.buffers_residual = sp->use_sg - 1; |
916 | sp->SCp.this_residual = sp->SCp.buffer->length; | 916 | sp->SCp.this_residual = sp->SCp.buffer->length; |
917 | if (esp->dma_mmu_get_scsi_sgl) | 917 | if (esp->dma_mmu_get_scsi_sgl) |
@@ -2152,29 +2152,23 @@ static int esp_do_data_finale(struct NCR_ESP *esp, | |||
2152 | */ | 2152 | */ |
2153 | static int esp_should_clear_sync(Scsi_Cmnd *sp) | 2153 | static int esp_should_clear_sync(Scsi_Cmnd *sp) |
2154 | { | 2154 | { |
2155 | unchar cmd1 = sp->cmnd[0]; | 2155 | unchar cmd = sp->cmnd[0]; |
2156 | unchar cmd2 = sp->data_cmnd[0]; | ||
2157 | 2156 | ||
2158 | /* These cases are for spinning up a disk and | 2157 | /* These cases are for spinning up a disk and |
2159 | * waiting for that spinup to complete. | 2158 | * waiting for that spinup to complete. |
2160 | */ | 2159 | */ |
2161 | if(cmd1 == START_STOP || | 2160 | if(cmd == START_STOP) |
2162 | cmd2 == START_STOP) | ||
2163 | return 0; | 2161 | return 0; |
2164 | 2162 | ||
2165 | if(cmd1 == TEST_UNIT_READY || | 2163 | if(cmd == TEST_UNIT_READY) |
2166 | cmd2 == TEST_UNIT_READY) | ||
2167 | return 0; | 2164 | return 0; |
2168 | 2165 | ||
2169 | /* One more special case for SCSI tape drives, | 2166 | /* One more special case for SCSI tape drives, |
2170 | * this is what is used to probe the device for | 2167 | * this is what is used to probe the device for |
2171 | * completion of a rewind or tape load operation. | 2168 | * completion of a rewind or tape load operation. |
2172 | */ | 2169 | */ |
2173 | if(sp->device->type == TYPE_TAPE) { | 2170 | if(sp->device->type == TYPE_TAPE && cmd == MODE_SENSE) |
2174 | if(cmd1 == MODE_SENSE || | 2171 | return 0; |
2175 | cmd2 == MODE_SENSE) | ||
2176 | return 0; | ||
2177 | } | ||
2178 | 2172 | ||
2179 | return 1; | 2173 | return 1; |
2180 | } | 2174 | } |
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index a06f547e87f7..d05681f9d81a 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c | |||
@@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver"); | |||
114 | MODULE_LICENSE("GPL"); | 114 | MODULE_LICENSE("GPL"); |
115 | module_param(NCR_D700, charp, 0); | 115 | module_param(NCR_D700, charp, 0); |
116 | 116 | ||
117 | static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = | 117 | static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = |
118 | { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 }; | 118 | { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 }; |
119 | 119 | ||
120 | #ifdef MODULE | 120 | #ifdef MODULE |
@@ -173,7 +173,7 @@ struct NCR_D700_private { | |||
173 | char pad; | 173 | char pad; |
174 | }; | 174 | }; |
175 | 175 | ||
176 | static int | 176 | static int __devinit |
177 | NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, | 177 | NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, |
178 | int slot, u32 region, int differential) | 178 | int slot, u32 region, int differential) |
179 | { | 179 | { |
@@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs) | |||
243 | * essentially connectecd to the MCA bus independently, it is easier | 243 | * essentially connectecd to the MCA bus independently, it is easier |
244 | * to set them up as two separate host adapters, rather than one | 244 | * to set them up as two separate host adapters, rather than one |
245 | * adapter with two channels */ | 245 | * adapter with two channels */ |
246 | static int | 246 | static int __devinit |
247 | NCR_D700_probe(struct device *dev) | 247 | NCR_D700_probe(struct device *dev) |
248 | { | 248 | { |
249 | struct NCR_D700_private *p; | 249 | struct NCR_D700_private *p; |
@@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev) | |||
329 | for (i = 0; i < 2; i++) { | 329 | for (i = 0; i < 2; i++) { |
330 | int err; | 330 | int err; |
331 | 331 | ||
332 | if ((err = NCR_D700_probe_one(p, i, slot, irq, | 332 | if ((err = NCR_D700_probe_one(p, i, irq, slot, |
333 | offset_addr + (0x80 * i), | 333 | offset_addr + (0x80 * i), |
334 | differential)) != 0) | 334 | differential)) != 0) |
335 | printk("D700: SIOP%d: probe failed, error = %d\n", | 335 | printk("D700: SIOP%d: probe failed, error = %d\n", |
@@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev) | |||
349 | return 0; | 349 | return 0; |
350 | } | 350 | } |
351 | 351 | ||
352 | static void | 352 | static void __devexit |
353 | NCR_D700_remove_one(struct Scsi_Host *host) | 353 | NCR_D700_remove_one(struct Scsi_Host *host) |
354 | { | 354 | { |
355 | scsi_remove_host(host); | 355 | scsi_remove_host(host); |
@@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host) | |||
359 | release_region(host->base, 64); | 359 | release_region(host->base, 64); |
360 | } | 360 | } |
361 | 361 | ||
362 | static int | 362 | static int __devexit |
363 | NCR_D700_remove(struct device *dev) | 363 | NCR_D700_remove(struct device *dev) |
364 | { | 364 | { |
365 | struct NCR_D700_private *p = dev_get_drvdata(dev); | 365 | struct NCR_D700_private *p = dev_get_drvdata(dev); |
@@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = { | |||
380 | .name = "NCR_D700", | 380 | .name = "NCR_D700", |
381 | .bus = &mca_bus_type, | 381 | .bus = &mca_bus_type, |
382 | .probe = NCR_D700_probe, | 382 | .probe = NCR_D700_probe, |
383 | .remove = NCR_D700_remove, | 383 | .remove = __devexit_p(NCR_D700_remove), |
384 | }, | 384 | }, |
385 | }; | 385 | }; |
386 | 386 | ||
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 36e63f82d9f8..f974869ea323 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -551,6 +551,11 @@ struct aha152x_hostdata { | |||
551 | struct aha152x_scdata { | 551 | struct aha152x_scdata { |
552 | Scsi_Cmnd *next; /* next sc in queue */ | 552 | Scsi_Cmnd *next; /* next sc in queue */ |
553 | struct semaphore *sem; /* semaphore to block on */ | 553 | struct semaphore *sem; /* semaphore to block on */ |
554 | unsigned char cmd_len; | ||
555 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
556 | unsigned short use_sg; | ||
557 | unsigned request_bufflen; | ||
558 | void *request_buffer; | ||
554 | }; | 559 | }; |
555 | 560 | ||
556 | 561 | ||
@@ -1006,11 +1011,20 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p | |||
1006 | return FAILED; | 1011 | return FAILED; |
1007 | } | 1012 | } |
1008 | } else { | 1013 | } else { |
1014 | struct aha152x_scdata *sc; | ||
1015 | |||
1009 | SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); | 1016 | SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); |
1010 | if(SCpnt->host_scribble==0) { | 1017 | if(SCpnt->host_scribble==0) { |
1011 | printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); | 1018 | printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); |
1012 | return FAILED; | 1019 | return FAILED; |
1013 | } | 1020 | } |
1021 | |||
1022 | sc = SCDATA(SCpnt); | ||
1023 | memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd)); | ||
1024 | sc->request_buffer = SCpnt->request_buffer; | ||
1025 | sc->request_bufflen = SCpnt->request_bufflen; | ||
1026 | sc->use_sg = SCpnt->use_sg; | ||
1027 | sc->cmd_len = SCpnt->cmd_len; | ||
1014 | } | 1028 | } |
1015 | 1029 | ||
1016 | SCNEXT(SCpnt) = NULL; | 1030 | SCNEXT(SCpnt) = NULL; |
@@ -1165,6 +1179,10 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) | |||
1165 | DECLARE_MUTEX_LOCKED(sem); | 1179 | DECLARE_MUTEX_LOCKED(sem); |
1166 | struct timer_list timer; | 1180 | struct timer_list timer; |
1167 | int ret, issued, disconnected; | 1181 | int ret, issued, disconnected; |
1182 | unsigned char old_cmd_len = SCpnt->cmd_len; | ||
1183 | unsigned short old_use_sg = SCpnt->use_sg; | ||
1184 | void *old_buffer = SCpnt->request_buffer; | ||
1185 | unsigned old_bufflen = SCpnt->request_bufflen; | ||
1168 | unsigned long flags; | 1186 | unsigned long flags; |
1169 | 1187 | ||
1170 | #if defined(AHA152X_DEBUG) | 1188 | #if defined(AHA152X_DEBUG) |
@@ -1198,11 +1216,11 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) | |||
1198 | add_timer(&timer); | 1216 | add_timer(&timer); |
1199 | down(&sem); | 1217 | down(&sem); |
1200 | del_timer(&timer); | 1218 | del_timer(&timer); |
1201 | 1219 | ||
1202 | SCpnt->cmd_len = SCpnt->old_cmd_len; | 1220 | SCpnt->cmd_len = old_cmd_len; |
1203 | SCpnt->use_sg = SCpnt->old_use_sg; | 1221 | SCpnt->use_sg = old_use_sg; |
1204 | SCpnt->request_buffer = SCpnt->buffer; | 1222 | SCpnt->request_buffer = old_buffer; |
1205 | SCpnt->request_bufflen = SCpnt->bufflen; | 1223 | SCpnt->request_bufflen = old_bufflen; |
1206 | 1224 | ||
1207 | DO_LOCK(flags); | 1225 | DO_LOCK(flags); |
1208 | 1226 | ||
@@ -1565,6 +1583,9 @@ static void busfree_run(struct Scsi_Host *shpnt) | |||
1565 | #endif | 1583 | #endif |
1566 | 1584 | ||
1567 | if(DONE_SC->SCp.phase & check_condition) { | 1585 | if(DONE_SC->SCp.phase & check_condition) { |
1586 | struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC; | ||
1587 | struct aha152x_scdata *sc = SCDATA(cmd); | ||
1588 | |||
1568 | #if 0 | 1589 | #if 0 |
1569 | if(HOSTDATA(shpnt)->debug & debug_eh) { | 1590 | if(HOSTDATA(shpnt)->debug & debug_eh) { |
1570 | printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC)); | 1591 | printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC)); |
@@ -1573,13 +1594,13 @@ static void busfree_run(struct Scsi_Host *shpnt) | |||
1573 | #endif | 1594 | #endif |
1574 | 1595 | ||
1575 | /* restore old command */ | 1596 | /* restore old command */ |
1576 | memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd)); | 1597 | memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd)); |
1577 | DONE_SC->request_buffer = DONE_SC->buffer; | 1598 | cmd->request_buffer = sc->request_buffer; |
1578 | DONE_SC->request_bufflen = DONE_SC->bufflen; | 1599 | cmd->request_bufflen = sc->request_bufflen; |
1579 | DONE_SC->use_sg = DONE_SC->old_use_sg; | 1600 | cmd->use_sg = sc->use_sg; |
1580 | DONE_SC->cmd_len = DONE_SC->old_cmd_len; | 1601 | cmd->cmd_len = sc->cmd_len; |
1581 | 1602 | ||
1582 | DONE_SC->SCp.Status = 0x02; | 1603 | cmd->SCp.Status = 0x02; |
1583 | 1604 | ||
1584 | HOSTDATA(shpnt)->commands--; | 1605 | HOSTDATA(shpnt)->commands--; |
1585 | if (!HOSTDATA(shpnt)->commands) | 1606 | if (!HOSTDATA(shpnt)->commands) |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 77e7202a0eba..68fd7667a082 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -92,7 +92,9 @@ enum { | |||
92 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | 92 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ |
93 | 93 | ||
94 | /* HOST_CAP bits */ | 94 | /* HOST_CAP bits */ |
95 | HOST_CAP_SSC = (1 << 14), /* Slumber capable */ | ||
95 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ | 96 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ |
97 | HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ | ||
96 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ | 98 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ |
97 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | 99 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ |
98 | 100 | ||
@@ -155,6 +157,7 @@ enum { | |||
155 | PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ | 157 | PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ |
156 | PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ | 158 | PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ |
157 | 159 | ||
160 | PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */ | ||
158 | PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ | 161 | PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ |
159 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ | 162 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ |
160 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ | 163 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ |
@@ -212,6 +215,10 @@ static void ahci_freeze(struct ata_port *ap); | |||
212 | static void ahci_thaw(struct ata_port *ap); | 215 | static void ahci_thaw(struct ata_port *ap); |
213 | static void ahci_error_handler(struct ata_port *ap); | 216 | static void ahci_error_handler(struct ata_port *ap); |
214 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 217 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
218 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); | ||
219 | static int ahci_port_resume(struct ata_port *ap); | ||
220 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
221 | static int ahci_pci_device_resume(struct pci_dev *pdev); | ||
215 | static void ahci_remove_one (struct pci_dev *pdev); | 222 | static void ahci_remove_one (struct pci_dev *pdev); |
216 | 223 | ||
217 | static struct scsi_host_template ahci_sht = { | 224 | static struct scsi_host_template ahci_sht = { |
@@ -231,6 +238,8 @@ static struct scsi_host_template ahci_sht = { | |||
231 | .slave_configure = ata_scsi_slave_config, | 238 | .slave_configure = ata_scsi_slave_config, |
232 | .slave_destroy = ata_scsi_slave_destroy, | 239 | .slave_destroy = ata_scsi_slave_destroy, |
233 | .bios_param = ata_std_bios_param, | 240 | .bios_param = ata_std_bios_param, |
241 | .suspend = ata_scsi_device_suspend, | ||
242 | .resume = ata_scsi_device_resume, | ||
234 | }; | 243 | }; |
235 | 244 | ||
236 | static const struct ata_port_operations ahci_ops = { | 245 | static const struct ata_port_operations ahci_ops = { |
@@ -257,6 +266,9 @@ static const struct ata_port_operations ahci_ops = { | |||
257 | .error_handler = ahci_error_handler, | 266 | .error_handler = ahci_error_handler, |
258 | .post_internal_cmd = ahci_post_internal_cmd, | 267 | .post_internal_cmd = ahci_post_internal_cmd, |
259 | 268 | ||
269 | .port_suspend = ahci_port_suspend, | ||
270 | .port_resume = ahci_port_resume, | ||
271 | |||
260 | .port_start = ahci_port_start, | 272 | .port_start = ahci_port_start, |
261 | .port_stop = ahci_port_stop, | 273 | .port_stop = ahci_port_stop, |
262 | }; | 274 | }; |
@@ -350,6 +362,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
350 | { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 362 | { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
351 | board_ahci }, /* MCP65 */ | 363 | board_ahci }, /* MCP65 */ |
352 | 364 | ||
365 | /* SiS */ | ||
366 | { PCI_VENDOR_ID_SI, 0x1184, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
367 | board_ahci }, /* SiS 966 */ | ||
368 | { PCI_VENDOR_ID_SI, 0x1185, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
369 | board_ahci }, /* SiS 966 */ | ||
370 | { PCI_VENDOR_ID_SI, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
371 | board_ahci }, /* SiS 968 */ | ||
372 | |||
353 | { } /* terminate list */ | 373 | { } /* terminate list */ |
354 | }; | 374 | }; |
355 | 375 | ||
@@ -358,6 +378,8 @@ static struct pci_driver ahci_pci_driver = { | |||
358 | .name = DRV_NAME, | 378 | .name = DRV_NAME, |
359 | .id_table = ahci_pci_tbl, | 379 | .id_table = ahci_pci_tbl, |
360 | .probe = ahci_init_one, | 380 | .probe = ahci_init_one, |
381 | .suspend = ahci_pci_device_suspend, | ||
382 | .resume = ahci_pci_device_resume, | ||
361 | .remove = ahci_remove_one, | 383 | .remove = ahci_remove_one, |
362 | }; | 384 | }; |
363 | 385 | ||
@@ -372,177 +394,288 @@ static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int por | |||
372 | return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); | 394 | return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); |
373 | } | 395 | } |
374 | 396 | ||
375 | static int ahci_port_start(struct ata_port *ap) | 397 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) |
376 | { | 398 | { |
377 | struct device *dev = ap->host_set->dev; | 399 | unsigned int sc_reg; |
378 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
379 | struct ahci_port_priv *pp; | ||
380 | void __iomem *mmio = ap->host_set->mmio_base; | ||
381 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
382 | void *mem; | ||
383 | dma_addr_t mem_dma; | ||
384 | int rc; | ||
385 | |||
386 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | ||
387 | if (!pp) | ||
388 | return -ENOMEM; | ||
389 | memset(pp, 0, sizeof(*pp)); | ||
390 | 400 | ||
391 | rc = ata_pad_alloc(ap, dev); | 401 | switch (sc_reg_in) { |
392 | if (rc) { | 402 | case SCR_STATUS: sc_reg = 0; break; |
393 | kfree(pp); | 403 | case SCR_CONTROL: sc_reg = 1; break; |
394 | return rc; | 404 | case SCR_ERROR: sc_reg = 2; break; |
405 | case SCR_ACTIVE: sc_reg = 3; break; | ||
406 | default: | ||
407 | return 0xffffffffU; | ||
395 | } | 408 | } |
396 | 409 | ||
397 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | 410 | return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
398 | if (!mem) { | 411 | } |
399 | ata_pad_free(ap, dev); | ||
400 | kfree(pp); | ||
401 | return -ENOMEM; | ||
402 | } | ||
403 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | ||
404 | 412 | ||
405 | /* | ||
406 | * First item in chunk of DMA memory: 32-slot command table, | ||
407 | * 32 bytes each in size | ||
408 | */ | ||
409 | pp->cmd_slot = mem; | ||
410 | pp->cmd_slot_dma = mem_dma; | ||
411 | 413 | ||
412 | mem += AHCI_CMD_SLOT_SZ; | 414 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, |
413 | mem_dma += AHCI_CMD_SLOT_SZ; | 415 | u32 val) |
416 | { | ||
417 | unsigned int sc_reg; | ||
414 | 418 | ||
415 | /* | 419 | switch (sc_reg_in) { |
416 | * Second item: Received-FIS area | 420 | case SCR_STATUS: sc_reg = 0; break; |
417 | */ | 421 | case SCR_CONTROL: sc_reg = 1; break; |
418 | pp->rx_fis = mem; | 422 | case SCR_ERROR: sc_reg = 2; break; |
419 | pp->rx_fis_dma = mem_dma; | 423 | case SCR_ACTIVE: sc_reg = 3; break; |
424 | default: | ||
425 | return; | ||
426 | } | ||
420 | 427 | ||
421 | mem += AHCI_RX_FIS_SZ; | 428 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
422 | mem_dma += AHCI_RX_FIS_SZ; | 429 | } |
423 | 430 | ||
424 | /* | 431 | static void ahci_start_engine(void __iomem *port_mmio) |
425 | * Third item: data area for storing a single command | 432 | { |
426 | * and its scatter-gather table | 433 | u32 tmp; |
427 | */ | ||
428 | pp->cmd_tbl = mem; | ||
429 | pp->cmd_tbl_dma = mem_dma; | ||
430 | 434 | ||
431 | ap->private_data = pp; | 435 | /* start DMA */ |
436 | tmp = readl(port_mmio + PORT_CMD); | ||
437 | tmp |= PORT_CMD_START; | ||
438 | writel(tmp, port_mmio + PORT_CMD); | ||
439 | readl(port_mmio + PORT_CMD); /* flush */ | ||
440 | } | ||
432 | 441 | ||
433 | if (hpriv->cap & HOST_CAP_64) | 442 | static int ahci_stop_engine(void __iomem *port_mmio) |
434 | writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); | 443 | { |
435 | writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); | 444 | u32 tmp; |
436 | readl(port_mmio + PORT_LST_ADDR); /* flush */ | ||
437 | 445 | ||
438 | if (hpriv->cap & HOST_CAP_64) | 446 | tmp = readl(port_mmio + PORT_CMD); |
439 | writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); | ||
440 | writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); | ||
441 | readl(port_mmio + PORT_FIS_ADDR); /* flush */ | ||
442 | 447 | ||
443 | writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | | 448 | /* check if the HBA is idle */ |
444 | PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | | 449 | if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) |
445 | PORT_CMD_START, port_mmio + PORT_CMD); | 450 | return 0; |
446 | readl(port_mmio + PORT_CMD); /* flush */ | 451 | |
452 | /* setting HBA to idle */ | ||
453 | tmp &= ~PORT_CMD_START; | ||
454 | writel(tmp, port_mmio + PORT_CMD); | ||
455 | |||
456 | /* wait for engine to stop. This could be as long as 500 msec */ | ||
457 | tmp = ata_wait_register(port_mmio + PORT_CMD, | ||
458 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | ||
459 | if (tmp & PORT_CMD_LIST_ON) | ||
460 | return -EIO; | ||
447 | 461 | ||
448 | return 0; | 462 | return 0; |
449 | } | 463 | } |
450 | 464 | ||
465 | static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap, | ||
466 | dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) | ||
467 | { | ||
468 | u32 tmp; | ||
451 | 469 | ||
452 | static void ahci_port_stop(struct ata_port *ap) | 470 | /* set FIS registers */ |
471 | if (cap & HOST_CAP_64) | ||
472 | writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); | ||
473 | writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); | ||
474 | |||
475 | if (cap & HOST_CAP_64) | ||
476 | writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); | ||
477 | writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); | ||
478 | |||
479 | /* enable FIS reception */ | ||
480 | tmp = readl(port_mmio + PORT_CMD); | ||
481 | tmp |= PORT_CMD_FIS_RX; | ||
482 | writel(tmp, port_mmio + PORT_CMD); | ||
483 | |||
484 | /* flush */ | ||
485 | readl(port_mmio + PORT_CMD); | ||
486 | } | ||
487 | |||
488 | static int ahci_stop_fis_rx(void __iomem *port_mmio) | ||
453 | { | 489 | { |
454 | struct device *dev = ap->host_set->dev; | ||
455 | struct ahci_port_priv *pp = ap->private_data; | ||
456 | void __iomem *mmio = ap->host_set->mmio_base; | ||
457 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
458 | u32 tmp; | 490 | u32 tmp; |
459 | 491 | ||
492 | /* disable FIS reception */ | ||
460 | tmp = readl(port_mmio + PORT_CMD); | 493 | tmp = readl(port_mmio + PORT_CMD); |
461 | tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); | 494 | tmp &= ~PORT_CMD_FIS_RX; |
462 | writel(tmp, port_mmio + PORT_CMD); | 495 | writel(tmp, port_mmio + PORT_CMD); |
463 | readl(port_mmio + PORT_CMD); /* flush */ | ||
464 | 496 | ||
465 | /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so | 497 | /* wait for completion, spec says 500ms, give it 1000 */ |
466 | * this is slightly incorrect. | 498 | tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, |
467 | */ | 499 | PORT_CMD_FIS_ON, 10, 1000); |
468 | msleep(500); | 500 | if (tmp & PORT_CMD_FIS_ON) |
501 | return -EBUSY; | ||
469 | 502 | ||
470 | ap->private_data = NULL; | 503 | return 0; |
471 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | ||
472 | pp->cmd_slot, pp->cmd_slot_dma); | ||
473 | ata_pad_free(ap, dev); | ||
474 | kfree(pp); | ||
475 | } | 504 | } |
476 | 505 | ||
477 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) | 506 | static void ahci_power_up(void __iomem *port_mmio, u32 cap) |
478 | { | 507 | { |
479 | unsigned int sc_reg; | 508 | u32 cmd; |
480 | 509 | ||
481 | switch (sc_reg_in) { | 510 | cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; |
482 | case SCR_STATUS: sc_reg = 0; break; | 511 | |
483 | case SCR_CONTROL: sc_reg = 1; break; | 512 | /* spin up device */ |
484 | case SCR_ERROR: sc_reg = 2; break; | 513 | if (cap & HOST_CAP_SSS) { |
485 | case SCR_ACTIVE: sc_reg = 3; break; | 514 | cmd |= PORT_CMD_SPIN_UP; |
486 | default: | 515 | writel(cmd, port_mmio + PORT_CMD); |
487 | return 0xffffffffU; | ||
488 | } | 516 | } |
489 | 517 | ||
490 | return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 518 | /* wake up link */ |
519 | writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); | ||
491 | } | 520 | } |
492 | 521 | ||
522 | static void ahci_power_down(void __iomem *port_mmio, u32 cap) | ||
523 | { | ||
524 | u32 cmd, scontrol; | ||
493 | 525 | ||
494 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, | 526 | cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; |
495 | u32 val) | 527 | |
528 | if (cap & HOST_CAP_SSC) { | ||
529 | /* enable transitions to slumber mode */ | ||
530 | scontrol = readl(port_mmio + PORT_SCR_CTL); | ||
531 | if ((scontrol & 0x0f00) > 0x100) { | ||
532 | scontrol &= ~0xf00; | ||
533 | writel(scontrol, port_mmio + PORT_SCR_CTL); | ||
534 | } | ||
535 | |||
536 | /* put device into slumber mode */ | ||
537 | writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); | ||
538 | |||
539 | /* wait for the transition to complete */ | ||
540 | ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, | ||
541 | PORT_CMD_ICC_SLUMBER, 1, 50); | ||
542 | } | ||
543 | |||
544 | /* put device into listen mode */ | ||
545 | if (cap & HOST_CAP_SSS) { | ||
546 | /* first set PxSCTL.DET to 0 */ | ||
547 | scontrol = readl(port_mmio + PORT_SCR_CTL); | ||
548 | scontrol &= ~0xf; | ||
549 | writel(scontrol, port_mmio + PORT_SCR_CTL); | ||
550 | |||
551 | /* then set PxCMD.SUD to 0 */ | ||
552 | cmd &= ~PORT_CMD_SPIN_UP; | ||
553 | writel(cmd, port_mmio + PORT_CMD); | ||
554 | } | ||
555 | } | ||
556 | |||
557 | static void ahci_init_port(void __iomem *port_mmio, u32 cap, | ||
558 | dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) | ||
496 | { | 559 | { |
497 | unsigned int sc_reg; | 560 | /* power up */ |
561 | ahci_power_up(port_mmio, cap); | ||
498 | 562 | ||
499 | switch (sc_reg_in) { | 563 | /* enable FIS reception */ |
500 | case SCR_STATUS: sc_reg = 0; break; | 564 | ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); |
501 | case SCR_CONTROL: sc_reg = 1; break; | 565 | |
502 | case SCR_ERROR: sc_reg = 2; break; | 566 | /* enable DMA */ |
503 | case SCR_ACTIVE: sc_reg = 3; break; | 567 | ahci_start_engine(port_mmio); |
504 | default: | 568 | } |
505 | return; | 569 | |
570 | static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) | ||
571 | { | ||
572 | int rc; | ||
573 | |||
574 | /* disable DMA */ | ||
575 | rc = ahci_stop_engine(port_mmio); | ||
576 | if (rc) { | ||
577 | *emsg = "failed to stop engine"; | ||
578 | return rc; | ||
506 | } | 579 | } |
507 | 580 | ||
508 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 581 | /* disable FIS reception */ |
582 | rc = ahci_stop_fis_rx(port_mmio); | ||
583 | if (rc) { | ||
584 | *emsg = "failed stop FIS RX"; | ||
585 | return rc; | ||
586 | } | ||
587 | |||
588 | /* put device into slumber mode */ | ||
589 | ahci_power_down(port_mmio, cap); | ||
590 | |||
591 | return 0; | ||
509 | } | 592 | } |
510 | 593 | ||
511 | static int ahci_stop_engine(struct ata_port *ap) | 594 | static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) |
512 | { | 595 | { |
513 | void __iomem *mmio = ap->host_set->mmio_base; | 596 | u32 cap_save, tmp; |
514 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
515 | int work; | ||
516 | u32 tmp; | ||
517 | 597 | ||
518 | tmp = readl(port_mmio + PORT_CMD); | 598 | cap_save = readl(mmio + HOST_CAP); |
519 | tmp &= ~PORT_CMD_START; | 599 | cap_save &= ( (1<<28) | (1<<17) ); |
520 | writel(tmp, port_mmio + PORT_CMD); | 600 | cap_save |= (1 << 27); |
521 | 601 | ||
522 | /* wait for engine to stop. TODO: this could be | 602 | /* global controller reset */ |
523 | * as long as 500 msec | 603 | tmp = readl(mmio + HOST_CTL); |
604 | if ((tmp & HOST_RESET) == 0) { | ||
605 | writel(tmp | HOST_RESET, mmio + HOST_CTL); | ||
606 | readl(mmio + HOST_CTL); /* flush */ | ||
607 | } | ||
608 | |||
609 | /* reset must complete within 1 second, or | ||
610 | * the hardware should be considered fried. | ||
524 | */ | 611 | */ |
525 | work = 1000; | 612 | ssleep(1); |
526 | while (work-- > 0) { | 613 | |
527 | tmp = readl(port_mmio + PORT_CMD); | 614 | tmp = readl(mmio + HOST_CTL); |
528 | if ((tmp & PORT_CMD_LIST_ON) == 0) | 615 | if (tmp & HOST_RESET) { |
529 | return 0; | 616 | dev_printk(KERN_ERR, &pdev->dev, |
530 | udelay(10); | 617 | "controller reset failed (0x%x)\n", tmp); |
618 | return -EIO; | ||
619 | } | ||
620 | |||
621 | writel(HOST_AHCI_EN, mmio + HOST_CTL); | ||
622 | (void) readl(mmio + HOST_CTL); /* flush */ | ||
623 | writel(cap_save, mmio + HOST_CAP); | ||
624 | writel(0xf, mmio + HOST_PORTS_IMPL); | ||
625 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | ||
626 | |||
627 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | ||
628 | u16 tmp16; | ||
629 | |||
630 | /* configure PCS */ | ||
631 | pci_read_config_word(pdev, 0x92, &tmp16); | ||
632 | tmp16 |= 0xf; | ||
633 | pci_write_config_word(pdev, 0x92, tmp16); | ||
531 | } | 634 | } |
532 | 635 | ||
533 | return -EIO; | 636 | return 0; |
534 | } | 637 | } |
535 | 638 | ||
536 | static void ahci_start_engine(struct ata_port *ap) | 639 | static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, |
640 | int n_ports, u32 cap) | ||
537 | { | 641 | { |
538 | void __iomem *mmio = ap->host_set->mmio_base; | 642 | int i, rc; |
539 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
540 | u32 tmp; | 643 | u32 tmp; |
541 | 644 | ||
542 | tmp = readl(port_mmio + PORT_CMD); | 645 | for (i = 0; i < n_ports; i++) { |
543 | tmp |= PORT_CMD_START; | 646 | void __iomem *port_mmio = ahci_port_base(mmio, i); |
544 | writel(tmp, port_mmio + PORT_CMD); | 647 | const char *emsg = NULL; |
545 | readl(port_mmio + PORT_CMD); /* flush */ | 648 | |
649 | #if 0 /* BIOSen initialize this incorrectly */ | ||
650 | if (!(hpriv->port_map & (1 << i))) | ||
651 | continue; | ||
652 | #endif | ||
653 | |||
654 | /* make sure port is not active */ | ||
655 | rc = ahci_deinit_port(port_mmio, cap, &emsg); | ||
656 | if (rc) | ||
657 | dev_printk(KERN_WARNING, &pdev->dev, | ||
658 | "%s (%d)\n", emsg, rc); | ||
659 | |||
660 | /* clear SError */ | ||
661 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
662 | VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); | ||
663 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
664 | |||
665 | /* clear port IRQ */ | ||
666 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
667 | VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); | ||
668 | if (tmp) | ||
669 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
670 | |||
671 | writel(1 << i, mmio + HOST_IRQ_STAT); | ||
672 | } | ||
673 | |||
674 | tmp = readl(mmio + HOST_CTL); | ||
675 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
676 | writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); | ||
677 | tmp = readl(mmio + HOST_CTL); | ||
678 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
546 | } | 679 | } |
547 | 680 | ||
548 | static unsigned int ahci_dev_classify(struct ata_port *ap) | 681 | static unsigned int ahci_dev_classify(struct ata_port *ap) |
@@ -626,7 +759,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
626 | } | 759 | } |
627 | 760 | ||
628 | /* prepare for SRST (AHCI-1.1 10.4.1) */ | 761 | /* prepare for SRST (AHCI-1.1 10.4.1) */ |
629 | rc = ahci_stop_engine(ap); | 762 | rc = ahci_stop_engine(port_mmio); |
630 | if (rc) { | 763 | if (rc) { |
631 | reason = "failed to stop engine"; | 764 | reason = "failed to stop engine"; |
632 | goto fail_restart; | 765 | goto fail_restart; |
@@ -647,7 +780,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
647 | } | 780 | } |
648 | 781 | ||
649 | /* restart engine */ | 782 | /* restart engine */ |
650 | ahci_start_engine(ap); | 783 | ahci_start_engine(port_mmio); |
651 | 784 | ||
652 | ata_tf_init(ap->device, &tf); | 785 | ata_tf_init(ap->device, &tf); |
653 | fis = pp->cmd_tbl; | 786 | fis = pp->cmd_tbl; |
@@ -706,7 +839,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
706 | return 0; | 839 | return 0; |
707 | 840 | ||
708 | fail_restart: | 841 | fail_restart: |
709 | ahci_start_engine(ap); | 842 | ahci_start_engine(port_mmio); |
710 | fail: | 843 | fail: |
711 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); | 844 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); |
712 | return rc; | 845 | return rc; |
@@ -717,11 +850,13 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) | |||
717 | struct ahci_port_priv *pp = ap->private_data; | 850 | struct ahci_port_priv *pp = ap->private_data; |
718 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 851 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
719 | struct ata_taskfile tf; | 852 | struct ata_taskfile tf; |
853 | void __iomem *mmio = ap->host_set->mmio_base; | ||
854 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
720 | int rc; | 855 | int rc; |
721 | 856 | ||
722 | DPRINTK("ENTER\n"); | 857 | DPRINTK("ENTER\n"); |
723 | 858 | ||
724 | ahci_stop_engine(ap); | 859 | ahci_stop_engine(port_mmio); |
725 | 860 | ||
726 | /* clear D2H reception area to properly wait for D2H FIS */ | 861 | /* clear D2H reception area to properly wait for D2H FIS */ |
727 | ata_tf_init(ap->device, &tf); | 862 | ata_tf_init(ap->device, &tf); |
@@ -730,7 +865,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) | |||
730 | 865 | ||
731 | rc = sata_std_hardreset(ap, class); | 866 | rc = sata_std_hardreset(ap, class); |
732 | 867 | ||
733 | ahci_start_engine(ap); | 868 | ahci_start_engine(port_mmio); |
734 | 869 | ||
735 | if (rc == 0 && ata_port_online(ap)) | 870 | if (rc == 0 && ata_port_online(ap)) |
736 | *class = ahci_dev_classify(ap); | 871 | *class = ahci_dev_classify(ap); |
@@ -940,14 +1075,8 @@ static void ahci_host_intr(struct ata_port *ap) | |||
940 | return; | 1075 | return; |
941 | 1076 | ||
942 | /* ignore interim PIO setup fis interrupts */ | 1077 | /* ignore interim PIO setup fis interrupts */ |
943 | if (ata_tag_valid(ap->active_tag)) { | 1078 | if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) |
944 | struct ata_queued_cmd *qc = | 1079 | return; |
945 | ata_qc_from_tag(ap, ap->active_tag); | ||
946 | |||
947 | if (qc && qc->tf.protocol == ATA_PROT_PIO && | ||
948 | (status & PORT_IRQ_PIOS_FIS)) | ||
949 | return; | ||
950 | } | ||
951 | 1080 | ||
952 | if (ata_ratelimit()) | 1081 | if (ata_ratelimit()) |
953 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " | 1082 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " |
@@ -1052,10 +1181,13 @@ static void ahci_thaw(struct ata_port *ap) | |||
1052 | 1181 | ||
1053 | static void ahci_error_handler(struct ata_port *ap) | 1182 | static void ahci_error_handler(struct ata_port *ap) |
1054 | { | 1183 | { |
1184 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1185 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1186 | |||
1055 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { | 1187 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) { |
1056 | /* restart engine */ | 1188 | /* restart engine */ |
1057 | ahci_stop_engine(ap); | 1189 | ahci_stop_engine(port_mmio); |
1058 | ahci_start_engine(ap); | 1190 | ahci_start_engine(port_mmio); |
1059 | } | 1191 | } |
1060 | 1192 | ||
1061 | /* perform recovery */ | 1193 | /* perform recovery */ |
@@ -1066,15 +1198,176 @@ static void ahci_error_handler(struct ata_port *ap) | |||
1066 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | 1198 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) |
1067 | { | 1199 | { |
1068 | struct ata_port *ap = qc->ap; | 1200 | struct ata_port *ap = qc->ap; |
1201 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1202 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1069 | 1203 | ||
1070 | if (qc->flags & ATA_QCFLAG_FAILED) | 1204 | if (qc->flags & ATA_QCFLAG_FAILED) |
1071 | qc->err_mask |= AC_ERR_OTHER; | 1205 | qc->err_mask |= AC_ERR_OTHER; |
1072 | 1206 | ||
1073 | if (qc->err_mask) { | 1207 | if (qc->err_mask) { |
1074 | /* make DMA engine forget about the failed command */ | 1208 | /* make DMA engine forget about the failed command */ |
1075 | ahci_stop_engine(ap); | 1209 | ahci_stop_engine(port_mmio); |
1076 | ahci_start_engine(ap); | 1210 | ahci_start_engine(port_mmio); |
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | ||
1215 | { | ||
1216 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
1217 | struct ahci_port_priv *pp = ap->private_data; | ||
1218 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1219 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1220 | const char *emsg = NULL; | ||
1221 | int rc; | ||
1222 | |||
1223 | rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); | ||
1224 | if (rc) { | ||
1225 | ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); | ||
1226 | ahci_init_port(port_mmio, hpriv->cap, | ||
1227 | pp->cmd_slot_dma, pp->rx_fis_dma); | ||
1228 | } | ||
1229 | |||
1230 | return rc; | ||
1231 | } | ||
1232 | |||
1233 | static int ahci_port_resume(struct ata_port *ap) | ||
1234 | { | ||
1235 | struct ahci_port_priv *pp = ap->private_data; | ||
1236 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
1237 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1238 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1239 | |||
1240 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); | ||
1241 | |||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
1246 | { | ||
1247 | struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); | ||
1248 | void __iomem *mmio = host_set->mmio_base; | ||
1249 | u32 ctl; | ||
1250 | |||
1251 | if (mesg.event == PM_EVENT_SUSPEND) { | ||
1252 | /* AHCI spec rev1.1 section 8.3.3: | ||
1253 | * Software must disable interrupts prior to requesting a | ||
1254 | * transition of the HBA to D3 state. | ||
1255 | */ | ||
1256 | ctl = readl(mmio + HOST_CTL); | ||
1257 | ctl &= ~HOST_IRQ_EN; | ||
1258 | writel(ctl, mmio + HOST_CTL); | ||
1259 | readl(mmio + HOST_CTL); /* flush */ | ||
1077 | } | 1260 | } |
1261 | |||
1262 | return ata_pci_device_suspend(pdev, mesg); | ||
1263 | } | ||
1264 | |||
1265 | static int ahci_pci_device_resume(struct pci_dev *pdev) | ||
1266 | { | ||
1267 | struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); | ||
1268 | struct ahci_host_priv *hpriv = host_set->private_data; | ||
1269 | void __iomem *mmio = host_set->mmio_base; | ||
1270 | int rc; | ||
1271 | |||
1272 | ata_pci_device_do_resume(pdev); | ||
1273 | |||
1274 | if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { | ||
1275 | rc = ahci_reset_controller(mmio, pdev); | ||
1276 | if (rc) | ||
1277 | return rc; | ||
1278 | |||
1279 | ahci_init_controller(mmio, pdev, host_set->n_ports, hpriv->cap); | ||
1280 | } | ||
1281 | |||
1282 | ata_host_set_resume(host_set); | ||
1283 | |||
1284 | return 0; | ||
1285 | } | ||
1286 | |||
1287 | static int ahci_port_start(struct ata_port *ap) | ||
1288 | { | ||
1289 | struct device *dev = ap->host_set->dev; | ||
1290 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
1291 | struct ahci_port_priv *pp; | ||
1292 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1293 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1294 | void *mem; | ||
1295 | dma_addr_t mem_dma; | ||
1296 | int rc; | ||
1297 | |||
1298 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | ||
1299 | if (!pp) | ||
1300 | return -ENOMEM; | ||
1301 | memset(pp, 0, sizeof(*pp)); | ||
1302 | |||
1303 | rc = ata_pad_alloc(ap, dev); | ||
1304 | if (rc) { | ||
1305 | kfree(pp); | ||
1306 | return rc; | ||
1307 | } | ||
1308 | |||
1309 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | ||
1310 | if (!mem) { | ||
1311 | ata_pad_free(ap, dev); | ||
1312 | kfree(pp); | ||
1313 | return -ENOMEM; | ||
1314 | } | ||
1315 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | ||
1316 | |||
1317 | /* | ||
1318 | * First item in chunk of DMA memory: 32-slot command table, | ||
1319 | * 32 bytes each in size | ||
1320 | */ | ||
1321 | pp->cmd_slot = mem; | ||
1322 | pp->cmd_slot_dma = mem_dma; | ||
1323 | |||
1324 | mem += AHCI_CMD_SLOT_SZ; | ||
1325 | mem_dma += AHCI_CMD_SLOT_SZ; | ||
1326 | |||
1327 | /* | ||
1328 | * Second item: Received-FIS area | ||
1329 | */ | ||
1330 | pp->rx_fis = mem; | ||
1331 | pp->rx_fis_dma = mem_dma; | ||
1332 | |||
1333 | mem += AHCI_RX_FIS_SZ; | ||
1334 | mem_dma += AHCI_RX_FIS_SZ; | ||
1335 | |||
1336 | /* | ||
1337 | * Third item: data area for storing a single command | ||
1338 | * and its scatter-gather table | ||
1339 | */ | ||
1340 | pp->cmd_tbl = mem; | ||
1341 | pp->cmd_tbl_dma = mem_dma; | ||
1342 | |||
1343 | ap->private_data = pp; | ||
1344 | |||
1345 | /* initialize port */ | ||
1346 | ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); | ||
1347 | |||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | static void ahci_port_stop(struct ata_port *ap) | ||
1352 | { | ||
1353 | struct device *dev = ap->host_set->dev; | ||
1354 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
1355 | struct ahci_port_priv *pp = ap->private_data; | ||
1356 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1357 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1358 | const char *emsg = NULL; | ||
1359 | int rc; | ||
1360 | |||
1361 | /* de-initialize port */ | ||
1362 | rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); | ||
1363 | if (rc) | ||
1364 | ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc); | ||
1365 | |||
1366 | ap->private_data = NULL; | ||
1367 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | ||
1368 | pp->cmd_slot, pp->cmd_slot_dma); | ||
1369 | ata_pad_free(ap, dev); | ||
1370 | kfree(pp); | ||
1078 | } | 1371 | } |
1079 | 1372 | ||
1080 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, | 1373 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, |
@@ -1095,47 +1388,12 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1095 | struct ahci_host_priv *hpriv = probe_ent->private_data; | 1388 | struct ahci_host_priv *hpriv = probe_ent->private_data; |
1096 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); | 1389 | struct pci_dev *pdev = to_pci_dev(probe_ent->dev); |
1097 | void __iomem *mmio = probe_ent->mmio_base; | 1390 | void __iomem *mmio = probe_ent->mmio_base; |
1098 | u32 tmp, cap_save; | 1391 | unsigned int i, using_dac; |
1099 | unsigned int i, j, using_dac; | ||
1100 | int rc; | 1392 | int rc; |
1101 | void __iomem *port_mmio; | ||
1102 | 1393 | ||
1103 | cap_save = readl(mmio + HOST_CAP); | 1394 | rc = ahci_reset_controller(mmio, pdev); |
1104 | cap_save &= ( (1<<28) | (1<<17) ); | 1395 | if (rc) |
1105 | cap_save |= (1 << 27); | 1396 | return rc; |
1106 | |||
1107 | /* global controller reset */ | ||
1108 | tmp = readl(mmio + HOST_CTL); | ||
1109 | if ((tmp & HOST_RESET) == 0) { | ||
1110 | writel(tmp | HOST_RESET, mmio + HOST_CTL); | ||
1111 | readl(mmio + HOST_CTL); /* flush */ | ||
1112 | } | ||
1113 | |||
1114 | /* reset must complete within 1 second, or | ||
1115 | * the hardware should be considered fried. | ||
1116 | */ | ||
1117 | ssleep(1); | ||
1118 | |||
1119 | tmp = readl(mmio + HOST_CTL); | ||
1120 | if (tmp & HOST_RESET) { | ||
1121 | dev_printk(KERN_ERR, &pdev->dev, | ||
1122 | "controller reset failed (0x%x)\n", tmp); | ||
1123 | return -EIO; | ||
1124 | } | ||
1125 | |||
1126 | writel(HOST_AHCI_EN, mmio + HOST_CTL); | ||
1127 | (void) readl(mmio + HOST_CTL); /* flush */ | ||
1128 | writel(cap_save, mmio + HOST_CAP); | ||
1129 | writel(0xf, mmio + HOST_PORTS_IMPL); | ||
1130 | (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ | ||
1131 | |||
1132 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) { | ||
1133 | u16 tmp16; | ||
1134 | |||
1135 | pci_read_config_word(pdev, 0x92, &tmp16); | ||
1136 | tmp16 |= 0xf; | ||
1137 | pci_write_config_word(pdev, 0x92, tmp16); | ||
1138 | } | ||
1139 | 1397 | ||
1140 | hpriv->cap = readl(mmio + HOST_CAP); | 1398 | hpriv->cap = readl(mmio + HOST_CAP); |
1141 | hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); | 1399 | hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); |
@@ -1171,63 +1429,10 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1171 | } | 1429 | } |
1172 | } | 1430 | } |
1173 | 1431 | ||
1174 | for (i = 0; i < probe_ent->n_ports; i++) { | 1432 | for (i = 0; i < probe_ent->n_ports; i++) |
1175 | #if 0 /* BIOSen initialize this incorrectly */ | 1433 | ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); |
1176 | if (!(hpriv->port_map & (1 << i))) | ||
1177 | continue; | ||
1178 | #endif | ||
1179 | |||
1180 | port_mmio = ahci_port_base(mmio, i); | ||
1181 | VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio); | ||
1182 | |||
1183 | ahci_setup_port(&probe_ent->port[i], | ||
1184 | (unsigned long) mmio, i); | ||
1185 | |||
1186 | /* make sure port is not active */ | ||
1187 | tmp = readl(port_mmio + PORT_CMD); | ||
1188 | VPRINTK("PORT_CMD 0x%x\n", tmp); | ||
1189 | if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | | ||
1190 | PORT_CMD_FIS_RX | PORT_CMD_START)) { | ||
1191 | tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | | ||
1192 | PORT_CMD_FIS_RX | PORT_CMD_START); | ||
1193 | writel(tmp, port_mmio + PORT_CMD); | ||
1194 | readl(port_mmio + PORT_CMD); /* flush */ | ||
1195 | |||
1196 | /* spec says 500 msecs for each bit, so | ||
1197 | * this is slightly incorrect. | ||
1198 | */ | ||
1199 | msleep(500); | ||
1200 | } | ||
1201 | |||
1202 | writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); | ||
1203 | |||
1204 | j = 0; | ||
1205 | while (j < 100) { | ||
1206 | msleep(10); | ||
1207 | tmp = readl(port_mmio + PORT_SCR_STAT); | ||
1208 | if ((tmp & 0xf) == 0x3) | ||
1209 | break; | ||
1210 | j++; | ||
1211 | } | ||
1212 | |||
1213 | tmp = readl(port_mmio + PORT_SCR_ERR); | ||
1214 | VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); | ||
1215 | writel(tmp, port_mmio + PORT_SCR_ERR); | ||
1216 | 1434 | ||
1217 | /* ack any pending irq events for this port */ | 1435 | ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); |
1218 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
1219 | VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); | ||
1220 | if (tmp) | ||
1221 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
1222 | |||
1223 | writel(1 << i, mmio + HOST_IRQ_STAT); | ||
1224 | } | ||
1225 | |||
1226 | tmp = readl(mmio + HOST_CTL); | ||
1227 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
1228 | writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); | ||
1229 | tmp = readl(mmio + HOST_CTL); | ||
1230 | VPRINTK("HOST_CTL 0x%x\n", tmp); | ||
1231 | 1436 | ||
1232 | pci_set_master(pdev); | 1437 | pci_set_master(pdev); |
1233 | 1438 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index a1e8ca758594..653818d2f802 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd) | |||
7289 | ahd->flags &= ~AHD_UPDATE_PEND_CMDS; | 7289 | ahd->flags &= ~AHD_UPDATE_PEND_CMDS; |
7290 | } | 7290 | } |
7291 | 7291 | ||
7292 | void | 7292 | static void |
7293 | ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status) | 7293 | ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status) |
7294 | { | 7294 | { |
7295 | cam_status ostat; | 7295 | cam_status ostat; |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index b244c7124179..998999c0a972 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -243,25 +243,6 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb) | |||
243 | static uint32_t aic79xx_no_reset; | 243 | static uint32_t aic79xx_no_reset; |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Certain PCI motherboards will scan PCI devices from highest to lowest, | ||
247 | * others scan from lowest to highest, and they tend to do all kinds of | ||
248 | * strange things when they come into contact with PCI bridge chips. The | ||
249 | * net result of all this is that the PCI card that is actually used to boot | ||
250 | * the machine is very hard to detect. Most motherboards go from lowest | ||
251 | * PCI slot number to highest, and the first SCSI controller found is the | ||
252 | * one you boot from. The only exceptions to this are when a controller | ||
253 | * has its BIOS disabled. So, we by default sort all of our SCSI controllers | ||
254 | * from lowest PCI slot number to highest PCI slot number. We also force | ||
255 | * all controllers with their BIOS disabled to the end of the list. This | ||
256 | * works on *almost* all computers. Where it doesn't work, we have this | ||
257 | * option. Setting this option to non-0 will reverse the order of the sort | ||
258 | * to highest first, then lowest, but will still leave cards with their BIOS | ||
259 | * disabled at the very end. That should fix everyone up unless there are | ||
260 | * really strange cirumstances. | ||
261 | */ | ||
262 | static uint32_t aic79xx_reverse_scan; | ||
263 | |||
264 | /* | ||
265 | * Should we force EXTENDED translation on a controller. | 246 | * Should we force EXTENDED translation on a controller. |
266 | * 0 == Use whatever is in the SEEPROM or default to off | 247 | * 0 == Use whatever is in the SEEPROM or default to off |
267 | * 1 == Use whatever is in the SEEPROM or default to on | 248 | * 1 == Use whatever is in the SEEPROM or default to on |
@@ -350,7 +331,6 @@ MODULE_PARM_DESC(aic79xx, | |||
350 | " periodically to prevent tag starvation.\n" | 331 | " periodically to prevent tag starvation.\n" |
351 | " This may be required by some older disk\n" | 332 | " This may be required by some older disk\n" |
352 | " or drives/RAID arrays.\n" | 333 | " or drives/RAID arrays.\n" |
353 | " reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" | ||
354 | " tag_info:<tag_str> Set per-target tag depth\n" | 334 | " tag_info:<tag_str> Set per-target tag depth\n" |
355 | " global_tag_depth:<int> Global tag depth for all targets on all buses\n" | 335 | " global_tag_depth:<int> Global tag depth for all targets on all buses\n" |
356 | " slewrate:<slewrate_list>Set the signal slew rate (0-15).\n" | 336 | " slewrate:<slewrate_list>Set the signal slew rate (0-15).\n" |
@@ -1031,7 +1011,6 @@ aic79xx_setup(char *s) | |||
1031 | #ifdef AHD_DEBUG | 1011 | #ifdef AHD_DEBUG |
1032 | { "debug", &ahd_debug }, | 1012 | { "debug", &ahd_debug }, |
1033 | #endif | 1013 | #endif |
1034 | { "reverse_scan", &aic79xx_reverse_scan }, | ||
1035 | { "periodic_otag", &aic79xx_periodic_otag }, | 1014 | { "periodic_otag", &aic79xx_periodic_otag }, |
1036 | { "pci_parity", &aic79xx_pci_parity }, | 1015 | { "pci_parity", &aic79xx_pci_parity }, |
1037 | { "seltime", &aic79xx_seltime }, | 1016 | { "seltime", &aic79xx_seltime }, |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index debf3e2a0798..aa4be8a31415 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -353,7 +353,6 @@ MODULE_PARM_DESC(aic7xxx, | |||
353 | " periodically to prevent tag starvation.\n" | 353 | " periodically to prevent tag starvation.\n" |
354 | " This may be required by some older disk\n" | 354 | " This may be required by some older disk\n" |
355 | " drives or RAID arrays.\n" | 355 | " drives or RAID arrays.\n" |
356 | " reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" | ||
357 | " tag_info:<tag_str> Set per-target tag depth\n" | 356 | " tag_info:<tag_str> Set per-target tag depth\n" |
358 | " global_tag_depth:<int> Global tag depth for every target\n" | 357 | " global_tag_depth:<int> Global tag depth for every target\n" |
359 | " on every bus\n" | 358 | " on every bus\n" |
diff --git a/drivers/scsi/aic7xxx/aicasm/Makefile b/drivers/scsi/aic7xxx/aicasm/Makefile index 8c91fda6482c..b98c5c1056c3 100644 --- a/drivers/scsi/aic7xxx/aicasm/Makefile +++ b/drivers/scsi/aic7xxx/aicasm/Makefile | |||
@@ -14,6 +14,8 @@ LIBS= -ldb | |||
14 | clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG) | 14 | clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG) |
15 | # Override default kernel CFLAGS. This is a userland app. | 15 | # Override default kernel CFLAGS. This is a userland app. |
16 | AICASM_CFLAGS:= -I/usr/include -I. | 16 | AICASM_CFLAGS:= -I/usr/include -I. |
17 | LEX= flex | ||
18 | YACC= bison | ||
17 | YFLAGS= -d | 19 | YFLAGS= -d |
18 | 20 | ||
19 | NOMAN= noman | 21 | NOMAN= noman |
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 3e1053f111dc..4cf7afc31cc7 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
@@ -2427,7 +2427,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt) | |||
2427 | info->stats.aborts += 1; | 2427 | info->stats.aborts += 1; |
2428 | 2428 | ||
2429 | printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); | 2429 | printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); |
2430 | __scsi_print_command(SCpnt->data_cmnd); | 2430 | __scsi_print_command(SCpnt->cmnd); |
2431 | 2431 | ||
2432 | print_debug_list(); | 2432 | print_debug_list(); |
2433 | fas216_dumpstate(info); | 2433 | fas216_dumpstate(info); |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 19745a31072b..501755a606ed 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -487,7 +487,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap) | |||
487 | goto cbl40; | 487 | goto cbl40; |
488 | 488 | ||
489 | /* check BIOS cable detect results */ | 489 | /* check BIOS cable detect results */ |
490 | mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; | 490 | mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; |
491 | pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); | 491 | pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); |
492 | if ((tmp & mask) == 0) | 492 | if ((tmp & mask) == 0) |
493 | goto cbl40; | 493 | goto cbl40; |
@@ -513,7 +513,7 @@ static int piix_pata_prereset(struct ata_port *ap) | |||
513 | { | 513 | { |
514 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 514 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); |
515 | 515 | ||
516 | if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { | 516 | if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) { |
517 | ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); | 517 | ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); |
518 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; | 518 | ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; |
519 | return 0; | 519 | return 0; |
@@ -550,7 +550,7 @@ static int piix_sata_prereset(struct ata_port *ap) | |||
550 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 550 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); |
551 | struct piix_host_priv *hpriv = ap->host_set->private_data; | 551 | struct piix_host_priv *hpriv = ap->host_set->private_data; |
552 | const unsigned int *map = hpriv->map; | 552 | const unsigned int *map = hpriv->map; |
553 | int base = 2 * ap->hard_port_no; | 553 | int base = 2 * ap->port_no; |
554 | unsigned int present = 0; | 554 | unsigned int present = 0; |
555 | int port, i; | 555 | int port, i; |
556 | u16 pcs; | 556 | u16 pcs; |
@@ -567,8 +567,8 @@ static int piix_sata_prereset(struct ata_port *ap) | |||
567 | present = 1; | 567 | present = 1; |
568 | } | 568 | } |
569 | 569 | ||
570 | DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", | 570 | DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n", |
571 | ap->id, pcs, present_mask); | 571 | ap->id, pcs, present); |
572 | 572 | ||
573 | if (!present) { | 573 | if (!present) { |
574 | ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); | 574 | ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); |
@@ -601,7 +601,7 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
601 | unsigned int pio = adev->pio_mode - XFER_PIO_0; | 601 | unsigned int pio = adev->pio_mode - XFER_PIO_0; |
602 | struct pci_dev *dev = to_pci_dev(ap->host_set->dev); | 602 | struct pci_dev *dev = to_pci_dev(ap->host_set->dev); |
603 | unsigned int is_slave = (adev->devno != 0); | 603 | unsigned int is_slave = (adev->devno != 0); |
604 | unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40; | 604 | unsigned int master_port= ap->port_no ? 0x42 : 0x40; |
605 | unsigned int slave_port = 0x44; | 605 | unsigned int slave_port = 0x44; |
606 | u16 master_data; | 606 | u16 master_data; |
607 | u8 slave_data; | 607 | u8 slave_data; |
@@ -619,10 +619,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
619 | /* enable PPE, IE and TIME */ | 619 | /* enable PPE, IE and TIME */ |
620 | master_data |= 0x0070; | 620 | master_data |= 0x0070; |
621 | pci_read_config_byte(dev, slave_port, &slave_data); | 621 | pci_read_config_byte(dev, slave_port, &slave_data); |
622 | slave_data &= (ap->hard_port_no ? 0x0f : 0xf0); | 622 | slave_data &= (ap->port_no ? 0x0f : 0xf0); |
623 | slave_data |= | 623 | slave_data |= |
624 | (timings[pio][0] << 2) | | 624 | (timings[pio][0] << 2) | |
625 | (timings[pio][1] << (ap->hard_port_no ? 4 : 0)); | 625 | (timings[pio][1] << (ap->port_no ? 4 : 0)); |
626 | } else { | 626 | } else { |
627 | master_data &= 0xccf8; | 627 | master_data &= 0xccf8; |
628 | /* enable PPE, IE and TIME */ | 628 | /* enable PPE, IE and TIME */ |
@@ -652,9 +652,9 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
652 | { | 652 | { |
653 | unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ | 653 | unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ |
654 | struct pci_dev *dev = to_pci_dev(ap->host_set->dev); | 654 | struct pci_dev *dev = to_pci_dev(ap->host_set->dev); |
655 | u8 maslave = ap->hard_port_no ? 0x42 : 0x40; | 655 | u8 maslave = ap->port_no ? 0x42 : 0x40; |
656 | u8 speed = udma; | 656 | u8 speed = udma; |
657 | unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno; | 657 | unsigned int drive_dn = (ap->port_no ? 2 : 0) + adev->devno; |
658 | int a_speed = 3 << (drive_dn * 4); | 658 | int a_speed = 3 << (drive_dn * 4); |
659 | int u_flag = 1 << drive_dn; | 659 | int u_flag = 1 << drive_dn; |
660 | int v_flag = 0x01 << drive_dn; | 660 | int v_flag = 0x01 << drive_dn; |
@@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, | |||
828 | case IDE: | 828 | case IDE: |
829 | WARN_ON((i & 1) || map[i + 1] != IDE); | 829 | WARN_ON((i & 1) || map[i + 1] != IDE); |
830 | pinfo[i / 2] = piix_port_info[ich5_pata]; | 830 | pinfo[i / 2] = piix_port_info[ich5_pata]; |
831 | pinfo[i / 2].private_data = hpriv; | ||
831 | i++; | 832 | i++; |
832 | printk(" IDE IDE"); | 833 | printk(" IDE IDE"); |
833 | break; | 834 | break; |
@@ -931,8 +932,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
931 | 932 | ||
932 | static void piix_host_stop(struct ata_host_set *host_set) | 933 | static void piix_host_stop(struct ata_host_set *host_set) |
933 | { | 934 | { |
934 | if (host_set->next == NULL) | ||
935 | kfree(host_set->private_data); | ||
936 | ata_host_stop(host_set); | 935 | ata_host_stop(host_set); |
937 | } | 936 | } |
938 | 937 | ||
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 007a14e5c3fd..e397129c90d1 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) | |||
507 | */ | 507 | */ |
508 | 508 | ||
509 | if (cmd->use_sg) { | 509 | if (cmd->use_sg) { |
510 | cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; | 510 | cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; |
511 | cmd->SCp.buffers_residual = cmd->use_sg - 1; | 511 | cmd->SCp.buffers_residual = cmd->use_sg - 1; |
512 | cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+ | 512 | cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+ |
513 | cmd->SCp.buffer->offset; | 513 | cmd->SCp.buffer->offset; |
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index dddd2acce76f..61f6024b61ba 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) | 5 | * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) |
6 | * by D. Gilbert and aeb (20020609) | 6 | * by D. Gilbert and aeb (20020609) |
7 | * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025 | 7 | * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025 |
8 | * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702 | ||
8 | */ | 9 | */ |
9 | 10 | ||
10 | #include <linux/blkdev.h> | 11 | #include <linux/blkdev.h> |
@@ -36,55 +37,56 @@ static const char * cdb_byte0_names[] = { | |||
36 | /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", | 37 | /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", |
37 | /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, | 38 | /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, |
38 | "Reasssign Blocks", | 39 | "Reasssign Blocks", |
39 | /* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL, | 40 | /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, |
40 | /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", | 41 | /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", |
41 | /* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)", | 42 | /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", |
42 | "Reserve (6)", | 43 | "Reserve(6)", |
43 | /* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", | 44 | /* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", |
44 | /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", | 45 | /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", |
45 | /* 1e-1f */ "Prevent/Allow Medium Removal", NULL, | 46 | /* 1e-1f */ "Prevent/Allow Medium Removal", NULL, |
46 | /* 20-22 */ NULL, NULL, NULL, | 47 | /* 20-22 */ NULL, NULL, NULL, |
47 | /* 23-28 */ "Read Format Capacities", "Set Window", | 48 | /* 23-28 */ "Read Format Capacities", "Set Window", |
48 | "Read Capacity (10)", NULL, NULL, "Read (10)", | 49 | "Read Capacity(10)", NULL, NULL, "Read(10)", |
49 | /* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", | 50 | /* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", |
50 | "Read updated block", | 51 | "Read updated block", |
51 | /* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", | 52 | /* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", |
52 | /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", | 53 | /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", |
53 | /* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)", | 54 | /* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", |
54 | "Read Defect Data(10)", | 55 | "Read Defect Data(10)", |
55 | /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", | 56 | /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", |
56 | "Read Buffer", | 57 | "Read Buffer", |
57 | /* 3d-3f */ "Update Block", "Read Long (10)", "Write Long (10)", | 58 | /* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", |
58 | /* 40-41 */ "Change Definition", "Write Same (10)", | 59 | /* 40-41 */ "Change Definition", "Write Same(10)", |
59 | /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support", | 60 | /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support", |
60 | "Play audio (10)", "Get configuration", "Play audio msf", | 61 | "Play audio(10)", "Get configuration", "Play audio msf", |
61 | "Play audio track/index", | 62 | "Play audio track/index", |
62 | /* 49-4f */ "Play track relative (10)", "Get event status notification", | 63 | /* 49-4f */ "Play track relative(10)", "Get event status notification", |
63 | "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", | 64 | "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", |
64 | NULL, | 65 | NULL, |
65 | /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", | 66 | /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", |
66 | "Reserve track", "Send OPC info", "Mode Select (10)", | 67 | "Reserve track", "Send OPC info", "Mode Select(10)", |
67 | /* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue", | 68 | /* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue", |
68 | "Mode Sense (10)", "Close track/session", | 69 | "Mode Sense(10)", "Close track/session", |
69 | /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", | 70 | /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", |
70 | "Persistent reserve out", | 71 | "Persistent reserve out", |
71 | /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 72 | /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
72 | /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 73 | /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
73 | /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 74 | /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
74 | /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length", | 75 | /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length", |
75 | /* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy", | 76 | /* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy", |
76 | "Receive copy results", | 77 | "Receive copy results", |
77 | /* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out", | 78 | /* 85-89 */ "ATA command pass through(16)", "Access control in", |
78 | "Read (16)", "Memory Export Out (16)", | 79 | "Access control out", "Read(16)", "Memory Export Out(16)", |
79 | /* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes", | 80 | /* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes", |
80 | "Write and verify (16)", "Verify (16)", | 81 | "Write and verify(16)", "Verify(16)", |
81 | /* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", | 82 | /* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)", |
82 | "Lock/unlock cache (16)", "Write same (16)", NULL, | 83 | "Lock/unlock cache(16)", "Write same(16)", NULL, |
83 | /* 95-99 */ NULL, NULL, NULL, NULL, NULL, | 84 | /* 95-99 */ NULL, NULL, NULL, NULL, NULL, |
84 | /* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)", | 85 | /* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)", |
85 | "Service action out (16)", | 86 | "Service action out(16)", |
86 | /* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in", | 87 | /* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank", |
87 | "Maintenance out", "Move medium/play audio(12)", | 88 | "Security protocol in", "Maintenance in", "Maintenance out", |
89 | "Move medium/play audio(12)", | ||
88 | /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", | 90 | /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", |
89 | "Play track relative(12)", | 91 | "Play track relative(12)", |
90 | /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance", | 92 | /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance", |
@@ -92,12 +94,12 @@ static const char * cdb_byte0_names[] = { | |||
92 | /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", | 94 | /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", |
93 | /* b2-b4 */ "Search data low(12)", "Set limits(12)", | 95 | /* b2-b4 */ "Search data low(12)", "Set limits(12)", |
94 | "Read element status attached", | 96 | "Read element status attached", |
95 | /* b5-b6 */ "Request volume element address", "Send volume tag, set streaming", | 97 | /* b5-b6 */ "Security protocol out", "Send volume tag, set streaming", |
96 | /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", | 98 | /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", |
97 | /* ba-bc */ "Redundancy group (in), Scan", | 99 | /* ba-bc */ "Redundancy group (in), Scan", |
98 | "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd", | 100 | "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", |
99 | /* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd", | 101 | /* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", |
100 | "Volume set out, Send DVD structure", | 102 | "Volume set (out), Send DVD structure", |
101 | }; | 103 | }; |
102 | 104 | ||
103 | struct value_name_pair { | 105 | struct value_name_pair { |
@@ -112,6 +114,7 @@ static const struct value_name_pair maint_in_arr[] = { | |||
112 | {0xc, "Report supported operation codes"}, | 114 | {0xc, "Report supported operation codes"}, |
113 | {0xd, "Report supported task management functions"}, | 115 | {0xd, "Report supported task management functions"}, |
114 | {0xe, "Report priority"}, | 116 | {0xe, "Report priority"}, |
117 | {0xf, "Report timestamp"}, | ||
115 | }; | 118 | }; |
116 | #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr) | 119 | #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr) |
117 | 120 | ||
@@ -120,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = { | |||
120 | {0xa, "Set target port groups"}, | 123 | {0xa, "Set target port groups"}, |
121 | {0xb, "Change aliases"}, | 124 | {0xb, "Change aliases"}, |
122 | {0xe, "Set priority"}, | 125 | {0xe, "Set priority"}, |
126 | {0xe, "Set timestamp"}, | ||
123 | }; | 127 | }; |
124 | #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr) | 128 | #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr) |
125 | 129 | ||
@@ -427,6 +431,7 @@ static struct error_info additional[] = | |||
427 | {0x001A, "Rewind operation in progress"}, | 431 | {0x001A, "Rewind operation in progress"}, |
428 | {0x001B, "Set capacity operation in progress"}, | 432 | {0x001B, "Set capacity operation in progress"}, |
429 | {0x001C, "Verify operation in progress"}, | 433 | {0x001C, "Verify operation in progress"}, |
434 | {0x001D, "ATA pass through information available"}, | ||
430 | 435 | ||
431 | {0x0100, "No index/sector signal"}, | 436 | {0x0100, "No index/sector signal"}, |
432 | 437 | ||
@@ -438,7 +443,7 @@ static struct error_info additional[] = | |||
438 | 443 | ||
439 | {0x0400, "Logical unit not ready, cause not reportable"}, | 444 | {0x0400, "Logical unit not ready, cause not reportable"}, |
440 | {0x0401, "Logical unit is in process of becoming ready"}, | 445 | {0x0401, "Logical unit is in process of becoming ready"}, |
441 | {0x0402, "Logical unit not ready, initializing cmd. required"}, | 446 | {0x0402, "Logical unit not ready, initializing command required"}, |
442 | {0x0403, "Logical unit not ready, manual intervention required"}, | 447 | {0x0403, "Logical unit not ready, manual intervention required"}, |
443 | {0x0404, "Logical unit not ready, format in progress"}, | 448 | {0x0404, "Logical unit not ready, format in progress"}, |
444 | {0x0405, "Logical unit not ready, rebuild in progress"}, | 449 | {0x0405, "Logical unit not ready, rebuild in progress"}, |
@@ -478,6 +483,9 @@ static struct error_info additional[] = | |||
478 | {0x0B00, "Warning"}, | 483 | {0x0B00, "Warning"}, |
479 | {0x0B01, "Warning - specified temperature exceeded"}, | 484 | {0x0B01, "Warning - specified temperature exceeded"}, |
480 | {0x0B02, "Warning - enclosure degraded"}, | 485 | {0x0B02, "Warning - enclosure degraded"}, |
486 | {0x0B03, "Warning - background self-test failed"}, | ||
487 | {0x0B04, "Warning - background pre-scan detected medium error"}, | ||
488 | {0x0B05, "Warning - background medium scan detected medium error"}, | ||
481 | 489 | ||
482 | {0x0C00, "Write error"}, | 490 | {0x0C00, "Write error"}, |
483 | {0x0C01, "Write error - recovered with auto reallocation"}, | 491 | {0x0C01, "Write error - recovered with auto reallocation"}, |
@@ -493,6 +501,7 @@ static struct error_info additional[] = | |||
493 | {0x0C0B, "Auxiliary memory write error"}, | 501 | {0x0C0B, "Auxiliary memory write error"}, |
494 | {0x0C0C, "Write error - unexpected unsolicited data"}, | 502 | {0x0C0C, "Write error - unexpected unsolicited data"}, |
495 | {0x0C0D, "Write error - not enough unsolicited data"}, | 503 | {0x0C0D, "Write error - not enough unsolicited data"}, |
504 | {0x0C0F, "Defects in error window"}, | ||
496 | 505 | ||
497 | {0x0D00, "Error detected by third party temporary initiator"}, | 506 | {0x0D00, "Error detected by third party temporary initiator"}, |
498 | {0x0D01, "Third party device failure"}, | 507 | {0x0D01, "Third party device failure"}, |
@@ -504,11 +513,12 @@ static struct error_info additional[] = | |||
504 | {0x0E00, "Invalid information unit"}, | 513 | {0x0E00, "Invalid information unit"}, |
505 | {0x0E01, "Information unit too short"}, | 514 | {0x0E01, "Information unit too short"}, |
506 | {0x0E02, "Information unit too long"}, | 515 | {0x0E02, "Information unit too long"}, |
516 | {0x0E03, "Invalid field in command information unit"}, | ||
507 | 517 | ||
508 | {0x1000, "Id CRC or ECC error"}, | 518 | {0x1000, "Id CRC or ECC error"}, |
509 | {0x1001, "Data block guard check failed"}, | 519 | {0x1001, "Logical block guard check failed"}, |
510 | {0x1002, "Data block application tag check failed"}, | 520 | {0x1002, "Logical block application tag check failed"}, |
511 | {0x1003, "Data block reference tag check failed"}, | 521 | {0x1003, "Logical block reference tag check failed"}, |
512 | 522 | ||
513 | {0x1100, "Unrecovered read error"}, | 523 | {0x1100, "Unrecovered read error"}, |
514 | {0x1101, "Read retries exhausted"}, | 524 | {0x1101, "Read retries exhausted"}, |
@@ -530,6 +540,7 @@ static struct error_info additional[] = | |||
530 | {0x1111, "Read error - loss of streaming"}, | 540 | {0x1111, "Read error - loss of streaming"}, |
531 | {0x1112, "Auxiliary memory read error"}, | 541 | {0x1112, "Auxiliary memory read error"}, |
532 | {0x1113, "Read error - failed retransmission request"}, | 542 | {0x1113, "Read error - failed retransmission request"}, |
543 | {0x1114, "Read error - lba marked bad by application client"}, | ||
533 | 544 | ||
534 | {0x1200, "Address mark not found for id field"}, | 545 | {0x1200, "Address mark not found for id field"}, |
535 | 546 | ||
@@ -610,11 +621,14 @@ static struct error_info additional[] = | |||
610 | {0x2100, "Logical block address out of range"}, | 621 | {0x2100, "Logical block address out of range"}, |
611 | {0x2101, "Invalid element address"}, | 622 | {0x2101, "Invalid element address"}, |
612 | {0x2102, "Invalid address for write"}, | 623 | {0x2102, "Invalid address for write"}, |
624 | {0x2103, "Invalid write crossing layer jump"}, | ||
613 | 625 | ||
614 | {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"}, | 626 | {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"}, |
615 | 627 | ||
616 | {0x2400, "Invalid field in cdb"}, | 628 | {0x2400, "Invalid field in cdb"}, |
617 | {0x2401, "CDB decryption error"}, | 629 | {0x2401, "CDB decryption error"}, |
630 | {0x2402, "Obsolete"}, | ||
631 | {0x2403, "Obsolete"}, | ||
618 | {0x2404, "Security audit value frozen"}, | 632 | {0x2404, "Security audit value frozen"}, |
619 | {0x2405, "Security working key frozen"}, | 633 | {0x2405, "Security working key frozen"}, |
620 | {0x2406, "Nonce not unique"}, | 634 | {0x2406, "Nonce not unique"}, |
@@ -637,7 +651,10 @@ static struct error_info additional[] = | |||
637 | {0x260C, "Invalid operation for copy source or destination"}, | 651 | {0x260C, "Invalid operation for copy source or destination"}, |
638 | {0x260D, "Copy segment granularity violation"}, | 652 | {0x260D, "Copy segment granularity violation"}, |
639 | {0x260E, "Invalid parameter while port is enabled"}, | 653 | {0x260E, "Invalid parameter while port is enabled"}, |
640 | {0x260F, "Invalid data-out buffer integrity"}, | 654 | {0x260F, "Invalid data-out buffer integrity check value"}, |
655 | {0x2610, "Data decryption key fail limit reached"}, | ||
656 | {0x2611, "Incomplete key-associated data set"}, | ||
657 | {0x2612, "Vendor specific key reference not found"}, | ||
641 | 658 | ||
642 | {0x2700, "Write protected"}, | 659 | {0x2700, "Write protected"}, |
643 | {0x2701, "Hardware write protected"}, | 660 | {0x2701, "Hardware write protected"}, |
@@ -649,6 +666,7 @@ static struct error_info additional[] = | |||
649 | 666 | ||
650 | {0x2800, "Not ready to ready change, medium may have changed"}, | 667 | {0x2800, "Not ready to ready change, medium may have changed"}, |
651 | {0x2801, "Import or export element accessed"}, | 668 | {0x2801, "Import or export element accessed"}, |
669 | {0x2802, "Format-layer may have changed"}, | ||
652 | 670 | ||
653 | {0x2900, "Power on, reset, or bus device reset occurred"}, | 671 | {0x2900, "Power on, reset, or bus device reset occurred"}, |
654 | {0x2901, "Power on occurred"}, | 672 | {0x2901, "Power on occurred"}, |
@@ -669,6 +687,11 @@ static struct error_info additional[] = | |||
669 | {0x2A07, "Implicit asymmetric access state transition failed"}, | 687 | {0x2A07, "Implicit asymmetric access state transition failed"}, |
670 | {0x2A08, "Priority changed"}, | 688 | {0x2A08, "Priority changed"}, |
671 | {0x2A09, "Capacity data has changed"}, | 689 | {0x2A09, "Capacity data has changed"}, |
690 | {0x2A10, "Timestamp changed"}, | ||
691 | {0x2A11, "Data encryption parameters changed by another i_t nexus"}, | ||
692 | {0x2A12, "Data encryption parameters changed by vendor specific " | ||
693 | "event"}, | ||
694 | {0x2A13, "Data encryption key instance counter has changed"}, | ||
672 | 695 | ||
673 | {0x2B00, "Copy cannot execute since host cannot disconnect"}, | 696 | {0x2B00, "Copy cannot execute since host cannot disconnect"}, |
674 | 697 | ||
@@ -690,6 +713,7 @@ static struct error_info additional[] = | |||
690 | {0x2E00, "Insufficient time for operation"}, | 713 | {0x2E00, "Insufficient time for operation"}, |
691 | 714 | ||
692 | {0x2F00, "Commands cleared by another initiator"}, | 715 | {0x2F00, "Commands cleared by another initiator"}, |
716 | {0x2F01, "Commands cleared by power loss notification"}, | ||
693 | 717 | ||
694 | {0x3000, "Incompatible medium installed"}, | 718 | {0x3000, "Incompatible medium installed"}, |
695 | {0x3001, "Cannot read medium - unknown format"}, | 719 | {0x3001, "Cannot read medium - unknown format"}, |
@@ -702,7 +726,8 @@ static struct error_info additional[] = | |||
702 | {0x3008, "Cannot write - application code mismatch"}, | 726 | {0x3008, "Cannot write - application code mismatch"}, |
703 | {0x3009, "Current session not fixated for append"}, | 727 | {0x3009, "Current session not fixated for append"}, |
704 | {0x300A, "Cleaning request rejected"}, | 728 | {0x300A, "Cleaning request rejected"}, |
705 | {0x300C, "WORM medium, overwrite attempted"}, | 729 | {0x300C, "WORM medium - overwrite attempted"}, |
730 | {0x300D, "WORM medium - integrity check"}, | ||
706 | {0x3010, "Medium not formatted"}, | 731 | {0x3010, "Medium not formatted"}, |
707 | 732 | ||
708 | {0x3100, "Medium format corrupted"}, | 733 | {0x3100, "Medium format corrupted"}, |
@@ -790,6 +815,9 @@ static struct error_info additional[] = | |||
790 | {0x3F0F, "Echo buffer overwritten"}, | 815 | {0x3F0F, "Echo buffer overwritten"}, |
791 | {0x3F10, "Medium loadable"}, | 816 | {0x3F10, "Medium loadable"}, |
792 | {0x3F11, "Medium auxiliary memory accessible"}, | 817 | {0x3F11, "Medium auxiliary memory accessible"}, |
818 | {0x3F12, "iSCSI IP address added"}, | ||
819 | {0x3F13, "iSCSI IP address removed"}, | ||
820 | {0x3F14, "iSCSI IP address changed"}, | ||
793 | /* | 821 | /* |
794 | * {0x40NN, "Ram failure"}, | 822 | * {0x40NN, "Ram failure"}, |
795 | * {0x40NN, "Diagnostic failure on component nn"}, | 823 | * {0x40NN, "Diagnostic failure on component nn"}, |
@@ -799,6 +827,7 @@ static struct error_info additional[] = | |||
799 | {0x4300, "Message error"}, | 827 | {0x4300, "Message error"}, |
800 | 828 | ||
801 | {0x4400, "Internal target failure"}, | 829 | {0x4400, "Internal target failure"}, |
830 | {0x4471, "ATA device failed set features"}, | ||
802 | 831 | ||
803 | {0x4500, "Select or reselect failure"}, | 832 | {0x4500, "Select or reselect failure"}, |
804 | 833 | ||
@@ -807,9 +836,10 @@ static struct error_info additional[] = | |||
807 | {0x4700, "Scsi parity error"}, | 836 | {0x4700, "Scsi parity error"}, |
808 | {0x4701, "Data phase CRC error detected"}, | 837 | {0x4701, "Data phase CRC error detected"}, |
809 | {0x4702, "Scsi parity error detected during st data phase"}, | 838 | {0x4702, "Scsi parity error detected during st data phase"}, |
810 | {0x4703, "Information unit CRC error detected"}, | 839 | {0x4703, "Information unit iuCRC error detected"}, |
811 | {0x4704, "Asynchronous information protection error detected"}, | 840 | {0x4704, "Asynchronous information protection error detected"}, |
812 | {0x4705, "Protocol service CRC error"}, | 841 | {0x4705, "Protocol service CRC error"}, |
842 | {0x4706, "Phy test function in progress"}, | ||
813 | {0x477f, "Some commands cleared by iSCSI Protocol event"}, | 843 | {0x477f, "Some commands cleared by iSCSI Protocol event"}, |
814 | 844 | ||
815 | {0x4800, "Initiator detected error message received"}, | 845 | {0x4800, "Initiator detected error message received"}, |
@@ -844,6 +874,8 @@ static struct error_info additional[] = | |||
844 | {0x5300, "Media load or eject failed"}, | 874 | {0x5300, "Media load or eject failed"}, |
845 | {0x5301, "Unload tape failure"}, | 875 | {0x5301, "Unload tape failure"}, |
846 | {0x5302, "Medium removal prevented"}, | 876 | {0x5302, "Medium removal prevented"}, |
877 | {0x5303, "Medium removal prevented by data transfer element"}, | ||
878 | {0x5304, "Medium thread or unthread failure"}, | ||
847 | 879 | ||
848 | {0x5400, "Scsi to host system interface failure"}, | 880 | {0x5400, "Scsi to host system interface failure"}, |
849 | 881 | ||
@@ -855,6 +887,7 @@ static struct error_info additional[] = | |||
855 | {0x5505, "Insufficient access control resources"}, | 887 | {0x5505, "Insufficient access control resources"}, |
856 | {0x5506, "Auxiliary memory out of space"}, | 888 | {0x5506, "Auxiliary memory out of space"}, |
857 | {0x5507, "Quota error"}, | 889 | {0x5507, "Quota error"}, |
890 | {0x5508, "Maximum number of supplemental decryption keys exceeded"}, | ||
858 | 891 | ||
859 | {0x5700, "Unable to recover table-of-contents"}, | 892 | {0x5700, "Unable to recover table-of-contents"}, |
860 | 893 | ||
@@ -1004,6 +1037,7 @@ static struct error_info additional[] = | |||
1004 | {0x6708, "Assign failure occurred"}, | 1037 | {0x6708, "Assign failure occurred"}, |
1005 | {0x6709, "Multiply assigned logical unit"}, | 1038 | {0x6709, "Multiply assigned logical unit"}, |
1006 | {0x670A, "Set target port groups command failed"}, | 1039 | {0x670A, "Set target port groups command failed"}, |
1040 | {0x670B, "ATA device feature not enabled"}, | ||
1007 | 1041 | ||
1008 | {0x6800, "Logical unit not configured"}, | 1042 | {0x6800, "Logical unit not configured"}, |
1009 | 1043 | ||
@@ -1030,6 +1064,8 @@ static struct error_info additional[] = | |||
1030 | {0x6F03, "Read of scrambled sector without authentication"}, | 1064 | {0x6F03, "Read of scrambled sector without authentication"}, |
1031 | {0x6F04, "Media region code is mismatched to logical unit region"}, | 1065 | {0x6F04, "Media region code is mismatched to logical unit region"}, |
1032 | {0x6F05, "Drive region must be permanent/region reset count error"}, | 1066 | {0x6F05, "Drive region must be permanent/region reset count error"}, |
1067 | {0x6F06, "Insufficient block count for binding nonce recording"}, | ||
1068 | {0x6F07, "Conflict in binding nonce recording"}, | ||
1033 | /* | 1069 | /* |
1034 | * {0x70NN, "Decompression exception short algorithm id of nn"}, | 1070 | * {0x70NN, "Decompression exception short algorithm id of nn"}, |
1035 | */ | 1071 | */ |
@@ -1041,6 +1077,8 @@ static struct error_info additional[] = | |||
1041 | {0x7203, "Session fixation error - incomplete track in session"}, | 1077 | {0x7203, "Session fixation error - incomplete track in session"}, |
1042 | {0x7204, "Empty or partially written reserved track"}, | 1078 | {0x7204, "Empty or partially written reserved track"}, |
1043 | {0x7205, "No more track reservations allowed"}, | 1079 | {0x7205, "No more track reservations allowed"}, |
1080 | {0x7206, "RMZ extension is not allowed"}, | ||
1081 | {0x7207, "No more test zone extensions are allowed"}, | ||
1044 | 1082 | ||
1045 | {0x7300, "Cd control error"}, | 1083 | {0x7300, "Cd control error"}, |
1046 | {0x7301, "Power calibration area almost full"}, | 1084 | {0x7301, "Power calibration area almost full"}, |
@@ -1049,6 +1087,18 @@ static struct error_info additional[] = | |||
1049 | {0x7304, "Program memory area update failure"}, | 1087 | {0x7304, "Program memory area update failure"}, |
1050 | {0x7305, "Program memory area is full"}, | 1088 | {0x7305, "Program memory area is full"}, |
1051 | {0x7306, "RMA/PMA is almost full"}, | 1089 | {0x7306, "RMA/PMA is almost full"}, |
1090 | {0x7310, "Current power calibration area almost full"}, | ||
1091 | {0x7311, "Current power calibration area is full"}, | ||
1092 | {0x7317, "RDZ is full"}, | ||
1093 | |||
1094 | {0x7400, "Security error"}, | ||
1095 | {0x7401, "Unable to decrypt data"}, | ||
1096 | {0x7402, "Unencrypted data encountered while decrypting"}, | ||
1097 | {0x7403, "Incorrect data encryption key"}, | ||
1098 | {0x7404, "Cryptographic integrity validation failed"}, | ||
1099 | {0x7405, "Error decrypting data"}, | ||
1100 | {0x7471, "Logical unit access not authorized"}, | ||
1101 | |||
1052 | {0, NULL} | 1102 | {0, NULL} |
1053 | }; | 1103 | }; |
1054 | 1104 | ||
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index 10573c24a50b..98bd22714d0d 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c | |||
@@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) | |||
1397 | sp->SCp.ptr = NULL; | 1397 | sp->SCp.ptr = NULL; |
1398 | } | 1398 | } |
1399 | } else { | 1399 | } else { |
1400 | sp->SCp.buffer = (struct scatterlist *) sp->buffer; | 1400 | sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; |
1401 | sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, | 1401 | sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, |
1402 | sp->SCp.buffer, | 1402 | sp->SCp.buffer, |
1403 | sp->use_sg, | 1403 | sp->use_sg, |
@@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) | |||
1410 | static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) | 1410 | static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) |
1411 | { | 1411 | { |
1412 | if (sp->use_sg) { | 1412 | if (sp->use_sg) { |
1413 | sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg, | 1413 | sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg, |
1414 | sp->sc_data_direction); | 1414 | sp->sc_data_direction); |
1415 | } else if (sp->request_bufflen) { | 1415 | } else if (sp->request_bufflen) { |
1416 | sbus_unmap_single(esp->sdev, | 1416 | sbus_unmap_single(esp->sdev, |
@@ -2754,18 +2754,15 @@ static int esp_do_data_finale(struct esp *esp) | |||
2754 | */ | 2754 | */ |
2755 | static int esp_should_clear_sync(struct scsi_cmnd *sp) | 2755 | static int esp_should_clear_sync(struct scsi_cmnd *sp) |
2756 | { | 2756 | { |
2757 | u8 cmd1 = sp->cmnd[0]; | 2757 | u8 cmd = sp->cmnd[0]; |
2758 | u8 cmd2 = sp->data_cmnd[0]; | ||
2759 | 2758 | ||
2760 | /* These cases are for spinning up a disk and | 2759 | /* These cases are for spinning up a disk and |
2761 | * waiting for that spinup to complete. | 2760 | * waiting for that spinup to complete. |
2762 | */ | 2761 | */ |
2763 | if (cmd1 == START_STOP || | 2762 | if (cmd == START_STOP) |
2764 | cmd2 == START_STOP) | ||
2765 | return 0; | 2763 | return 0; |
2766 | 2764 | ||
2767 | if (cmd1 == TEST_UNIT_READY || | 2765 | if (cmd == TEST_UNIT_READY) |
2768 | cmd2 == TEST_UNIT_READY) | ||
2769 | return 0; | 2766 | return 0; |
2770 | 2767 | ||
2771 | /* One more special case for SCSI tape drives, | 2768 | /* One more special case for SCSI tape drives, |
@@ -2773,8 +2770,7 @@ static int esp_should_clear_sync(struct scsi_cmnd *sp) | |||
2773 | * completion of a rewind or tape load operation. | 2770 | * completion of a rewind or tape load operation. |
2774 | */ | 2771 | */ |
2775 | if (sp->device->type == TYPE_TAPE) { | 2772 | if (sp->device->type == TYPE_TAPE) { |
2776 | if (cmd1 == MODE_SENSE || | 2773 | if (cmd == MODE_SENSE) |
2777 | cmd2 == MODE_SENSE) | ||
2778 | return 0; | 2774 | return 0; |
2779 | } | 2775 | } |
2780 | 2776 | ||
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 7eed0b098171..6aeb5f003c3c 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c | |||
@@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
81 | int rc; | 81 | int rc; |
82 | 82 | ||
83 | single_host_data = hostdata; | 83 | single_host_data = hostdata; |
84 | rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0); | 84 | rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests); |
85 | if (rc < 0) { | 85 | if (rc < 0) { |
86 | printk("viopath_open failed with rc %d in open_event_path\n", | 86 | printk("viopath_open failed with rc %d in open_event_path\n", |
87 | rc); | 87 | rc); |
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 242b8873b333..ed22b96580c6 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -238,6 +238,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
238 | if (rc == 2) { | 238 | if (rc == 2) { |
239 | /* Adapter is good, but other end is not ready */ | 239 | /* Adapter is good, but other end is not ready */ |
240 | printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); | 240 | printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); |
241 | retrc = 0; | ||
241 | } else if (rc != 0) { | 242 | } else if (rc != 0) { |
242 | printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc); | 243 | printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc); |
243 | goto reg_crq_failed; | 244 | goto reg_crq_failed; |
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 3fd8a96f2af3..bfac4441d89f 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c | |||
@@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) | |||
257 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) | 257 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) |
258 | { | 258 | { |
259 | int sz = sp->use_sg - 1; | 259 | int sz = sp->use_sg - 1; |
260 | struct scatterlist *sg = (struct scatterlist *)sp->buffer; | 260 | struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; |
261 | 261 | ||
262 | while(sz >= 0) { | 262 | while(sz >= 0) { |
263 | vdma_free(sg[sz].dma_address); | 263 | vdma_free(sg[sz].dma_address); |
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c index 9ce221f25954..158f62dbf21b 100644 --- a/drivers/scsi/libata-bmdma.c +++ b/drivers/scsi/libata-bmdma.c | |||
@@ -797,32 +797,6 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) | |||
797 | } | 797 | } |
798 | 798 | ||
799 | #ifdef CONFIG_PCI | 799 | #ifdef CONFIG_PCI |
800 | static struct ata_probe_ent * | ||
801 | ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | ||
802 | { | ||
803 | struct ata_probe_ent *probe_ent; | ||
804 | |||
805 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
806 | if (!probe_ent) { | ||
807 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | ||
808 | kobject_name(&(dev->kobj))); | ||
809 | return NULL; | ||
810 | } | ||
811 | |||
812 | INIT_LIST_HEAD(&probe_ent->node); | ||
813 | probe_ent->dev = dev; | ||
814 | |||
815 | probe_ent->sht = port->sht; | ||
816 | probe_ent->host_flags = port->host_flags; | ||
817 | probe_ent->pio_mask = port->pio_mask; | ||
818 | probe_ent->mwdma_mask = port->mwdma_mask; | ||
819 | probe_ent->udma_mask = port->udma_mask; | ||
820 | probe_ent->port_ops = port->port_ops; | ||
821 | |||
822 | return probe_ent; | ||
823 | } | ||
824 | |||
825 | |||
826 | /** | 800 | /** |
827 | * ata_pci_init_native_mode - Initialize native-mode driver | 801 | * ata_pci_init_native_mode - Initialize native-mode driver |
828 | * @pdev: pci device to be initialized | 802 | * @pdev: pci device to be initialized |
@@ -880,7 +854,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
880 | if (bmdma) { | 854 | if (bmdma) { |
881 | bmdma += 8; | 855 | bmdma += 8; |
882 | if(inb(bmdma + 2) & 0x80) | 856 | if(inb(bmdma + 2) & 0x80) |
883 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | 857 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; |
884 | probe_ent->port[p].bmdma_addr = bmdma; | 858 | probe_ent->port[p].bmdma_addr = bmdma; |
885 | } | 859 | } |
886 | ata_std_ports(&probe_ent->port[p]); | 860 | ata_std_ports(&probe_ent->port[p]); |
@@ -893,44 +867,48 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int | |||
893 | 867 | ||
894 | 868 | ||
895 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | 869 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, |
896 | struct ata_port_info *port, int port_num) | 870 | struct ata_port_info **port, int port_mask) |
897 | { | 871 | { |
898 | struct ata_probe_ent *probe_ent; | 872 | struct ata_probe_ent *probe_ent; |
899 | unsigned long bmdma; | 873 | unsigned long bmdma = pci_resource_start(pdev, 4); |
900 | 874 | ||
901 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); | 875 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); |
902 | if (!probe_ent) | 876 | if (!probe_ent) |
903 | return NULL; | 877 | return NULL; |
904 | 878 | ||
905 | probe_ent->legacy_mode = 1; | 879 | probe_ent->n_ports = 2; |
906 | probe_ent->n_ports = 1; | 880 | probe_ent->private_data = port[0]->private_data; |
907 | probe_ent->hard_port_no = port_num; | ||
908 | probe_ent->private_data = port->private_data; | ||
909 | |||
910 | switch(port_num) | ||
911 | { | ||
912 | case 0: | ||
913 | probe_ent->irq = 14; | ||
914 | probe_ent->port[0].cmd_addr = 0x1f0; | ||
915 | probe_ent->port[0].altstatus_addr = | ||
916 | probe_ent->port[0].ctl_addr = 0x3f6; | ||
917 | break; | ||
918 | case 1: | ||
919 | probe_ent->irq = 15; | ||
920 | probe_ent->port[0].cmd_addr = 0x170; | ||
921 | probe_ent->port[0].altstatus_addr = | ||
922 | probe_ent->port[0].ctl_addr = 0x376; | ||
923 | break; | ||
924 | } | ||
925 | 881 | ||
926 | bmdma = pci_resource_start(pdev, 4); | 882 | if (port_mask & ATA_PORT_PRIMARY) { |
927 | if (bmdma != 0) { | 883 | probe_ent->irq = 14; |
928 | bmdma += 8 * port_num; | 884 | probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; |
929 | probe_ent->port[0].bmdma_addr = bmdma; | 885 | probe_ent->port[0].altstatus_addr = |
930 | if (inb(bmdma + 2) & 0x80) | 886 | probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; |
931 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | 887 | if (bmdma) { |
932 | } | 888 | probe_ent->port[0].bmdma_addr = bmdma; |
933 | ata_std_ports(&probe_ent->port[0]); | 889 | if (inb(bmdma + 2) & 0x80) |
890 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | ||
891 | } | ||
892 | ata_std_ports(&probe_ent->port[0]); | ||
893 | } else | ||
894 | probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY; | ||
895 | |||
896 | if (port_mask & ATA_PORT_SECONDARY) { | ||
897 | if (probe_ent->irq) | ||
898 | probe_ent->irq2 = 15; | ||
899 | else | ||
900 | probe_ent->irq = 15; | ||
901 | probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; | ||
902 | probe_ent->port[1].altstatus_addr = | ||
903 | probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; | ||
904 | if (bmdma) { | ||
905 | probe_ent->port[1].bmdma_addr = bmdma + 8; | ||
906 | if (inb(bmdma + 10) & 0x80) | ||
907 | probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; | ||
908 | } | ||
909 | ata_std_ports(&probe_ent->port[1]); | ||
910 | } else | ||
911 | probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; | ||
934 | 912 | ||
935 | return probe_ent; | 913 | return probe_ent; |
936 | } | 914 | } |
@@ -950,6 +928,10 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
950 | * regions, sets the dma mask, enables bus master mode, and calls | 928 | * regions, sets the dma mask, enables bus master mode, and calls |
951 | * ata_device_add() | 929 | * ata_device_add() |
952 | * | 930 | * |
931 | * ASSUMPTION: | ||
932 | * Nobody makes a single channel controller that appears solely as | ||
933 | * the secondary legacy port on PCI. | ||
934 | * | ||
953 | * LOCKING: | 935 | * LOCKING: |
954 | * Inherited from PCI layer (may sleep). | 936 | * Inherited from PCI layer (may sleep). |
955 | * | 937 | * |
@@ -960,7 +942,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | |||
960 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | 942 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, |
961 | unsigned int n_ports) | 943 | unsigned int n_ports) |
962 | { | 944 | { |
963 | struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; | 945 | struct ata_probe_ent *probe_ent = NULL; |
964 | struct ata_port_info *port[2]; | 946 | struct ata_port_info *port[2]; |
965 | u8 tmp8, mask; | 947 | u8 tmp8, mask; |
966 | unsigned int legacy_mode = 0; | 948 | unsigned int legacy_mode = 0; |
@@ -1009,35 +991,34 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1009 | goto err_out; | 991 | goto err_out; |
1010 | } | 992 | } |
1011 | 993 | ||
1012 | /* FIXME: Should use platform specific mappers for legacy port ranges */ | ||
1013 | if (legacy_mode) { | 994 | if (legacy_mode) { |
1014 | if (!request_region(0x1f0, 8, "libata")) { | 995 | if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) { |
1015 | struct resource *conflict, res; | 996 | struct resource *conflict, res; |
1016 | res.start = 0x1f0; | 997 | res.start = ATA_PRIMARY_CMD; |
1017 | res.end = 0x1f0 + 8 - 1; | 998 | res.end = ATA_PRIMARY_CMD + 8 - 1; |
1018 | conflict = ____request_resource(&ioport_resource, &res); | 999 | conflict = ____request_resource(&ioport_resource, &res); |
1019 | if (!strcmp(conflict->name, "libata")) | 1000 | if (!strcmp(conflict->name, "libata")) |
1020 | legacy_mode |= (1 << 0); | 1001 | legacy_mode |= ATA_PORT_PRIMARY; |
1021 | else { | 1002 | else { |
1022 | disable_dev_on_err = 0; | 1003 | disable_dev_on_err = 0; |
1023 | printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); | 1004 | printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD); |
1024 | } | 1005 | } |
1025 | } else | 1006 | } else |
1026 | legacy_mode |= (1 << 0); | 1007 | legacy_mode |= ATA_PORT_PRIMARY; |
1027 | 1008 | ||
1028 | if (!request_region(0x170, 8, "libata")) { | 1009 | if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) { |
1029 | struct resource *conflict, res; | 1010 | struct resource *conflict, res; |
1030 | res.start = 0x170; | 1011 | res.start = ATA_SECONDARY_CMD; |
1031 | res.end = 0x170 + 8 - 1; | 1012 | res.end = ATA_SECONDARY_CMD + 8 - 1; |
1032 | conflict = ____request_resource(&ioport_resource, &res); | 1013 | conflict = ____request_resource(&ioport_resource, &res); |
1033 | if (!strcmp(conflict->name, "libata")) | 1014 | if (!strcmp(conflict->name, "libata")) |
1034 | legacy_mode |= (1 << 1); | 1015 | legacy_mode |= ATA_PORT_SECONDARY; |
1035 | else { | 1016 | else { |
1036 | disable_dev_on_err = 0; | 1017 | disable_dev_on_err = 0; |
1037 | printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); | 1018 | printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD); |
1038 | } | 1019 | } |
1039 | } else | 1020 | } else |
1040 | legacy_mode |= (1 << 1); | 1021 | legacy_mode |= ATA_PORT_SECONDARY; |
1041 | } | 1022 | } |
1042 | 1023 | ||
1043 | /* we have legacy mode, but all ports are unavailable */ | 1024 | /* we have legacy mode, but all ports are unavailable */ |
@@ -1055,17 +1036,14 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1055 | goto err_out_regions; | 1036 | goto err_out_regions; |
1056 | 1037 | ||
1057 | if (legacy_mode) { | 1038 | if (legacy_mode) { |
1058 | if (legacy_mode & (1 << 0)) | 1039 | probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); |
1059 | probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); | ||
1060 | if (legacy_mode & (1 << 1)) | ||
1061 | probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); | ||
1062 | } else { | 1040 | } else { |
1063 | if (n_ports == 2) | 1041 | if (n_ports == 2) |
1064 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | 1042 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); |
1065 | else | 1043 | else |
1066 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); | 1044 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); |
1067 | } | 1045 | } |
1068 | if (!probe_ent && !probe_ent2) { | 1046 | if (!probe_ent) { |
1069 | rc = -ENOMEM; | 1047 | rc = -ENOMEM; |
1070 | goto err_out_regions; | 1048 | goto err_out_regions; |
1071 | } | 1049 | } |
@@ -1073,35 +1051,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | |||
1073 | pci_set_master(pdev); | 1051 | pci_set_master(pdev); |
1074 | 1052 | ||
1075 | /* FIXME: check ata_device_add return */ | 1053 | /* FIXME: check ata_device_add return */ |
1076 | if (legacy_mode) { | 1054 | ata_device_add(probe_ent); |
1077 | struct device *dev = &pdev->dev; | ||
1078 | struct ata_host_set *host_set = NULL; | ||
1079 | |||
1080 | if (legacy_mode & (1 << 0)) { | ||
1081 | ata_device_add(probe_ent); | ||
1082 | host_set = dev_get_drvdata(dev); | ||
1083 | } | ||
1084 | |||
1085 | if (legacy_mode & (1 << 1)) { | ||
1086 | ata_device_add(probe_ent2); | ||
1087 | if (host_set) { | ||
1088 | host_set->next = dev_get_drvdata(dev); | ||
1089 | dev_set_drvdata(dev, host_set); | ||
1090 | } | ||
1091 | } | ||
1092 | } else | ||
1093 | ata_device_add(probe_ent); | ||
1094 | 1055 | ||
1095 | kfree(probe_ent); | 1056 | kfree(probe_ent); |
1096 | kfree(probe_ent2); | ||
1097 | 1057 | ||
1098 | return 0; | 1058 | return 0; |
1099 | 1059 | ||
1100 | err_out_regions: | 1060 | err_out_regions: |
1101 | if (legacy_mode & (1 << 0)) | 1061 | if (legacy_mode & ATA_PORT_PRIMARY) |
1102 | release_region(0x1f0, 8); | 1062 | release_region(ATA_PRIMARY_CMD, 8); |
1103 | if (legacy_mode & (1 << 1)) | 1063 | if (legacy_mode & ATA_PORT_SECONDARY) |
1104 | release_region(0x170, 8); | 1064 | release_region(ATA_SECONDARY_CMD, 8); |
1105 | pci_release_regions(pdev); | 1065 | pci_release_regions(pdev); |
1106 | err_out: | 1066 | err_out: |
1107 | if (disable_dev_on_err) | 1067 | if (disable_dev_on_err) |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 386e5f21e191..3f963f206d4a 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1528,7 +1528,7 @@ err_out_nosup: | |||
1528 | * Zero on success, negative errno otherwise. | 1528 | * Zero on success, negative errno otherwise. |
1529 | */ | 1529 | */ |
1530 | 1530 | ||
1531 | static int ata_bus_probe(struct ata_port *ap) | 1531 | int ata_bus_probe(struct ata_port *ap) |
1532 | { | 1532 | { |
1533 | unsigned int classes[ATA_MAX_DEVICES]; | 1533 | unsigned int classes[ATA_MAX_DEVICES]; |
1534 | int tries[ATA_MAX_DEVICES]; | 1534 | int tries[ATA_MAX_DEVICES]; |
@@ -3040,10 +3040,6 @@ static int ata_dma_blacklisted(const struct ata_device *dev) | |||
3040 | * known limits including host controller limits, device | 3040 | * known limits including host controller limits, device |
3041 | * blacklist, etc... | 3041 | * blacklist, etc... |
3042 | * | 3042 | * |
3043 | * FIXME: The current implementation limits all transfer modes to | ||
3044 | * the fastest of the lowested device on the port. This is not | ||
3045 | * required on most controllers. | ||
3046 | * | ||
3047 | * LOCKING: | 3043 | * LOCKING: |
3048 | * None. | 3044 | * None. |
3049 | */ | 3045 | */ |
@@ -3052,8 +3048,8 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
3052 | struct ata_port *ap = dev->ap; | 3048 | struct ata_port *ap = dev->ap; |
3053 | struct ata_host_set *hs = ap->host_set; | 3049 | struct ata_host_set *hs = ap->host_set; |
3054 | unsigned long xfer_mask; | 3050 | unsigned long xfer_mask; |
3055 | int i; | ||
3056 | 3051 | ||
3052 | /* controller modes available */ | ||
3057 | xfer_mask = ata_pack_xfermask(ap->pio_mask, | 3053 | xfer_mask = ata_pack_xfermask(ap->pio_mask, |
3058 | ap->mwdma_mask, ap->udma_mask); | 3054 | ap->mwdma_mask, ap->udma_mask); |
3059 | 3055 | ||
@@ -3063,34 +3059,20 @@ static void ata_dev_xfermask(struct ata_device *dev) | |||
3063 | if (ap->cbl == ATA_CBL_PATA40) | 3059 | if (ap->cbl == ATA_CBL_PATA40) |
3064 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | 3060 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); |
3065 | 3061 | ||
3066 | /* FIXME: Use port-wide xfermask for now */ | 3062 | xfer_mask &= ata_pack_xfermask(dev->pio_mask, |
3067 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 3063 | dev->mwdma_mask, dev->udma_mask); |
3068 | struct ata_device *d = &ap->device[i]; | 3064 | xfer_mask &= ata_id_xfermask(dev->id); |
3069 | |||
3070 | if (ata_dev_absent(d)) | ||
3071 | continue; | ||
3072 | |||
3073 | if (ata_dev_disabled(d)) { | ||
3074 | /* to avoid violating device selection timing */ | ||
3075 | xfer_mask &= ata_pack_xfermask(d->pio_mask, | ||
3076 | UINT_MAX, UINT_MAX); | ||
3077 | continue; | ||
3078 | } | ||
3079 | |||
3080 | xfer_mask &= ata_pack_xfermask(d->pio_mask, | ||
3081 | d->mwdma_mask, d->udma_mask); | ||
3082 | xfer_mask &= ata_id_xfermask(d->id); | ||
3083 | if (ata_dma_blacklisted(d)) | ||
3084 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
3085 | } | ||
3086 | 3065 | ||
3087 | if (ata_dma_blacklisted(dev)) | 3066 | if (ata_dma_blacklisted(dev)) { |
3067 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
3088 | ata_dev_printk(dev, KERN_WARNING, | 3068 | ata_dev_printk(dev, KERN_WARNING, |
3089 | "device is on DMA blacklist, disabling DMA\n"); | 3069 | "device is on DMA blacklist, disabling DMA\n"); |
3070 | } | ||
3090 | 3071 | ||
3091 | if (hs->flags & ATA_HOST_SIMPLEX) { | 3072 | if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) { |
3092 | if (hs->simplex_claimed) | 3073 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
3093 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 3074 | ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " |
3075 | "other device, disabling DMA\n"); | ||
3094 | } | 3076 | } |
3095 | 3077 | ||
3096 | if (ap->ops->mode_filter) | 3078 | if (ap->ops->mode_filter) |
@@ -5185,28 +5167,6 @@ void ata_host_stop (struct ata_host_set *host_set) | |||
5185 | iounmap(host_set->mmio_base); | 5167 | iounmap(host_set->mmio_base); |
5186 | } | 5168 | } |
5187 | 5169 | ||
5188 | |||
5189 | /** | ||
5190 | * ata_host_remove - Unregister SCSI host structure with upper layers | ||
5191 | * @ap: Port to unregister | ||
5192 | * @do_unregister: 1 if we fully unregister, 0 to just stop the port | ||
5193 | * | ||
5194 | * LOCKING: | ||
5195 | * Inherited from caller. | ||
5196 | */ | ||
5197 | |||
5198 | static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) | ||
5199 | { | ||
5200 | struct Scsi_Host *sh = ap->host; | ||
5201 | |||
5202 | DPRINTK("ENTER\n"); | ||
5203 | |||
5204 | if (do_unregister) | ||
5205 | scsi_remove_host(sh); | ||
5206 | |||
5207 | ap->ops->port_stop(ap); | ||
5208 | } | ||
5209 | |||
5210 | /** | 5170 | /** |
5211 | * ata_dev_init - Initialize an ata_device structure | 5171 | * ata_dev_init - Initialize an ata_device structure |
5212 | * @dev: Device structure to initialize | 5172 | * @dev: Device structure to initialize |
@@ -5240,41 +5200,29 @@ void ata_dev_init(struct ata_device *dev) | |||
5240 | } | 5200 | } |
5241 | 5201 | ||
5242 | /** | 5202 | /** |
5243 | * ata_host_init - Initialize an ata_port structure | 5203 | * ata_port_init - Initialize an ata_port structure |
5244 | * @ap: Structure to initialize | 5204 | * @ap: Structure to initialize |
5245 | * @host: associated SCSI mid-layer structure | ||
5246 | * @host_set: Collection of hosts to which @ap belongs | 5205 | * @host_set: Collection of hosts to which @ap belongs |
5247 | * @ent: Probe information provided by low-level driver | 5206 | * @ent: Probe information provided by low-level driver |
5248 | * @port_no: Port number associated with this ata_port | 5207 | * @port_no: Port number associated with this ata_port |
5249 | * | 5208 | * |
5250 | * Initialize a new ata_port structure, and its associated | 5209 | * Initialize a new ata_port structure. |
5251 | * scsi_host. | ||
5252 | * | 5210 | * |
5253 | * LOCKING: | 5211 | * LOCKING: |
5254 | * Inherited from caller. | 5212 | * Inherited from caller. |
5255 | */ | 5213 | */ |
5256 | static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | 5214 | void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, |
5257 | struct ata_host_set *host_set, | 5215 | const struct ata_probe_ent *ent, unsigned int port_no) |
5258 | const struct ata_probe_ent *ent, unsigned int port_no) | ||
5259 | { | 5216 | { |
5260 | unsigned int i; | 5217 | unsigned int i; |
5261 | 5218 | ||
5262 | host->max_id = 16; | ||
5263 | host->max_lun = 1; | ||
5264 | host->max_channel = 1; | ||
5265 | host->unique_id = ata_unique_id++; | ||
5266 | host->max_cmd_len = 12; | ||
5267 | |||
5268 | ap->lock = &host_set->lock; | 5219 | ap->lock = &host_set->lock; |
5269 | ap->flags = ATA_FLAG_DISABLED; | 5220 | ap->flags = ATA_FLAG_DISABLED; |
5270 | ap->id = host->unique_id; | 5221 | ap->id = ata_unique_id++; |
5271 | ap->host = host; | ||
5272 | ap->ctl = ATA_DEVCTL_OBS; | 5222 | ap->ctl = ATA_DEVCTL_OBS; |
5273 | ap->host_set = host_set; | 5223 | ap->host_set = host_set; |
5274 | ap->dev = ent->dev; | 5224 | ap->dev = ent->dev; |
5275 | ap->port_no = port_no; | 5225 | ap->port_no = port_no; |
5276 | ap->hard_port_no = | ||
5277 | ent->legacy_mode ? ent->hard_port_no : port_no; | ||
5278 | ap->pio_mask = ent->pio_mask; | 5226 | ap->pio_mask = ent->pio_mask; |
5279 | ap->mwdma_mask = ent->mwdma_mask; | 5227 | ap->mwdma_mask = ent->mwdma_mask; |
5280 | ap->udma_mask = ent->udma_mask; | 5228 | ap->udma_mask = ent->udma_mask; |
@@ -5320,7 +5268,28 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
5320 | } | 5268 | } |
5321 | 5269 | ||
5322 | /** | 5270 | /** |
5323 | * ata_host_add - Attach low-level ATA driver to system | 5271 | * ata_port_init_shost - Initialize SCSI host associated with ATA port |
5272 | * @ap: ATA port to initialize SCSI host for | ||
5273 | * @shost: SCSI host associated with @ap | ||
5274 | * | ||
5275 | * Initialize SCSI host @shost associated with ATA port @ap. | ||
5276 | * | ||
5277 | * LOCKING: | ||
5278 | * Inherited from caller. | ||
5279 | */ | ||
5280 | static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) | ||
5281 | { | ||
5282 | ap->host = shost; | ||
5283 | |||
5284 | shost->unique_id = ap->id; | ||
5285 | shost->max_id = 16; | ||
5286 | shost->max_lun = 1; | ||
5287 | shost->max_channel = 1; | ||
5288 | shost->max_cmd_len = 12; | ||
5289 | } | ||
5290 | |||
5291 | /** | ||
5292 | * ata_port_add - Attach low-level ATA driver to system | ||
5324 | * @ent: Information provided by low-level driver | 5293 | * @ent: Information provided by low-level driver |
5325 | * @host_set: Collections of ports to which we add | 5294 | * @host_set: Collections of ports to which we add |
5326 | * @port_no: Port number associated with this host | 5295 | * @port_no: Port number associated with this host |
@@ -5333,14 +5302,12 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
5333 | * RETURNS: | 5302 | * RETURNS: |
5334 | * New ata_port on success, for NULL on error. | 5303 | * New ata_port on success, for NULL on error. |
5335 | */ | 5304 | */ |
5336 | 5305 | static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, | |
5337 | static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, | ||
5338 | struct ata_host_set *host_set, | 5306 | struct ata_host_set *host_set, |
5339 | unsigned int port_no) | 5307 | unsigned int port_no) |
5340 | { | 5308 | { |
5341 | struct Scsi_Host *host; | 5309 | struct Scsi_Host *shost; |
5342 | struct ata_port *ap; | 5310 | struct ata_port *ap; |
5343 | int rc; | ||
5344 | 5311 | ||
5345 | DPRINTK("ENTER\n"); | 5312 | DPRINTK("ENTER\n"); |
5346 | 5313 | ||
@@ -5351,25 +5318,40 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, | |||
5351 | return NULL; | 5318 | return NULL; |
5352 | } | 5319 | } |
5353 | 5320 | ||
5354 | host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); | 5321 | shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); |
5355 | if (!host) | 5322 | if (!shost) |
5356 | return NULL; | 5323 | return NULL; |
5357 | 5324 | ||
5358 | host->transportt = &ata_scsi_transport_template; | 5325 | shost->transportt = &ata_scsi_transport_template; |
5359 | 5326 | ||
5360 | ap = ata_shost_to_port(host); | 5327 | ap = ata_shost_to_port(shost); |
5361 | 5328 | ||
5362 | ata_host_init(ap, host, host_set, ent, port_no); | 5329 | ata_port_init(ap, host_set, ent, port_no); |
5363 | 5330 | ata_port_init_shost(ap, shost); | |
5364 | rc = ap->ops->port_start(ap); | ||
5365 | if (rc) | ||
5366 | goto err_out; | ||
5367 | 5331 | ||
5368 | return ap; | 5332 | return ap; |
5333 | } | ||
5369 | 5334 | ||
5370 | err_out: | 5335 | /** |
5371 | scsi_host_put(host); | 5336 | * ata_sas_host_init - Initialize a host_set struct |
5372 | return NULL; | 5337 | * @host_set: host_set to initialize |
5338 | * @dev: device host_set is attached to | ||
5339 | * @flags: host_set flags | ||
5340 | * @ops: port_ops | ||
5341 | * | ||
5342 | * LOCKING: | ||
5343 | * PCI/etc. bus probe sem. | ||
5344 | * | ||
5345 | */ | ||
5346 | |||
5347 | void ata_host_set_init(struct ata_host_set *host_set, | ||
5348 | struct device *dev, unsigned long flags, | ||
5349 | const struct ata_port_operations *ops) | ||
5350 | { | ||
5351 | spin_lock_init(&host_set->lock); | ||
5352 | host_set->dev = dev; | ||
5353 | host_set->flags = flags; | ||
5354 | host_set->ops = ops; | ||
5373 | } | 5355 | } |
5374 | 5356 | ||
5375 | /** | 5357 | /** |
@@ -5392,7 +5374,7 @@ err_out: | |||
5392 | */ | 5374 | */ |
5393 | int ata_device_add(const struct ata_probe_ent *ent) | 5375 | int ata_device_add(const struct ata_probe_ent *ent) |
5394 | { | 5376 | { |
5395 | unsigned int count = 0, i; | 5377 | unsigned int i; |
5396 | struct device *dev = ent->dev; | 5378 | struct device *dev = ent->dev; |
5397 | struct ata_host_set *host_set; | 5379 | struct ata_host_set *host_set; |
5398 | int rc; | 5380 | int rc; |
@@ -5403,50 +5385,65 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5403 | (ent->n_ports * sizeof(void *)), GFP_KERNEL); | 5385 | (ent->n_ports * sizeof(void *)), GFP_KERNEL); |
5404 | if (!host_set) | 5386 | if (!host_set) |
5405 | return 0; | 5387 | return 0; |
5406 | spin_lock_init(&host_set->lock); | ||
5407 | 5388 | ||
5408 | host_set->dev = dev; | 5389 | ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops); |
5409 | host_set->n_ports = ent->n_ports; | 5390 | host_set->n_ports = ent->n_ports; |
5410 | host_set->irq = ent->irq; | 5391 | host_set->irq = ent->irq; |
5392 | host_set->irq2 = ent->irq2; | ||
5411 | host_set->mmio_base = ent->mmio_base; | 5393 | host_set->mmio_base = ent->mmio_base; |
5412 | host_set->private_data = ent->private_data; | 5394 | host_set->private_data = ent->private_data; |
5413 | host_set->ops = ent->port_ops; | ||
5414 | host_set->flags = ent->host_set_flags; | ||
5415 | 5395 | ||
5416 | /* register each port bound to this device */ | 5396 | /* register each port bound to this device */ |
5417 | for (i = 0; i < ent->n_ports; i++) { | 5397 | for (i = 0; i < host_set->n_ports; i++) { |
5418 | struct ata_port *ap; | 5398 | struct ata_port *ap; |
5419 | unsigned long xfer_mode_mask; | 5399 | unsigned long xfer_mode_mask; |
5400 | int irq_line = ent->irq; | ||
5420 | 5401 | ||
5421 | ap = ata_host_add(ent, host_set, i); | 5402 | ap = ata_port_add(ent, host_set, i); |
5422 | if (!ap) | 5403 | if (!ap) |
5423 | goto err_out; | 5404 | goto err_out; |
5424 | 5405 | ||
5425 | host_set->ports[i] = ap; | 5406 | host_set->ports[i] = ap; |
5407 | |||
5408 | /* dummy? */ | ||
5409 | if (ent->dummy_port_mask & (1 << i)) { | ||
5410 | ata_port_printk(ap, KERN_INFO, "DUMMY\n"); | ||
5411 | ap->ops = &ata_dummy_port_ops; | ||
5412 | continue; | ||
5413 | } | ||
5414 | |||
5415 | /* start port */ | ||
5416 | rc = ap->ops->port_start(ap); | ||
5417 | if (rc) { | ||
5418 | host_set->ports[i] = NULL; | ||
5419 | scsi_host_put(ap->host); | ||
5420 | goto err_out; | ||
5421 | } | ||
5422 | |||
5423 | /* Report the secondary IRQ for second channel legacy */ | ||
5424 | if (i == 1 && ent->irq2) | ||
5425 | irq_line = ent->irq2; | ||
5426 | |||
5426 | xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | | 5427 | xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | |
5427 | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | | 5428 | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | |
5428 | (ap->pio_mask << ATA_SHIFT_PIO); | 5429 | (ap->pio_mask << ATA_SHIFT_PIO); |
5429 | 5430 | ||
5430 | /* print per-port info to dmesg */ | 5431 | /* print per-port info to dmesg */ |
5431 | ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " | 5432 | ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " |
5432 | "ctl 0x%lX bmdma 0x%lX irq %lu\n", | 5433 | "ctl 0x%lX bmdma 0x%lX irq %d\n", |
5433 | ap->flags & ATA_FLAG_SATA ? 'S' : 'P', | 5434 | ap->flags & ATA_FLAG_SATA ? 'S' : 'P', |
5434 | ata_mode_string(xfer_mode_mask), | 5435 | ata_mode_string(xfer_mode_mask), |
5435 | ap->ioaddr.cmd_addr, | 5436 | ap->ioaddr.cmd_addr, |
5436 | ap->ioaddr.ctl_addr, | 5437 | ap->ioaddr.ctl_addr, |
5437 | ap->ioaddr.bmdma_addr, | 5438 | ap->ioaddr.bmdma_addr, |
5438 | ent->irq); | 5439 | irq_line); |
5439 | 5440 | ||
5440 | ata_chk_status(ap); | 5441 | ata_chk_status(ap); |
5441 | host_set->ops->irq_clear(ap); | 5442 | host_set->ops->irq_clear(ap); |
5442 | ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ | 5443 | ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ |
5443 | count++; | ||
5444 | } | 5444 | } |
5445 | 5445 | ||
5446 | if (!count) | 5446 | /* obtain irq, that may be shared between channels */ |
5447 | goto err_free_ret; | ||
5448 | |||
5449 | /* obtain irq, that is shared between channels */ | ||
5450 | rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, | 5447 | rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, |
5451 | DRV_NAME, host_set); | 5448 | DRV_NAME, host_set); |
5452 | if (rc) { | 5449 | if (rc) { |
@@ -5455,15 +5452,28 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5455 | goto err_out; | 5452 | goto err_out; |
5456 | } | 5453 | } |
5457 | 5454 | ||
5455 | /* do we have a second IRQ for the other channel, eg legacy mode */ | ||
5456 | if (ent->irq2) { | ||
5457 | /* We will get weird core code crashes later if this is true | ||
5458 | so trap it now */ | ||
5459 | BUG_ON(ent->irq == ent->irq2); | ||
5460 | |||
5461 | rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags, | ||
5462 | DRV_NAME, host_set); | ||
5463 | if (rc) { | ||
5464 | dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", | ||
5465 | ent->irq2, rc); | ||
5466 | goto err_out_free_irq; | ||
5467 | } | ||
5468 | } | ||
5469 | |||
5458 | /* perform each probe synchronously */ | 5470 | /* perform each probe synchronously */ |
5459 | DPRINTK("probe begin\n"); | 5471 | DPRINTK("probe begin\n"); |
5460 | for (i = 0; i < count; i++) { | 5472 | for (i = 0; i < host_set->n_ports; i++) { |
5461 | struct ata_port *ap; | 5473 | struct ata_port *ap = host_set->ports[i]; |
5462 | u32 scontrol; | 5474 | u32 scontrol; |
5463 | int rc; | 5475 | int rc; |
5464 | 5476 | ||
5465 | ap = host_set->ports[i]; | ||
5466 | |||
5467 | /* init sata_spd_limit to the current value */ | 5477 | /* init sata_spd_limit to the current value */ |
5468 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { | 5478 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { |
5469 | int spd = (scontrol >> 4) & 0xf; | 5479 | int spd = (scontrol >> 4) & 0xf; |
@@ -5519,7 +5529,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5519 | 5529 | ||
5520 | /* probes are done, now scan each port's disk(s) */ | 5530 | /* probes are done, now scan each port's disk(s) */ |
5521 | DPRINTK("host probe begin\n"); | 5531 | DPRINTK("host probe begin\n"); |
5522 | for (i = 0; i < count; i++) { | 5532 | for (i = 0; i < host_set->n_ports; i++) { |
5523 | struct ata_port *ap = host_set->ports[i]; | 5533 | struct ata_port *ap = host_set->ports[i]; |
5524 | 5534 | ||
5525 | ata_scsi_scan_host(ap); | 5535 | ata_scsi_scan_host(ap); |
@@ -5530,12 +5540,17 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5530 | VPRINTK("EXIT, returning %u\n", ent->n_ports); | 5540 | VPRINTK("EXIT, returning %u\n", ent->n_ports); |
5531 | return ent->n_ports; /* success */ | 5541 | return ent->n_ports; /* success */ |
5532 | 5542 | ||
5543 | err_out_free_irq: | ||
5544 | free_irq(ent->irq, host_set); | ||
5533 | err_out: | 5545 | err_out: |
5534 | for (i = 0; i < count; i++) { | 5546 | for (i = 0; i < host_set->n_ports; i++) { |
5535 | ata_host_remove(host_set->ports[i], 1); | 5547 | struct ata_port *ap = host_set->ports[i]; |
5536 | scsi_host_put(host_set->ports[i]->host); | 5548 | if (ap) { |
5549 | ap->ops->port_stop(ap); | ||
5550 | scsi_host_put(ap->host); | ||
5551 | } | ||
5537 | } | 5552 | } |
5538 | err_free_ret: | 5553 | |
5539 | kfree(host_set); | 5554 | kfree(host_set); |
5540 | VPRINTK("EXIT, returning 0\n"); | 5555 | VPRINTK("EXIT, returning 0\n"); |
5541 | return 0; | 5556 | return 0; |
@@ -5558,7 +5573,7 @@ void ata_port_detach(struct ata_port *ap) | |||
5558 | int i; | 5573 | int i; |
5559 | 5574 | ||
5560 | if (!ap->ops->error_handler) | 5575 | if (!ap->ops->error_handler) |
5561 | return; | 5576 | goto skip_eh; |
5562 | 5577 | ||
5563 | /* tell EH we're leaving & flush EH */ | 5578 | /* tell EH we're leaving & flush EH */ |
5564 | spin_lock_irqsave(ap->lock, flags); | 5579 | spin_lock_irqsave(ap->lock, flags); |
@@ -5594,6 +5609,7 @@ void ata_port_detach(struct ata_port *ap) | |||
5594 | cancel_delayed_work(&ap->hotplug_task); | 5609 | cancel_delayed_work(&ap->hotplug_task); |
5595 | flush_workqueue(ata_aux_wq); | 5610 | flush_workqueue(ata_aux_wq); |
5596 | 5611 | ||
5612 | skip_eh: | ||
5597 | /* remove the associated SCSI host */ | 5613 | /* remove the associated SCSI host */ |
5598 | scsi_remove_host(ap->host); | 5614 | scsi_remove_host(ap->host); |
5599 | } | 5615 | } |
@@ -5617,6 +5633,8 @@ void ata_host_set_remove(struct ata_host_set *host_set) | |||
5617 | ata_port_detach(host_set->ports[i]); | 5633 | ata_port_detach(host_set->ports[i]); |
5618 | 5634 | ||
5619 | free_irq(host_set->irq, host_set); | 5635 | free_irq(host_set->irq, host_set); |
5636 | if (host_set->irq2) | ||
5637 | free_irq(host_set->irq2, host_set); | ||
5620 | 5638 | ||
5621 | for (i = 0; i < host_set->n_ports; i++) { | 5639 | for (i = 0; i < host_set->n_ports; i++) { |
5622 | struct ata_port *ap = host_set->ports[i]; | 5640 | struct ata_port *ap = host_set->ports[i]; |
@@ -5626,10 +5644,11 @@ void ata_host_set_remove(struct ata_host_set *host_set) | |||
5626 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { | 5644 | if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { |
5627 | struct ata_ioports *ioaddr = &ap->ioaddr; | 5645 | struct ata_ioports *ioaddr = &ap->ioaddr; |
5628 | 5646 | ||
5629 | if (ioaddr->cmd_addr == 0x1f0) | 5647 | /* FIXME: Add -ac IDE pci mods to remove these special cases */ |
5630 | release_region(0x1f0, 8); | 5648 | if (ioaddr->cmd_addr == ATA_PRIMARY_CMD) |
5631 | else if (ioaddr->cmd_addr == 0x170) | 5649 | release_region(ATA_PRIMARY_CMD, 8); |
5632 | release_region(0x170, 8); | 5650 | else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD) |
5651 | release_region(ATA_SECONDARY_CMD, 8); | ||
5633 | } | 5652 | } |
5634 | 5653 | ||
5635 | scsi_host_put(ap->host); | 5654 | scsi_host_put(ap->host); |
@@ -5662,12 +5681,37 @@ int ata_scsi_release(struct Scsi_Host *host) | |||
5662 | DPRINTK("ENTER\n"); | 5681 | DPRINTK("ENTER\n"); |
5663 | 5682 | ||
5664 | ap->ops->port_disable(ap); | 5683 | ap->ops->port_disable(ap); |
5665 | ata_host_remove(ap, 0); | 5684 | ap->ops->port_stop(ap); |
5666 | 5685 | ||
5667 | DPRINTK("EXIT\n"); | 5686 | DPRINTK("EXIT\n"); |
5668 | return 1; | 5687 | return 1; |
5669 | } | 5688 | } |
5670 | 5689 | ||
5690 | struct ata_probe_ent * | ||
5691 | ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | ||
5692 | { | ||
5693 | struct ata_probe_ent *probe_ent; | ||
5694 | |||
5695 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
5696 | if (!probe_ent) { | ||
5697 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | ||
5698 | kobject_name(&(dev->kobj))); | ||
5699 | return NULL; | ||
5700 | } | ||
5701 | |||
5702 | INIT_LIST_HEAD(&probe_ent->node); | ||
5703 | probe_ent->dev = dev; | ||
5704 | |||
5705 | probe_ent->sht = port->sht; | ||
5706 | probe_ent->host_flags = port->host_flags; | ||
5707 | probe_ent->pio_mask = port->pio_mask; | ||
5708 | probe_ent->mwdma_mask = port->mwdma_mask; | ||
5709 | probe_ent->udma_mask = port->udma_mask; | ||
5710 | probe_ent->port_ops = port->port_ops; | ||
5711 | |||
5712 | return probe_ent; | ||
5713 | } | ||
5714 | |||
5671 | /** | 5715 | /** |
5672 | * ata_std_ports - initialize ioaddr with standard port offsets. | 5716 | * ata_std_ports - initialize ioaddr with standard port offsets. |
5673 | * @ioaddr: IO address structure to be initialized | 5717 | * @ioaddr: IO address structure to be initialized |
@@ -5722,11 +5766,8 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
5722 | { | 5766 | { |
5723 | struct device *dev = pci_dev_to_dev(pdev); | 5767 | struct device *dev = pci_dev_to_dev(pdev); |
5724 | struct ata_host_set *host_set = dev_get_drvdata(dev); | 5768 | struct ata_host_set *host_set = dev_get_drvdata(dev); |
5725 | struct ata_host_set *host_set2 = host_set->next; | ||
5726 | 5769 | ||
5727 | ata_host_set_remove(host_set); | 5770 | ata_host_set_remove(host_set); |
5728 | if (host_set2) | ||
5729 | ata_host_set_remove(host_set2); | ||
5730 | 5771 | ||
5731 | pci_release_regions(pdev); | 5772 | pci_release_regions(pdev); |
5732 | pci_disable_device(pdev); | 5773 | pci_disable_device(pdev); |
@@ -5767,11 +5808,11 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) | |||
5767 | return (tmp == bits->val) ? 1 : 0; | 5808 | return (tmp == bits->val) ? 1 : 0; |
5768 | } | 5809 | } |
5769 | 5810 | ||
5770 | void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state) | 5811 | void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) |
5771 | { | 5812 | { |
5772 | pci_save_state(pdev); | 5813 | pci_save_state(pdev); |
5773 | 5814 | ||
5774 | if (state.event == PM_EVENT_SUSPEND) { | 5815 | if (mesg.event == PM_EVENT_SUSPEND) { |
5775 | pci_disable_device(pdev); | 5816 | pci_disable_device(pdev); |
5776 | pci_set_power_state(pdev, PCI_D3hot); | 5817 | pci_set_power_state(pdev, PCI_D3hot); |
5777 | } | 5818 | } |
@@ -5785,24 +5826,16 @@ void ata_pci_device_do_resume(struct pci_dev *pdev) | |||
5785 | pci_set_master(pdev); | 5826 | pci_set_master(pdev); |
5786 | } | 5827 | } |
5787 | 5828 | ||
5788 | int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state) | 5829 | int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) |
5789 | { | 5830 | { |
5790 | struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); | 5831 | struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); |
5791 | int rc = 0; | 5832 | int rc = 0; |
5792 | 5833 | ||
5793 | rc = ata_host_set_suspend(host_set, state); | 5834 | rc = ata_host_set_suspend(host_set, mesg); |
5794 | if (rc) | 5835 | if (rc) |
5795 | return rc; | 5836 | return rc; |
5796 | 5837 | ||
5797 | if (host_set->next) { | 5838 | ata_pci_device_do_suspend(pdev, mesg); |
5798 | rc = ata_host_set_suspend(host_set->next, state); | ||
5799 | if (rc) { | ||
5800 | ata_host_set_resume(host_set); | ||
5801 | return rc; | ||
5802 | } | ||
5803 | } | ||
5804 | |||
5805 | ata_pci_device_do_suspend(pdev, state); | ||
5806 | 5839 | ||
5807 | return 0; | 5840 | return 0; |
5808 | } | 5841 | } |
@@ -5813,9 +5846,6 @@ int ata_pci_device_resume(struct pci_dev *pdev) | |||
5813 | 5846 | ||
5814 | ata_pci_device_do_resume(pdev); | 5847 | ata_pci_device_do_resume(pdev); |
5815 | ata_host_set_resume(host_set); | 5848 | ata_host_set_resume(host_set); |
5816 | if (host_set->next) | ||
5817 | ata_host_set_resume(host_set->next); | ||
5818 | |||
5819 | return 0; | 5849 | return 0; |
5820 | } | 5850 | } |
5821 | #endif /* CONFIG_PCI */ | 5851 | #endif /* CONFIG_PCI */ |
@@ -5915,6 +5945,39 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, | |||
5915 | } | 5945 | } |
5916 | 5946 | ||
5917 | /* | 5947 | /* |
5948 | * Dummy port_ops | ||
5949 | */ | ||
5950 | static void ata_dummy_noret(struct ata_port *ap) { } | ||
5951 | static int ata_dummy_ret0(struct ata_port *ap) { return 0; } | ||
5952 | static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { } | ||
5953 | |||
5954 | static u8 ata_dummy_check_status(struct ata_port *ap) | ||
5955 | { | ||
5956 | return ATA_DRDY; | ||
5957 | } | ||
5958 | |||
5959 | static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc) | ||
5960 | { | ||
5961 | return AC_ERR_SYSTEM; | ||
5962 | } | ||
5963 | |||
5964 | const struct ata_port_operations ata_dummy_port_ops = { | ||
5965 | .port_disable = ata_port_disable, | ||
5966 | .check_status = ata_dummy_check_status, | ||
5967 | .check_altstatus = ata_dummy_check_status, | ||
5968 | .dev_select = ata_noop_dev_select, | ||
5969 | .qc_prep = ata_noop_qc_prep, | ||
5970 | .qc_issue = ata_dummy_qc_issue, | ||
5971 | .freeze = ata_dummy_noret, | ||
5972 | .thaw = ata_dummy_noret, | ||
5973 | .error_handler = ata_dummy_noret, | ||
5974 | .post_internal_cmd = ata_dummy_qc_noret, | ||
5975 | .irq_clear = ata_dummy_noret, | ||
5976 | .port_start = ata_dummy_ret0, | ||
5977 | .port_stop = ata_dummy_noret, | ||
5978 | }; | ||
5979 | |||
5980 | /* | ||
5918 | * libata is essentially a library of internal helper functions for | 5981 | * libata is essentially a library of internal helper functions for |
5919 | * low-level ATA host controller drivers. As such, the API/ABI is | 5982 | * low-level ATA host controller drivers. As such, the API/ABI is |
5920 | * likely to change as new drivers are added and updated. | 5983 | * likely to change as new drivers are added and updated. |
@@ -5924,8 +5987,10 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, | |||
5924 | EXPORT_SYMBOL_GPL(sata_deb_timing_normal); | 5987 | EXPORT_SYMBOL_GPL(sata_deb_timing_normal); |
5925 | EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); | 5988 | EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); |
5926 | EXPORT_SYMBOL_GPL(sata_deb_timing_long); | 5989 | EXPORT_SYMBOL_GPL(sata_deb_timing_long); |
5990 | EXPORT_SYMBOL_GPL(ata_dummy_port_ops); | ||
5927 | EXPORT_SYMBOL_GPL(ata_std_bios_param); | 5991 | EXPORT_SYMBOL_GPL(ata_std_bios_param); |
5928 | EXPORT_SYMBOL_GPL(ata_std_ports); | 5992 | EXPORT_SYMBOL_GPL(ata_std_ports); |
5993 | EXPORT_SYMBOL_GPL(ata_host_set_init); | ||
5929 | EXPORT_SYMBOL_GPL(ata_device_add); | 5994 | EXPORT_SYMBOL_GPL(ata_device_add); |
5930 | EXPORT_SYMBOL_GPL(ata_port_detach); | 5995 | EXPORT_SYMBOL_GPL(ata_port_detach); |
5931 | EXPORT_SYMBOL_GPL(ata_host_set_remove); | 5996 | EXPORT_SYMBOL_GPL(ata_host_set_remove); |
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c index 4b6aa30f4d68..29f59345305d 100644 --- a/drivers/scsi/libata-eh.c +++ b/drivers/scsi/libata-eh.c | |||
@@ -764,12 +764,27 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
764 | unsigned int action) | 764 | unsigned int action) |
765 | { | 765 | { |
766 | unsigned long flags; | 766 | unsigned long flags; |
767 | struct ata_eh_info *ehi = &ap->eh_info; | ||
768 | struct ata_eh_context *ehc = &ap->eh_context; | ||
767 | 769 | ||
768 | spin_lock_irqsave(ap->lock, flags); | 770 | spin_lock_irqsave(ap->lock, flags); |
769 | 771 | ||
770 | ata_eh_clear_action(dev, &ap->eh_info, action); | 772 | /* Reset is represented by combination of actions and EHI |
773 | * flags. Suck in all related bits before clearing eh_info to | ||
774 | * avoid losing requested action. | ||
775 | */ | ||
776 | if (action & ATA_EH_RESET_MASK) { | ||
777 | ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; | ||
778 | ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; | ||
779 | |||
780 | /* make sure all reset actions are cleared & clear EHI flags */ | ||
781 | action |= ATA_EH_RESET_MASK; | ||
782 | ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
783 | } | ||
784 | |||
785 | ata_eh_clear_action(dev, ehi, action); | ||
771 | 786 | ||
772 | if (!(ap->eh_context.i.flags & ATA_EHI_QUIET)) | 787 | if (!(ehc->i.flags & ATA_EHI_QUIET)) |
773 | ap->pflags |= ATA_PFLAG_RECOVERED; | 788 | ap->pflags |= ATA_PFLAG_RECOVERED; |
774 | 789 | ||
775 | spin_unlock_irqrestore(ap->lock, flags); | 790 | spin_unlock_irqrestore(ap->lock, flags); |
@@ -790,6 +805,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, | |||
790 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, | 805 | static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, |
791 | unsigned int action) | 806 | unsigned int action) |
792 | { | 807 | { |
808 | /* if reset is complete, clear all reset actions & reset modifier */ | ||
809 | if (action & ATA_EH_RESET_MASK) { | ||
810 | action |= ATA_EH_RESET_MASK; | ||
811 | ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; | ||
812 | } | ||
813 | |||
793 | ata_eh_clear_action(dev, &ap->eh_context.i, action); | 814 | ata_eh_clear_action(dev, &ap->eh_context.i, action); |
794 | } | 815 | } |
795 | 816 | ||
@@ -1276,8 +1297,6 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io, | |||
1276 | static void ata_eh_autopsy(struct ata_port *ap) | 1297 | static void ata_eh_autopsy(struct ata_port *ap) |
1277 | { | 1298 | { |
1278 | struct ata_eh_context *ehc = &ap->eh_context; | 1299 | struct ata_eh_context *ehc = &ap->eh_context; |
1279 | unsigned int action = ehc->i.action; | ||
1280 | struct ata_device *failed_dev = NULL; | ||
1281 | unsigned int all_err_mask = 0; | 1300 | unsigned int all_err_mask = 0; |
1282 | int tag, is_io = 0; | 1301 | int tag, is_io = 0; |
1283 | u32 serror; | 1302 | u32 serror; |
@@ -1294,7 +1313,7 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1294 | ehc->i.serror |= serror; | 1313 | ehc->i.serror |= serror; |
1295 | ata_eh_analyze_serror(ap); | 1314 | ata_eh_analyze_serror(ap); |
1296 | } else if (rc != -EOPNOTSUPP) | 1315 | } else if (rc != -EOPNOTSUPP) |
1297 | action |= ATA_EH_HARDRESET; | 1316 | ehc->i.action |= ATA_EH_HARDRESET; |
1298 | 1317 | ||
1299 | /* analyze NCQ failure */ | 1318 | /* analyze NCQ failure */ |
1300 | ata_eh_analyze_ncq_error(ap); | 1319 | ata_eh_analyze_ncq_error(ap); |
@@ -1315,7 +1334,7 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1315 | qc->err_mask |= ehc->i.err_mask; | 1334 | qc->err_mask |= ehc->i.err_mask; |
1316 | 1335 | ||
1317 | /* analyze TF */ | 1336 | /* analyze TF */ |
1318 | action |= ata_eh_analyze_tf(qc, &qc->result_tf); | 1337 | ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); |
1319 | 1338 | ||
1320 | /* DEV errors are probably spurious in case of ATA_BUS error */ | 1339 | /* DEV errors are probably spurious in case of ATA_BUS error */ |
1321 | if (qc->err_mask & AC_ERR_ATA_BUS) | 1340 | if (qc->err_mask & AC_ERR_ATA_BUS) |
@@ -1329,11 +1348,11 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1329 | /* SENSE_VALID trumps dev/unknown error and revalidation */ | 1348 | /* SENSE_VALID trumps dev/unknown error and revalidation */ |
1330 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { | 1349 | if (qc->flags & ATA_QCFLAG_SENSE_VALID) { |
1331 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); | 1350 | qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); |
1332 | action &= ~ATA_EH_REVALIDATE; | 1351 | ehc->i.action &= ~ATA_EH_REVALIDATE; |
1333 | } | 1352 | } |
1334 | 1353 | ||
1335 | /* accumulate error info */ | 1354 | /* accumulate error info */ |
1336 | failed_dev = qc->dev; | 1355 | ehc->i.dev = qc->dev; |
1337 | all_err_mask |= qc->err_mask; | 1356 | all_err_mask |= qc->err_mask; |
1338 | if (qc->flags & ATA_QCFLAG_IO) | 1357 | if (qc->flags & ATA_QCFLAG_IO) |
1339 | is_io = 1; | 1358 | is_io = 1; |
@@ -1342,25 +1361,22 @@ static void ata_eh_autopsy(struct ata_port *ap) | |||
1342 | /* enforce default EH actions */ | 1361 | /* enforce default EH actions */ |
1343 | if (ap->pflags & ATA_PFLAG_FROZEN || | 1362 | if (ap->pflags & ATA_PFLAG_FROZEN || |
1344 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) | 1363 | all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) |
1345 | action |= ATA_EH_SOFTRESET; | 1364 | ehc->i.action |= ATA_EH_SOFTRESET; |
1346 | else if (all_err_mask) | 1365 | else if (all_err_mask) |
1347 | action |= ATA_EH_REVALIDATE; | 1366 | ehc->i.action |= ATA_EH_REVALIDATE; |
1348 | 1367 | ||
1349 | /* if we have offending qcs and the associated failed device */ | 1368 | /* if we have offending qcs and the associated failed device */ |
1350 | if (failed_dev) { | 1369 | if (ehc->i.dev) { |
1351 | /* speed down */ | 1370 | /* speed down */ |
1352 | action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); | 1371 | ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io, |
1372 | all_err_mask); | ||
1353 | 1373 | ||
1354 | /* perform per-dev EH action only on the offending device */ | 1374 | /* perform per-dev EH action only on the offending device */ |
1355 | ehc->i.dev_action[failed_dev->devno] |= | 1375 | ehc->i.dev_action[ehc->i.dev->devno] |= |
1356 | action & ATA_EH_PERDEV_MASK; | 1376 | ehc->i.action & ATA_EH_PERDEV_MASK; |
1357 | action &= ~ATA_EH_PERDEV_MASK; | 1377 | ehc->i.action &= ~ATA_EH_PERDEV_MASK; |
1358 | } | 1378 | } |
1359 | 1379 | ||
1360 | /* record autopsy result */ | ||
1361 | ehc->i.dev = failed_dev; | ||
1362 | ehc->i.action |= action; | ||
1363 | |||
1364 | DPRINTK("EXIT\n"); | 1380 | DPRINTK("EXIT\n"); |
1365 | } | 1381 | } |
1366 | 1382 | ||
@@ -1483,6 +1499,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1483 | ata_reset_fn_t reset; | 1499 | ata_reset_fn_t reset; |
1484 | int i, did_followup_srst, rc; | 1500 | int i, did_followup_srst, rc; |
1485 | 1501 | ||
1502 | /* about to reset */ | ||
1503 | ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); | ||
1504 | |||
1486 | /* Determine which reset to use and record in ehc->i.action. | 1505 | /* Determine which reset to use and record in ehc->i.action. |
1487 | * prereset() may examine and modify it. | 1506 | * prereset() may examine and modify it. |
1488 | */ | 1507 | */ |
@@ -1531,8 +1550,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1531 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", | 1550 | ata_port_printk(ap, KERN_INFO, "%s resetting port\n", |
1532 | reset == softreset ? "soft" : "hard"); | 1551 | reset == softreset ? "soft" : "hard"); |
1533 | 1552 | ||
1534 | /* reset */ | 1553 | /* mark that this EH session started with reset */ |
1535 | ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); | ||
1536 | ehc->i.flags |= ATA_EHI_DID_RESET; | 1554 | ehc->i.flags |= ATA_EHI_DID_RESET; |
1537 | 1555 | ||
1538 | rc = ata_do_reset(ap, reset, classes); | 1556 | rc = ata_do_reset(ap, reset, classes); |
@@ -1595,7 +1613,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, | |||
1595 | postreset(ap, classes); | 1613 | postreset(ap, classes); |
1596 | 1614 | ||
1597 | /* reset successful, schedule revalidation */ | 1615 | /* reset successful, schedule revalidation */ |
1598 | ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); | 1616 | ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); |
1599 | ehc->i.action |= ATA_EH_REVALIDATE; | 1617 | ehc->i.action |= ATA_EH_REVALIDATE; |
1600 | } | 1618 | } |
1601 | 1619 | ||
@@ -1848,15 +1866,16 @@ static int ata_eh_skip_recovery(struct ata_port *ap) | |||
1848 | for (i = 0; i < ata_port_max_devices(ap); i++) { | 1866 | for (i = 0; i < ata_port_max_devices(ap); i++) { |
1849 | struct ata_device *dev = &ap->device[i]; | 1867 | struct ata_device *dev = &ap->device[i]; |
1850 | 1868 | ||
1851 | if (ata_dev_absent(dev) || ata_dev_ready(dev)) | 1869 | if (!(dev->flags & ATA_DFLAG_SUSPENDED)) |
1852 | break; | 1870 | break; |
1853 | } | 1871 | } |
1854 | 1872 | ||
1855 | if (i == ata_port_max_devices(ap)) | 1873 | if (i == ata_port_max_devices(ap)) |
1856 | return 1; | 1874 | return 1; |
1857 | 1875 | ||
1858 | /* always thaw frozen port and recover failed devices */ | 1876 | /* thaw frozen port, resume link and recover failed devices */ |
1859 | if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap)) | 1877 | if ((ap->pflags & ATA_PFLAG_FROZEN) || |
1878 | (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) | ||
1860 | return 0; | 1879 | return 0; |
1861 | 1880 | ||
1862 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ | 1881 | /* skip if class codes for all vacant slots are ATA_DEV_NONE */ |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 7ced41ecde86..d168e3413661 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -400,7 +400,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) | |||
400 | /** | 400 | /** |
401 | * ata_scsi_device_suspend - suspend ATA device associated with sdev | 401 | * ata_scsi_device_suspend - suspend ATA device associated with sdev |
402 | * @sdev: the SCSI device to suspend | 402 | * @sdev: the SCSI device to suspend |
403 | * @state: target power management state | 403 | * @mesg: target power management message |
404 | * | 404 | * |
405 | * Request suspend EH action on the ATA device associated with | 405 | * Request suspend EH action on the ATA device associated with |
406 | * @sdev and wait for the operation to complete. | 406 | * @sdev and wait for the operation to complete. |
@@ -411,7 +411,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) | |||
411 | * RETURNS: | 411 | * RETURNS: |
412 | * 0 on success, -errno otherwise. | 412 | * 0 on success, -errno otherwise. |
413 | */ | 413 | */ |
414 | int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) | 414 | int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) |
415 | { | 415 | { |
416 | struct ata_port *ap = ata_shost_to_port(sdev->host); | 416 | struct ata_port *ap = ata_shost_to_port(sdev->host); |
417 | struct ata_device *dev = ata_scsi_find_dev(ap, sdev); | 417 | struct ata_device *dev = ata_scsi_find_dev(ap, sdev); |
@@ -438,7 +438,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) | |||
438 | 438 | ||
439 | /* request suspend */ | 439 | /* request suspend */ |
440 | action = ATA_EH_SUSPEND; | 440 | action = ATA_EH_SUSPEND; |
441 | if (state.event != PM_EVENT_SUSPEND) | 441 | if (mesg.event != PM_EVENT_SUSPEND) |
442 | action |= ATA_EH_PM_FREEZE; | 442 | action |= ATA_EH_PM_FREEZE; |
443 | ap->eh_info.dev_action[dev->devno] |= action; | 443 | ap->eh_info.dev_action[dev->devno] |= action; |
444 | ap->eh_info.flags |= ATA_EHI_QUIET; | 444 | ap->eh_info.flags |= ATA_EHI_QUIET; |
@@ -463,7 +463,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) | |||
463 | spin_unlock_irqrestore(ap->lock, flags); | 463 | spin_unlock_irqrestore(ap->lock, flags); |
464 | out: | 464 | out: |
465 | if (rc == 0) | 465 | if (rc == 0) |
466 | sdev->sdev_gendev.power.power_state = state; | 466 | sdev->sdev_gendev.power.power_state = mesg; |
467 | return rc; | 467 | return rc; |
468 | } | 468 | } |
469 | 469 | ||
@@ -2353,6 +2353,19 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) | |||
2353 | ata_gen_ata_desc_sense(qc); | 2353 | ata_gen_ata_desc_sense(qc); |
2354 | } | 2354 | } |
2355 | 2355 | ||
2356 | /* SCSI EH automatically locks door if sdev->locked is | ||
2357 | * set. Sometimes door lock request continues to | ||
2358 | * fail, for example, when no media is present. This | ||
2359 | * creates a loop - SCSI EH issues door lock which | ||
2360 | * fails and gets invoked again to acquire sense data | ||
2361 | * for the failed command. | ||
2362 | * | ||
2363 | * If door lock fails, always clear sdev->locked to | ||
2364 | * avoid this infinite loop. | ||
2365 | */ | ||
2366 | if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) | ||
2367 | qc->dev->sdev->locked = 0; | ||
2368 | |||
2356 | qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; | 2369 | qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; |
2357 | qc->scsidone(cmd); | 2370 | qc->scsidone(cmd); |
2358 | ata_qc_free(qc); | 2371 | ata_qc_free(qc); |
@@ -3158,3 +3171,152 @@ void ata_scsi_dev_rescan(void *data) | |||
3158 | scsi_rescan_device(&(dev->sdev->sdev_gendev)); | 3171 | scsi_rescan_device(&(dev->sdev->sdev_gendev)); |
3159 | } | 3172 | } |
3160 | } | 3173 | } |
3174 | |||
3175 | /** | ||
3176 | * ata_sas_port_alloc - Allocate port for a SAS attached SATA device | ||
3177 | * @pdev: PCI device that the scsi device is attached to | ||
3178 | * @port_info: Information from low-level host driver | ||
3179 | * @host: SCSI host that the scsi device is attached to | ||
3180 | * | ||
3181 | * LOCKING: | ||
3182 | * PCI/etc. bus probe sem. | ||
3183 | * | ||
3184 | * RETURNS: | ||
3185 | * ata_port pointer on success / NULL on failure. | ||
3186 | */ | ||
3187 | |||
3188 | struct ata_port *ata_sas_port_alloc(struct ata_host_set *host_set, | ||
3189 | struct ata_port_info *port_info, | ||
3190 | struct Scsi_Host *host) | ||
3191 | { | ||
3192 | struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); | ||
3193 | struct ata_probe_ent *ent; | ||
3194 | |||
3195 | if (!ap) | ||
3196 | return NULL; | ||
3197 | |||
3198 | ent = ata_probe_ent_alloc(host_set->dev, port_info); | ||
3199 | if (!ent) { | ||
3200 | kfree(ap); | ||
3201 | return NULL; | ||
3202 | } | ||
3203 | |||
3204 | ata_port_init(ap, host_set, ent, 0); | ||
3205 | ap->lock = host->host_lock; | ||
3206 | kfree(ent); | ||
3207 | return ap; | ||
3208 | } | ||
3209 | EXPORT_SYMBOL_GPL(ata_sas_port_alloc); | ||
3210 | |||
3211 | /** | ||
3212 | * ata_sas_port_start - Set port up for dma. | ||
3213 | * @ap: Port to initialize | ||
3214 | * | ||
3215 | * Called just after data structures for each port are | ||
3216 | * initialized. Allocates DMA pad. | ||
3217 | * | ||
3218 | * May be used as the port_start() entry in ata_port_operations. | ||
3219 | * | ||
3220 | * LOCKING: | ||
3221 | * Inherited from caller. | ||
3222 | */ | ||
3223 | int ata_sas_port_start(struct ata_port *ap) | ||
3224 | { | ||
3225 | return ata_pad_alloc(ap, ap->dev); | ||
3226 | } | ||
3227 | EXPORT_SYMBOL_GPL(ata_sas_port_start); | ||
3228 | |||
3229 | /** | ||
3230 | * ata_port_stop - Undo ata_sas_port_start() | ||
3231 | * @ap: Port to shut down | ||
3232 | * | ||
3233 | * Frees the DMA pad. | ||
3234 | * | ||
3235 | * May be used as the port_stop() entry in ata_port_operations. | ||
3236 | * | ||
3237 | * LOCKING: | ||
3238 | * Inherited from caller. | ||
3239 | */ | ||
3240 | |||
3241 | void ata_sas_port_stop(struct ata_port *ap) | ||
3242 | { | ||
3243 | ata_pad_free(ap, ap->dev); | ||
3244 | } | ||
3245 | EXPORT_SYMBOL_GPL(ata_sas_port_stop); | ||
3246 | |||
3247 | /** | ||
3248 | * ata_sas_port_init - Initialize a SATA device | ||
3249 | * @ap: SATA port to initialize | ||
3250 | * | ||
3251 | * LOCKING: | ||
3252 | * PCI/etc. bus probe sem. | ||
3253 | * | ||
3254 | * RETURNS: | ||
3255 | * Zero on success, non-zero on error. | ||
3256 | */ | ||
3257 | |||
3258 | int ata_sas_port_init(struct ata_port *ap) | ||
3259 | { | ||
3260 | int rc = ap->ops->port_start(ap); | ||
3261 | |||
3262 | if (!rc) | ||
3263 | rc = ata_bus_probe(ap); | ||
3264 | |||
3265 | return rc; | ||
3266 | } | ||
3267 | EXPORT_SYMBOL_GPL(ata_sas_port_init); | ||
3268 | |||
3269 | /** | ||
3270 | * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc | ||
3271 | * @ap: SATA port to destroy | ||
3272 | * | ||
3273 | */ | ||
3274 | |||
3275 | void ata_sas_port_destroy(struct ata_port *ap) | ||
3276 | { | ||
3277 | ap->ops->port_stop(ap); | ||
3278 | kfree(ap); | ||
3279 | } | ||
3280 | EXPORT_SYMBOL_GPL(ata_sas_port_destroy); | ||
3281 | |||
3282 | /** | ||
3283 | * ata_sas_slave_configure - Default slave_config routine for libata devices | ||
3284 | * @sdev: SCSI device to configure | ||
3285 | * @ap: ATA port to which SCSI device is attached | ||
3286 | * | ||
3287 | * RETURNS: | ||
3288 | * Zero. | ||
3289 | */ | ||
3290 | |||
3291 | int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap) | ||
3292 | { | ||
3293 | ata_scsi_sdev_config(sdev); | ||
3294 | ata_scsi_dev_config(sdev, ap->device); | ||
3295 | return 0; | ||
3296 | } | ||
3297 | EXPORT_SYMBOL_GPL(ata_sas_slave_configure); | ||
3298 | |||
3299 | /** | ||
3300 | * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device | ||
3301 | * @cmd: SCSI command to be sent | ||
3302 | * @done: Completion function, called when command is complete | ||
3303 | * @ap: ATA port to which the command is being sent | ||
3304 | * | ||
3305 | * RETURNS: | ||
3306 | * Zero. | ||
3307 | */ | ||
3308 | |||
3309 | int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), | ||
3310 | struct ata_port *ap) | ||
3311 | { | ||
3312 | ata_scsi_dump_cdb(ap, cmd); | ||
3313 | |||
3314 | if (likely(ata_scsi_dev_enabled(ap->device))) | ||
3315 | __ata_scsi_queuecmd(cmd, done, ap->device); | ||
3316 | else { | ||
3317 | cmd->result = (DID_BAD_TARGET << 16); | ||
3318 | done(cmd); | ||
3319 | } | ||
3320 | return 0; | ||
3321 | } | ||
3322 | EXPORT_SYMBOL_GPL(ata_sas_queuecmd); | ||
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index c325679d9b54..d4a4f82360ec 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -69,6 +69,10 @@ extern int ata_flush_cache(struct ata_device *dev); | |||
69 | extern void ata_dev_init(struct ata_device *dev); | 69 | extern void ata_dev_init(struct ata_device *dev); |
70 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); | 70 | extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); |
71 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); | 71 | extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); |
72 | extern void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, | ||
73 | const struct ata_probe_ent *ent, unsigned int port_no); | ||
74 | extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev, | ||
75 | const struct ata_port_info *port); | ||
72 | 76 | ||
73 | 77 | ||
74 | /* libata-scsi.c */ | 78 | /* libata-scsi.c */ |
@@ -107,6 +111,7 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | |||
107 | u8 *rbuf, unsigned int buflen)); | 111 | u8 *rbuf, unsigned int buflen)); |
108 | extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); | 112 | extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); |
109 | extern void ata_scsi_dev_rescan(void *data); | 113 | extern void ata_scsi_dev_rescan(void *data); |
114 | extern int ata_bus_probe(struct ata_port *ap); | ||
110 | 115 | ||
111 | /* libata-eh.c */ | 116 | /* libata-eh.c */ |
112 | extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); | 117 | extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index f81691fcf177..d44f9aac6b8f 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -21,10 +21,12 @@ | |||
21 | 21 | ||
22 | struct lpfc_sli2_slim; | 22 | struct lpfc_sli2_slim; |
23 | 23 | ||
24 | #define LPFC_MAX_TARGET 256 /* max targets supported */ | ||
25 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els req */ | ||
26 | #define LPFC_MAX_NS_RETRY 3 /* max NameServer retries */ | ||
27 | 24 | ||
25 | #define LPFC_MAX_TARGET 256 /* max number of targets supported */ | ||
26 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els | ||
27 | requests */ | ||
28 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | ||
29 | the NameServer before giving up. */ | ||
28 | #define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */ | 30 | #define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */ |
29 | #define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ | 31 | #define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ |
30 | #define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ | 32 | #define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ |
@@ -41,7 +43,6 @@ struct lpfc_sli2_slim; | |||
41 | (( (u64)(high)<<16 ) << 16)|( (u64)(low)))) | 43 | (( (u64)(high)<<16 ) << 16)|( (u64)(low)))) |
42 | /* Provide maximum configuration definitions. */ | 44 | /* Provide maximum configuration definitions. */ |
43 | #define LPFC_DRVR_TIMEOUT 16 /* driver iocb timeout value in sec */ | 45 | #define LPFC_DRVR_TIMEOUT 16 /* driver iocb timeout value in sec */ |
44 | #define MAX_FCP_TARGET 256 /* max num of FCP targets supported */ | ||
45 | #define FC_MAX_ADPTMSG 64 | 46 | #define FC_MAX_ADPTMSG 64 |
46 | 47 | ||
47 | #define MAX_HBAEVT 32 | 48 | #define MAX_HBAEVT 32 |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b62a72dfab29..5c68cdd8736f 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -219,9 +219,19 @@ lpfc_issue_lip(struct Scsi_Host *host) | |||
219 | return -ENOMEM; | 219 | return -ENOMEM; |
220 | 220 | ||
221 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | 221 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); |
222 | lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed); | 222 | pmboxq->mb.mbxCommand = MBX_DOWN_LINK; |
223 | pmboxq->mb.mbxOwner = OWN_HOST; | ||
224 | |||
223 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); | 225 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); |
224 | 226 | ||
227 | if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { | ||
228 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | ||
229 | lpfc_init_link(phba, pmboxq, phba->cfg_topology, | ||
230 | phba->cfg_link_speed); | ||
231 | mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, | ||
232 | phba->fc_ratov * 2); | ||
233 | } | ||
234 | |||
225 | if (mbxstatus == MBX_TIMEOUT) | 235 | if (mbxstatus == MBX_TIMEOUT) |
226 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 236 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
227 | else | 237 | else |
@@ -233,51 +243,53 @@ lpfc_issue_lip(struct Scsi_Host *host) | |||
233 | return 0; | 243 | return 0; |
234 | } | 244 | } |
235 | 245 | ||
236 | static ssize_t | 246 | static int |
237 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) | 247 | lpfc_selective_reset(struct lpfc_hba *phba) |
238 | { | 248 | { |
239 | struct Scsi_Host *host = class_to_shost(cdev); | 249 | struct completion online_compl; |
240 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 250 | int status = 0; |
241 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); | 251 | |
252 | init_completion(&online_compl); | ||
253 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
254 | LPFC_EVT_OFFLINE); | ||
255 | wait_for_completion(&online_compl); | ||
256 | |||
257 | if (status != 0) | ||
258 | return -EIO; | ||
259 | |||
260 | init_completion(&online_compl); | ||
261 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
262 | LPFC_EVT_ONLINE); | ||
263 | wait_for_completion(&online_compl); | ||
264 | |||
265 | if (status != 0) | ||
266 | return -EIO; | ||
267 | |||
268 | return 0; | ||
242 | } | 269 | } |
243 | 270 | ||
244 | static ssize_t | 271 | static ssize_t |
245 | lpfc_board_online_show(struct class_device *cdev, char *buf) | 272 | lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) |
246 | { | 273 | { |
247 | struct Scsi_Host *host = class_to_shost(cdev); | 274 | struct Scsi_Host *host = class_to_shost(cdev); |
248 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 275 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
276 | int status = -EINVAL; | ||
249 | 277 | ||
250 | if (phba->fc_flag & FC_OFFLINE_MODE) | 278 | if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) |
251 | return snprintf(buf, PAGE_SIZE, "0\n"); | 279 | status = lpfc_selective_reset(phba); |
280 | |||
281 | if (status == 0) | ||
282 | return strlen(buf); | ||
252 | else | 283 | else |
253 | return snprintf(buf, PAGE_SIZE, "1\n"); | 284 | return status; |
254 | } | 285 | } |
255 | 286 | ||
256 | static ssize_t | 287 | static ssize_t |
257 | lpfc_board_online_store(struct class_device *cdev, const char *buf, | 288 | lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) |
258 | size_t count) | ||
259 | { | 289 | { |
260 | struct Scsi_Host *host = class_to_shost(cdev); | 290 | struct Scsi_Host *host = class_to_shost(cdev); |
261 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 291 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
262 | struct completion online_compl; | 292 | return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); |
263 | int val=0, status=0; | ||
264 | |||
265 | if (sscanf(buf, "%d", &val) != 1) | ||
266 | return -EINVAL; | ||
267 | |||
268 | init_completion(&online_compl); | ||
269 | |||
270 | if (val) | ||
271 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
272 | LPFC_EVT_ONLINE); | ||
273 | else | ||
274 | lpfc_workq_post_event(phba, &status, &online_compl, | ||
275 | LPFC_EVT_OFFLINE); | ||
276 | wait_for_completion(&online_compl); | ||
277 | if (!status) | ||
278 | return strlen(buf); | ||
279 | else | ||
280 | return -EIO; | ||
281 | } | 293 | } |
282 | 294 | ||
283 | static ssize_t | 295 | static ssize_t |
@@ -532,10 +544,9 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, | |||
532 | NULL); | 544 | NULL); |
533 | static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, | 545 | static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, |
534 | NULL); | 546 | NULL); |
535 | static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, | ||
536 | lpfc_board_online_show, lpfc_board_online_store); | ||
537 | static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, | 547 | static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, |
538 | lpfc_board_mode_show, lpfc_board_mode_store); | 548 | lpfc_board_mode_show, lpfc_board_mode_store); |
549 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); | ||
539 | 550 | ||
540 | static int lpfc_poll = 0; | 551 | static int lpfc_poll = 0; |
541 | module_param(lpfc_poll, int, 0); | 552 | module_param(lpfc_poll, int, 0); |
@@ -695,12 +706,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " | |||
695 | "during discovery"); | 706 | "during discovery"); |
696 | 707 | ||
697 | /* | 708 | /* |
698 | # lpfc_max_luns: maximum number of LUNs per target driver will support | 709 | # lpfc_max_luns: maximum allowed LUN. |
699 | # Value range is [1,32768]. Default value is 256. | 710 | # Value range is [0,65535]. Default value is 255. |
700 | # NOTE: The SCSI layer will scan each target for this many luns | 711 | # NOTE: The SCSI layer might probe all allowed LUN on some old targets. |
701 | */ | 712 | */ |
702 | LPFC_ATTR_R(max_luns, 256, 1, 32768, | 713 | LPFC_ATTR_R(max_luns, 255, 0, 65535, |
703 | "Maximum number of LUNs per target driver will support"); | 714 | "Maximum allowed LUN"); |
704 | 715 | ||
705 | /* | 716 | /* |
706 | # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. | 717 | # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. |
@@ -739,8 +750,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
739 | &class_device_attr_lpfc_max_luns, | 750 | &class_device_attr_lpfc_max_luns, |
740 | &class_device_attr_nport_evt_cnt, | 751 | &class_device_attr_nport_evt_cnt, |
741 | &class_device_attr_management_version, | 752 | &class_device_attr_management_version, |
742 | &class_device_attr_board_online, | ||
743 | &class_device_attr_board_mode, | 753 | &class_device_attr_board_mode, |
754 | &class_device_attr_issue_reset, | ||
744 | &class_device_attr_lpfc_poll, | 755 | &class_device_attr_lpfc_poll, |
745 | &class_device_attr_lpfc_poll_tmo, | 756 | &class_device_attr_lpfc_poll_tmo, |
746 | NULL, | 757 | NULL, |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index ee22173fce43..517e9e4dd461 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -147,6 +147,7 @@ int lpfc_sli_hba_setup(struct lpfc_hba *); | |||
147 | int lpfc_sli_hba_down(struct lpfc_hba *); | 147 | int lpfc_sli_hba_down(struct lpfc_hba *); |
148 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 148 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
149 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); | 149 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); |
150 | int lpfc_sli_flush_mbox_queue(struct lpfc_hba *); | ||
150 | int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, | 151 | int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, |
151 | struct lpfc_sli_ring *, uint32_t); | 152 | struct lpfc_sli_ring *, uint32_t); |
152 | void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); | 153 | void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4126fd87956f..b89f6cb641e6 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -648,33 +648,32 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static struct lpfc_nodelist * | 650 | static struct lpfc_nodelist * |
651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 651 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, |
652 | struct lpfc_nodelist *ndlp) | 652 | struct lpfc_nodelist *ndlp) |
653 | { | 653 | { |
654 | struct lpfc_nodelist *new_ndlp; | 654 | struct lpfc_nodelist *new_ndlp; |
655 | struct lpfc_dmabuf *pcmd, *prsp; | ||
656 | uint32_t *lp; | 655 | uint32_t *lp; |
657 | struct serv_parm *sp; | 656 | struct serv_parm *sp; |
658 | uint8_t name[sizeof (struct lpfc_name)]; | 657 | uint8_t name[sizeof (struct lpfc_name)]; |
659 | uint32_t rc; | 658 | uint32_t rc; |
660 | 659 | ||
661 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
662 | prsp = (struct lpfc_dmabuf *) pcmd->list.next; | ||
663 | lp = (uint32_t *) prsp->virt; | 660 | lp = (uint32_t *) prsp->virt; |
664 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 661 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
662 | memset(name, 0, sizeof (struct lpfc_name)); | ||
665 | 663 | ||
666 | /* Now we to find out if the NPort we are logging into, matches the WWPN | 664 | /* Now we to find out if the NPort we are logging into, matches the WWPN |
667 | * we have for that ndlp. If not, we have some work to do. | 665 | * we have for that ndlp. If not, we have some work to do. |
668 | */ | 666 | */ |
669 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | 667 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); |
670 | 668 | ||
671 | memset(name, 0, sizeof (struct lpfc_name)); | 669 | if (new_ndlp == ndlp) |
672 | rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
673 | if (!rc || (new_ndlp == ndlp)) { | ||
674 | return ndlp; | 670 | return ndlp; |
675 | } | ||
676 | 671 | ||
677 | if (!new_ndlp) { | 672 | if (!new_ndlp) { |
673 | rc = | ||
674 | memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); | ||
675 | if (!rc) | ||
676 | return ndlp; | ||
678 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 677 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
679 | if (!new_ndlp) | 678 | if (!new_ndlp) |
680 | return ndlp; | 679 | return ndlp; |
@@ -683,17 +682,21 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
683 | } | 682 | } |
684 | 683 | ||
685 | lpfc_unreg_rpi(phba, new_ndlp); | 684 | lpfc_unreg_rpi(phba, new_ndlp); |
686 | new_ndlp->nlp_prev_state = ndlp->nlp_state; | ||
687 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 685 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
688 | new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 686 | new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; |
689 | lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); | 687 | new_ndlp->nlp_state = ndlp->nlp_state; |
688 | lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); | ||
690 | 689 | ||
691 | /* Move this back to NPR list */ | 690 | /* Move this back to NPR list */ |
692 | lpfc_unreg_rpi(phba, ndlp); | 691 | if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { |
693 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 692 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
694 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 693 | } |
695 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 694 | else { |
696 | 695 | lpfc_unreg_rpi(phba, ndlp); | |
696 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | ||
697 | ndlp->nlp_state = NLP_STE_NPR_NODE; | ||
698 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | ||
699 | } | ||
697 | return new_ndlp; | 700 | return new_ndlp; |
698 | } | 701 | } |
699 | 702 | ||
@@ -703,6 +706,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
703 | { | 706 | { |
704 | IOCB_t *irsp; | 707 | IOCB_t *irsp; |
705 | struct lpfc_nodelist *ndlp; | 708 | struct lpfc_nodelist *ndlp; |
709 | struct lpfc_dmabuf *prsp; | ||
706 | int disc, rc, did, type; | 710 | int disc, rc, did, type; |
707 | 711 | ||
708 | 712 | ||
@@ -769,7 +773,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
769 | } | 773 | } |
770 | } else { | 774 | } else { |
771 | /* Good status, call state machine */ | 775 | /* Good status, call state machine */ |
772 | ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); | 776 | prsp = list_entry(((struct lpfc_dmabuf *) |
777 | cmdiocb->context2)->list.next, | ||
778 | struct lpfc_dmabuf, list); | ||
779 | ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); | ||
773 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, | 780 | rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, |
774 | NLP_EVT_CMPL_PLOGI); | 781 | NLP_EVT_CMPL_PLOGI); |
775 | } | 782 | } |
@@ -3282,10 +3289,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) | |||
3282 | } else | 3289 | } else |
3283 | lpfc_sli_release_iocbq(phba, piocb); | 3290 | lpfc_sli_release_iocbq(phba, piocb); |
3284 | } | 3291 | } |
3285 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { | 3292 | if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) |
3286 | phba->els_tmofunc.expires = jiffies + HZ * timeout; | 3293 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); |
3287 | add_timer(&phba->els_tmofunc); | 3294 | |
3288 | } | ||
3289 | spin_unlock_irq(phba->host->host_lock); | 3295 | spin_unlock_irq(phba->host->host_lock); |
3290 | } | 3296 | } |
3291 | 3297 | ||
@@ -3442,6 +3448,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3442 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 3448 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { |
3443 | ndlp->nlp_type |= NLP_FABRIC; | 3449 | ndlp->nlp_type |= NLP_FABRIC; |
3444 | } | 3450 | } |
3451 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
3452 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
3445 | } | 3453 | } |
3446 | 3454 | ||
3447 | phba->fc_stat.elsRcvFrame++; | 3455 | phba->fc_stat.elsRcvFrame++; |
@@ -3463,13 +3471,14 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3463 | rjt_err = 1; | 3471 | rjt_err = 1; |
3464 | break; | 3472 | break; |
3465 | } | 3473 | } |
3474 | ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); | ||
3466 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); | 3475 | lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); |
3467 | break; | 3476 | break; |
3468 | case ELS_CMD_FLOGI: | 3477 | case ELS_CMD_FLOGI: |
3469 | phba->fc_stat.elsRcvFLOGI++; | 3478 | phba->fc_stat.elsRcvFLOGI++; |
3470 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); | 3479 | lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); |
3471 | if (newnode) { | 3480 | if (newnode) { |
3472 | mempool_free( ndlp, phba->nlp_mem_pool); | 3481 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3473 | } | 3482 | } |
3474 | break; | 3483 | break; |
3475 | case ELS_CMD_LOGO: | 3484 | case ELS_CMD_LOGO: |
@@ -3492,7 +3501,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3492 | phba->fc_stat.elsRcvRSCN++; | 3501 | phba->fc_stat.elsRcvRSCN++; |
3493 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); | 3502 | lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); |
3494 | if (newnode) { | 3503 | if (newnode) { |
3495 | mempool_free( ndlp, phba->nlp_mem_pool); | 3504 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3496 | } | 3505 | } |
3497 | break; | 3506 | break; |
3498 | case ELS_CMD_ADISC: | 3507 | case ELS_CMD_ADISC: |
@@ -3535,28 +3544,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3535 | phba->fc_stat.elsRcvLIRR++; | 3544 | phba->fc_stat.elsRcvLIRR++; |
3536 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); | 3545 | lpfc_els_rcv_lirr(phba, elsiocb, ndlp); |
3537 | if (newnode) { | 3546 | if (newnode) { |
3538 | mempool_free( ndlp, phba->nlp_mem_pool); | 3547 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3539 | } | 3548 | } |
3540 | break; | 3549 | break; |
3541 | case ELS_CMD_RPS: | 3550 | case ELS_CMD_RPS: |
3542 | phba->fc_stat.elsRcvRPS++; | 3551 | phba->fc_stat.elsRcvRPS++; |
3543 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); | 3552 | lpfc_els_rcv_rps(phba, elsiocb, ndlp); |
3544 | if (newnode) { | 3553 | if (newnode) { |
3545 | mempool_free( ndlp, phba->nlp_mem_pool); | 3554 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3546 | } | 3555 | } |
3547 | break; | 3556 | break; |
3548 | case ELS_CMD_RPL: | 3557 | case ELS_CMD_RPL: |
3549 | phba->fc_stat.elsRcvRPL++; | 3558 | phba->fc_stat.elsRcvRPL++; |
3550 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); | 3559 | lpfc_els_rcv_rpl(phba, elsiocb, ndlp); |
3551 | if (newnode) { | 3560 | if (newnode) { |
3552 | mempool_free( ndlp, phba->nlp_mem_pool); | 3561 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3553 | } | 3562 | } |
3554 | break; | 3563 | break; |
3555 | case ELS_CMD_RNID: | 3564 | case ELS_CMD_RNID: |
3556 | phba->fc_stat.elsRcvRNID++; | 3565 | phba->fc_stat.elsRcvRNID++; |
3557 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); | 3566 | lpfc_els_rcv_rnid(phba, elsiocb, ndlp); |
3558 | if (newnode) { | 3567 | if (newnode) { |
3559 | mempool_free( ndlp, phba->nlp_mem_pool); | 3568 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3560 | } | 3569 | } |
3561 | break; | 3570 | break; |
3562 | default: | 3571 | default: |
@@ -3568,7 +3577,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3568 | "%d:0115 Unknown ELS command x%x received from " | 3577 | "%d:0115 Unknown ELS command x%x received from " |
3569 | "NPORT x%x\n", phba->brd_no, cmd, did); | 3578 | "NPORT x%x\n", phba->brd_no, cmd, did); |
3570 | if (newnode) { | 3579 | if (newnode) { |
3571 | mempool_free( ndlp, phba->nlp_mem_pool); | 3580 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
3572 | } | 3581 | } |
3573 | break; | 3582 | break; |
3574 | } | 3583 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index adb086009ae0..4d6cf990c4fc 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, | |||
1084 | fc_remote_port_rolechg(rport, rport_ids.roles); | 1084 | fc_remote_port_rolechg(rport, rport_ids.roles); |
1085 | 1085 | ||
1086 | if ((rport->scsi_target_id != -1) && | 1086 | if ((rport->scsi_target_id != -1) && |
1087 | (rport->scsi_target_id < MAX_FCP_TARGET)) { | 1087 | (rport->scsi_target_id < LPFC_MAX_TARGET)) { |
1088 | ndlp->nlp_sid = rport->scsi_target_id; | 1088 | ndlp->nlp_sid = rport->scsi_target_id; |
1089 | } | 1089 | } |
1090 | 1090 | ||
@@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1313 | if ((rport_add == mapped) && | 1313 | if ((rport_add == mapped) && |
1314 | ((!nlp->rport) || | 1314 | ((!nlp->rport) || |
1315 | (nlp->rport->scsi_target_id == -1) || | 1315 | (nlp->rport->scsi_target_id == -1) || |
1316 | (nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) { | 1316 | (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) { |
1317 | nlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1317 | nlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1318 | spin_lock_irq(phba->host->host_lock); | 1318 | spin_lock_irq(phba->host->host_lock); |
1319 | nlp->nlp_flag |= NLP_TGT_NO_SCSIID; | 1319 | nlp->nlp_flag |= NLP_TGT_NO_SCSIID; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 81755a3f7c68..ef47b824cbed 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -71,6 +71,7 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
71 | uint16_t offset = 0; | 71 | uint16_t offset = 0; |
72 | static char licensed[56] = | 72 | static char licensed[56] = |
73 | "key unlock for use with gnu public licensed code only\0"; | 73 | "key unlock for use with gnu public licensed code only\0"; |
74 | static int init_key = 1; | ||
74 | 75 | ||
75 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 76 | pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
76 | if (!pmb) { | 77 | if (!pmb) { |
@@ -82,10 +83,13 @@ lpfc_config_port_prep(struct lpfc_hba * phba) | |||
82 | phba->hba_state = LPFC_INIT_MBX_CMDS; | 83 | phba->hba_state = LPFC_INIT_MBX_CMDS; |
83 | 84 | ||
84 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { | 85 | if (lpfc_is_LC_HBA(phba->pcidev->device)) { |
85 | uint32_t *ptext = (uint32_t *) licensed; | 86 | if (init_key) { |
87 | uint32_t *ptext = (uint32_t *) licensed; | ||
86 | 88 | ||
87 | for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) | 89 | for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) |
88 | *ptext = cpu_to_be32(*ptext); | 90 | *ptext = cpu_to_be32(*ptext); |
91 | init_key = 0; | ||
92 | } | ||
89 | 93 | ||
90 | lpfc_read_nv(phba, pmb); | 94 | lpfc_read_nv(phba, pmb); |
91 | memset((char*)mb->un.varRDnvp.rsvd3, 0, | 95 | memset((char*)mb->un.varRDnvp.rsvd3, 0, |
@@ -405,19 +409,26 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
405 | } | 409 | } |
406 | /* MBOX buffer will be freed in mbox compl */ | 410 | /* MBOX buffer will be freed in mbox compl */ |
407 | 411 | ||
408 | i = 0; | 412 | return (0); |
413 | } | ||
414 | |||
415 | static int | ||
416 | lpfc_discovery_wait(struct lpfc_hba *phba) | ||
417 | { | ||
418 | int i = 0; | ||
419 | |||
409 | while ((phba->hba_state != LPFC_HBA_READY) || | 420 | while ((phba->hba_state != LPFC_HBA_READY) || |
410 | (phba->num_disc_nodes) || (phba->fc_prli_sent) || | 421 | (phba->num_disc_nodes) || (phba->fc_prli_sent) || |
411 | ((phba->fc_map_cnt == 0) && (i<2)) || | 422 | ((phba->fc_map_cnt == 0) && (i<2)) || |
412 | (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) { | 423 | (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) { |
413 | /* Check every second for 30 retries. */ | 424 | /* Check every second for 30 retries. */ |
414 | i++; | 425 | i++; |
415 | if (i > 30) { | 426 | if (i > 30) { |
416 | break; | 427 | return -ETIMEDOUT; |
417 | } | 428 | } |
418 | if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) { | 429 | if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) { |
419 | /* The link is down. Set linkdown timeout */ | 430 | /* The link is down. Set linkdown timeout */ |
420 | break; | 431 | return -ETIMEDOUT; |
421 | } | 432 | } |
422 | 433 | ||
423 | /* Delay for 1 second to give discovery time to complete. */ | 434 | /* Delay for 1 second to give discovery time to complete. */ |
@@ -425,12 +436,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
425 | 436 | ||
426 | } | 437 | } |
427 | 438 | ||
428 | /* Since num_disc_nodes keys off of PLOGI, delay a bit to let | 439 | return 0; |
429 | * any potential PRLIs to flush thru the SLI sub-system. | ||
430 | */ | ||
431 | msleep(50); | ||
432 | |||
433 | return (0); | ||
434 | } | 440 | } |
435 | 441 | ||
436 | /************************************************************************/ | 442 | /************************************************************************/ |
@@ -1339,7 +1345,8 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1339 | struct lpfc_sli_ring *pring; | 1345 | struct lpfc_sli_ring *pring; |
1340 | struct lpfc_sli *psli; | 1346 | struct lpfc_sli *psli; |
1341 | unsigned long iflag; | 1347 | unsigned long iflag; |
1342 | int i = 0; | 1348 | int i; |
1349 | int cnt = 0; | ||
1343 | 1350 | ||
1344 | if (!phba) | 1351 | if (!phba) |
1345 | return 0; | 1352 | return 0; |
@@ -1348,17 +1355,27 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1348 | return 0; | 1355 | return 0; |
1349 | 1356 | ||
1350 | psli = &phba->sli; | 1357 | psli = &phba->sli; |
1351 | pring = &psli->ring[psli->fcp_ring]; | ||
1352 | 1358 | ||
1353 | lpfc_linkdown(phba); | 1359 | lpfc_linkdown(phba); |
1360 | lpfc_sli_flush_mbox_queue(phba); | ||
1354 | 1361 | ||
1355 | /* The linkdown event takes 30 seconds to timeout. */ | 1362 | for (i = 0; i < psli->num_rings; i++) { |
1356 | while (pring->txcmplq_cnt) { | 1363 | pring = &psli->ring[i]; |
1357 | mdelay(10); | 1364 | /* The linkdown event takes 30 seconds to timeout. */ |
1358 | if (i++ > 3000) | 1365 | while (pring->txcmplq_cnt) { |
1359 | break; | 1366 | mdelay(10); |
1367 | if (cnt++ > 3000) { | ||
1368 | lpfc_printf_log(phba, | ||
1369 | KERN_WARNING, LOG_INIT, | ||
1370 | "%d:0466 Outstanding IO when " | ||
1371 | "bringing Adapter offline\n", | ||
1372 | phba->brd_no); | ||
1373 | break; | ||
1374 | } | ||
1375 | } | ||
1360 | } | 1376 | } |
1361 | 1377 | ||
1378 | |||
1362 | /* stop all timers associated with this hba */ | 1379 | /* stop all timers associated with this hba */ |
1363 | lpfc_stop_timer(phba); | 1380 | lpfc_stop_timer(phba); |
1364 | phba->work_hba_events = 0; | 1381 | phba->work_hba_events = 0; |
@@ -1639,6 +1656,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1639 | goto out_free_irq; | 1656 | goto out_free_irq; |
1640 | } | 1657 | } |
1641 | 1658 | ||
1659 | lpfc_discovery_wait(phba); | ||
1660 | |||
1642 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { | 1661 | if (phba->cfg_poll & DISABLE_FCP_RING_INT) { |
1643 | spin_lock_irq(phba->host->host_lock); | 1662 | spin_lock_irq(phba->host->host_lock); |
1644 | lpfc_poll_start_timer(phba); | 1663 | lpfc_poll_start_timer(phba); |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 07017658ac56..066292d3995a 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -133,6 +133,11 @@ lpfc_mem_free(struct lpfc_hba * phba) | |||
133 | 133 | ||
134 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); | 134 | pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); |
135 | pci_pool_destroy(phba->lpfc_mbuf_pool); | 135 | pci_pool_destroy(phba->lpfc_mbuf_pool); |
136 | |||
137 | /* Free the iocb lookup array */ | ||
138 | kfree(psli->iocbq_lookup); | ||
139 | psli->iocbq_lookup = NULL; | ||
140 | |||
136 | } | 141 | } |
137 | 142 | ||
138 | void * | 143 | void * |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 27d60ad897cd..bd0b0e293d63 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -1110,6 +1110,17 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1110 | phba->brd_no, | 1110 | phba->brd_no, |
1111 | did, mb->mbxStatus, phba->hba_state); | 1111 | did, mb->mbxStatus, phba->hba_state); |
1112 | 1112 | ||
1113 | /* | ||
1114 | * If RegLogin failed due to lack of HBA resources do not | ||
1115 | * retry discovery. | ||
1116 | */ | ||
1117 | if (mb->mbxStatus == MBXERR_RPI_FULL) { | ||
1118 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
1119 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | ||
1120 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | ||
1121 | return ndlp->nlp_state; | ||
1122 | } | ||
1123 | |||
1113 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1124 | /* Put ndlp in npr list set plogi timer for 1 sec */ |
1114 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1125 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1115 | spin_lock_irq(phba->host->host_lock); | 1126 | spin_lock_irq(phba->host->host_lock); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index aea1ee472f3d..a760a44173df 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -153,22 +153,6 @@ static void | |||
153 | lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | 153 | lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) |
154 | { | 154 | { |
155 | unsigned long iflag = 0; | 155 | unsigned long iflag = 0; |
156 | /* | ||
157 | * There are only two special cases to consider. (1) the scsi command | ||
158 | * requested scatter-gather usage or (2) the scsi command allocated | ||
159 | * a request buffer, but did not request use_sg. There is a third | ||
160 | * case, but it does not require resource deallocation. | ||
161 | */ | ||
162 | if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { | ||
163 | dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, | ||
164 | psb->seg_cnt, psb->pCmd->sc_data_direction); | ||
165 | } else { | ||
166 | if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { | ||
167 | dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, | ||
168 | psb->pCmd->request_bufflen, | ||
169 | psb->pCmd->sc_data_direction); | ||
170 | } | ||
171 | } | ||
172 | 156 | ||
173 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); | 157 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); |
174 | psb->pCmd = NULL; | 158 | psb->pCmd = NULL; |
@@ -282,6 +266,27 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd) | |||
282 | } | 266 | } |
283 | 267 | ||
284 | static void | 268 | static void |
269 | lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) | ||
270 | { | ||
271 | /* | ||
272 | * There are only two special cases to consider. (1) the scsi command | ||
273 | * requested scatter-gather usage or (2) the scsi command allocated | ||
274 | * a request buffer, but did not request use_sg. There is a third | ||
275 | * case, but it does not require resource deallocation. | ||
276 | */ | ||
277 | if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { | ||
278 | dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, | ||
279 | psb->seg_cnt, psb->pCmd->sc_data_direction); | ||
280 | } else { | ||
281 | if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { | ||
282 | dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, | ||
283 | psb->pCmd->request_bufflen, | ||
284 | psb->pCmd->sc_data_direction); | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | static void | ||
285 | lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | 290 | lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) |
286 | { | 291 | { |
287 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; | 292 | struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; |
@@ -454,6 +459,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
454 | cmd->scsi_done(cmd); | 459 | cmd->scsi_done(cmd); |
455 | 460 | ||
456 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 461 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
462 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
457 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 463 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
458 | return; | 464 | return; |
459 | } | 465 | } |
@@ -511,6 +517,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
511 | } | 517 | } |
512 | } | 518 | } |
513 | 519 | ||
520 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
514 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 521 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
515 | } | 522 | } |
516 | 523 | ||
@@ -609,6 +616,7 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, | |||
609 | static int | 616 | static int |
610 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | 617 | lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, |
611 | struct lpfc_scsi_buf *lpfc_cmd, | 618 | struct lpfc_scsi_buf *lpfc_cmd, |
619 | unsigned int lun, | ||
612 | uint8_t task_mgmt_cmd) | 620 | uint8_t task_mgmt_cmd) |
613 | { | 621 | { |
614 | struct lpfc_sli *psli; | 622 | struct lpfc_sli *psli; |
@@ -627,8 +635,7 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
627 | piocb = &piocbq->iocb; | 635 | piocb = &piocbq->iocb; |
628 | 636 | ||
629 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 637 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
630 | int_to_scsilun(lpfc_cmd->pCmd->device->lun, | 638 | int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); |
631 | &lpfc_cmd->fcp_cmnd->fcp_lun); | ||
632 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; | 639 | fcp_cmnd->fcpCntl2 = task_mgmt_cmd; |
633 | 640 | ||
634 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; | 641 | piocb->ulpCommand = CMD_FCP_ICMND64_CR; |
@@ -655,14 +662,16 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, | |||
655 | 662 | ||
656 | static int | 663 | static int |
657 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | 664 | lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, |
658 | unsigned tgt_id, struct lpfc_rport_data *rdata) | 665 | unsigned tgt_id, unsigned int lun, |
666 | struct lpfc_rport_data *rdata) | ||
659 | { | 667 | { |
660 | struct lpfc_iocbq *iocbq; | 668 | struct lpfc_iocbq *iocbq; |
661 | struct lpfc_iocbq *iocbqrsp; | 669 | struct lpfc_iocbq *iocbqrsp; |
662 | int ret; | 670 | int ret; |
663 | 671 | ||
664 | lpfc_cmd->rdata = rdata; | 672 | lpfc_cmd->rdata = rdata; |
665 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); | 673 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, |
674 | FCP_TARGET_RESET); | ||
666 | if (!ret) | 675 | if (!ret) |
667 | return FAILED; | 676 | return FAILED; |
668 | 677 | ||
@@ -822,6 +831,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
822 | return 0; | 831 | return 0; |
823 | 832 | ||
824 | out_host_busy_free_buf: | 833 | out_host_busy_free_buf: |
834 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
825 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 835 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
826 | out_host_busy: | 836 | out_host_busy: |
827 | return SCSI_MLQUEUE_HOST_BUSY; | 837 | return SCSI_MLQUEUE_HOST_BUSY; |
@@ -969,12 +979,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
969 | if (lpfc_cmd == NULL) | 979 | if (lpfc_cmd == NULL) |
970 | goto out; | 980 | goto out; |
971 | 981 | ||
972 | lpfc_cmd->pCmd = cmnd; | ||
973 | lpfc_cmd->timeout = 60; | 982 | lpfc_cmd->timeout = 60; |
974 | lpfc_cmd->scsi_hba = phba; | 983 | lpfc_cmd->scsi_hba = phba; |
975 | lpfc_cmd->rdata = rdata; | 984 | lpfc_cmd->rdata = rdata; |
976 | 985 | ||
977 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); | 986 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, |
987 | FCP_LUN_RESET); | ||
978 | if (!ret) | 988 | if (!ret) |
979 | goto out_free_scsi_buf; | 989 | goto out_free_scsi_buf; |
980 | 990 | ||
@@ -1001,7 +1011,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1001 | cmd_status = iocbqrsp->iocb.ulpStatus; | 1011 | cmd_status = iocbqrsp->iocb.ulpStatus; |
1002 | 1012 | ||
1003 | lpfc_sli_release_iocbq(phba, iocbqrsp); | 1013 | lpfc_sli_release_iocbq(phba, iocbqrsp); |
1004 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1005 | 1014 | ||
1006 | /* | 1015 | /* |
1007 | * All outstanding txcmplq I/Os should have been aborted by the device. | 1016 | * All outstanding txcmplq I/Os should have been aborted by the device. |
@@ -1040,6 +1049,8 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
1040 | } | 1049 | } |
1041 | 1050 | ||
1042 | out_free_scsi_buf: | 1051 | out_free_scsi_buf: |
1052 | lpfc_release_scsi_buf(phba, lpfc_cmd); | ||
1053 | |||
1043 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1054 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1044 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " | 1055 | "%d:0713 SCSI layer issued LUN reset (%d, %d) " |
1045 | "Data: x%x x%x x%x\n", | 1056 | "Data: x%x x%x x%x\n", |
@@ -1070,7 +1081,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1070 | 1081 | ||
1071 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ | 1082 | /* The lpfc_cmd storage is reused. Set all loop invariants. */ |
1072 | lpfc_cmd->timeout = 60; | 1083 | lpfc_cmd->timeout = 60; |
1073 | lpfc_cmd->pCmd = cmnd; | ||
1074 | lpfc_cmd->scsi_hba = phba; | 1084 | lpfc_cmd->scsi_hba = phba; |
1075 | 1085 | ||
1076 | /* | 1086 | /* |
@@ -1078,7 +1088,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1078 | * targets known to the driver. Should any target reset | 1088 | * targets known to the driver. Should any target reset |
1079 | * fail, this routine returns failure to the midlayer. | 1089 | * fail, this routine returns failure to the midlayer. |
1080 | */ | 1090 | */ |
1081 | for (i = 0; i < MAX_FCP_TARGET; i++) { | 1091 | for (i = 0; i < LPFC_MAX_TARGET; i++) { |
1082 | /* Search the mapped list for this target ID */ | 1092 | /* Search the mapped list for this target ID */ |
1083 | match = 0; | 1093 | match = 0; |
1084 | list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { | 1094 | list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { |
@@ -1090,8 +1100,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1090 | if (!match) | 1100 | if (!match) |
1091 | continue; | 1101 | continue; |
1092 | 1102 | ||
1093 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, | 1103 | ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, |
1094 | i, ndlp->rport->dd_data); | 1104 | ndlp->rport->dd_data); |
1095 | if (ret != SUCCESS) { | 1105 | if (ret != SUCCESS) { |
1096 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | 1106 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, |
1097 | "%d:0713 Bus Reset on target %d failed\n", | 1107 | "%d:0713 Bus Reset on target %d failed\n", |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bb69a7a1ec59..350a625fa224 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -191,35 +191,12 @@ static int | |||
191 | lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba, | 191 | lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba, |
192 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb) | 192 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb) |
193 | { | 193 | { |
194 | uint16_t iotag; | ||
195 | |||
196 | list_add_tail(&piocb->list, &pring->txcmplq); | 194 | list_add_tail(&piocb->list, &pring->txcmplq); |
197 | pring->txcmplq_cnt++; | 195 | pring->txcmplq_cnt++; |
198 | if (unlikely(pring->ringno == LPFC_ELS_RING)) | 196 | if (unlikely(pring->ringno == LPFC_ELS_RING)) |
199 | mod_timer(&phba->els_tmofunc, | 197 | mod_timer(&phba->els_tmofunc, |
200 | jiffies + HZ * (phba->fc_ratov << 1)); | 198 | jiffies + HZ * (phba->fc_ratov << 1)); |
201 | 199 | ||
202 | if (pring->fast_lookup) { | ||
203 | /* Setup fast lookup based on iotag for completion */ | ||
204 | iotag = piocb->iocb.ulpIoTag; | ||
205 | if (iotag && (iotag < pring->fast_iotag)) | ||
206 | *(pring->fast_lookup + iotag) = piocb; | ||
207 | else { | ||
208 | |||
209 | /* Cmd ring <ringno> put: iotag <iotag> greater then | ||
210 | configured max <fast_iotag> wd0 <icmd> */ | ||
211 | lpfc_printf_log(phba, | ||
212 | KERN_ERR, | ||
213 | LOG_SLI, | ||
214 | "%d:0316 Cmd ring %d put: iotag x%x " | ||
215 | "greater then configured max x%x " | ||
216 | "wd0 x%x\n", | ||
217 | phba->brd_no, | ||
218 | pring->ringno, iotag, | ||
219 | pring->fast_iotag, | ||
220 | *(((uint32_t *)(&piocb->iocb)) + 7)); | ||
221 | } | ||
222 | } | ||
223 | return (0); | 200 | return (0); |
224 | } | 201 | } |
225 | 202 | ||
@@ -601,7 +578,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
601 | /* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus | 578 | /* Stray Mailbox Interrupt, mbxCommand <cmd> mbxStatus |
602 | <status> */ | 579 | <status> */ |
603 | lpfc_printf_log(phba, | 580 | lpfc_printf_log(phba, |
604 | KERN_ERR, | 581 | KERN_WARNING, |
605 | LOG_MBOX | LOG_SLI, | 582 | LOG_MBOX | LOG_SLI, |
606 | "%d:0304 Stray Mailbox Interrupt " | 583 | "%d:0304 Stray Mailbox Interrupt " |
607 | "mbxCommand x%x mbxStatus x%x\n", | 584 | "mbxCommand x%x mbxStatus x%x\n", |
@@ -1570,8 +1547,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) | |||
1570 | 1547 | ||
1571 | void lpfc_reset_barrier(struct lpfc_hba * phba) | 1548 | void lpfc_reset_barrier(struct lpfc_hba * phba) |
1572 | { | 1549 | { |
1573 | uint32_t * resp_buf; | 1550 | uint32_t __iomem *resp_buf; |
1574 | uint32_t * mbox_buf; | 1551 | uint32_t __iomem *mbox_buf; |
1575 | volatile uint32_t mbox; | 1552 | volatile uint32_t mbox; |
1576 | uint32_t hc_copy; | 1553 | uint32_t hc_copy; |
1577 | int i; | 1554 | int i; |
@@ -1587,7 +1564,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1587 | * Tell the other part of the chip to suspend temporarily all | 1564 | * Tell the other part of the chip to suspend temporarily all |
1588 | * its DMA activity. | 1565 | * its DMA activity. |
1589 | */ | 1566 | */ |
1590 | resp_buf = (uint32_t *)phba->MBslimaddr; | 1567 | resp_buf = phba->MBslimaddr; |
1591 | 1568 | ||
1592 | /* Disable the error attention */ | 1569 | /* Disable the error attention */ |
1593 | hc_copy = readl(phba->HCregaddr); | 1570 | hc_copy = readl(phba->HCregaddr); |
@@ -1605,7 +1582,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) | |||
1605 | ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; | 1582 | ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; |
1606 | 1583 | ||
1607 | writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); | 1584 | writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); |
1608 | mbox_buf = (uint32_t *)phba->MBslimaddr; | 1585 | mbox_buf = phba->MBslimaddr; |
1609 | writel(mbox, mbox_buf); | 1586 | writel(mbox, mbox_buf); |
1610 | 1587 | ||
1611 | for (i = 0; | 1588 | for (i = 0; |
@@ -1805,7 +1782,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) | |||
1805 | skip_post = 0; | 1782 | skip_post = 0; |
1806 | word0 = 0; /* This is really setting up word1 */ | 1783 | word0 = 0; /* This is really setting up word1 */ |
1807 | } | 1784 | } |
1808 | to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); | 1785 | to_slim = phba->MBslimaddr + sizeof (uint32_t); |
1809 | writel(*(uint32_t *) mb, to_slim); | 1786 | writel(*(uint32_t *) mb, to_slim); |
1810 | readl(to_slim); /* flush */ | 1787 | readl(to_slim); /* flush */ |
1811 | 1788 | ||
@@ -2659,8 +2636,6 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) | |||
2659 | 2636 | ||
2660 | INIT_LIST_HEAD(&(pring->txq)); | 2637 | INIT_LIST_HEAD(&(pring->txq)); |
2661 | 2638 | ||
2662 | kfree(pring->fast_lookup); | ||
2663 | pring->fast_lookup = NULL; | ||
2664 | } | 2639 | } |
2665 | 2640 | ||
2666 | spin_unlock_irqrestore(phba->host->host_lock, flags); | 2641 | spin_unlock_irqrestore(phba->host->host_lock, flags); |
@@ -3110,6 +3085,24 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, | |||
3110 | return retval; | 3085 | return retval; |
3111 | } | 3086 | } |
3112 | 3087 | ||
3088 | int | ||
3089 | lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) | ||
3090 | { | ||
3091 | int i = 0; | ||
3092 | |||
3093 | while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) { | ||
3094 | if (i++ > LPFC_MBOX_TMO * 1000) | ||
3095 | return 1; | ||
3096 | |||
3097 | if (lpfc_sli_handle_mb_event(phba) == 0) | ||
3098 | i = 0; | ||
3099 | |||
3100 | msleep(1); | ||
3101 | } | ||
3102 | |||
3103 | return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0; | ||
3104 | } | ||
3105 | |||
3113 | irqreturn_t | 3106 | irqreturn_t |
3114 | lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) | 3107 | lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) |
3115 | { | 3108 | { |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index a52d6c6cf083..d8ef0d2894d4 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -135,8 +135,6 @@ struct lpfc_sli_ring { | |||
135 | uint32_t fast_iotag; /* max fastlookup based iotag */ | 135 | uint32_t fast_iotag; /* max fastlookup based iotag */ |
136 | uint32_t iotag_ctr; /* keeps track of the next iotag to use */ | 136 | uint32_t iotag_ctr; /* keeps track of the next iotag to use */ |
137 | uint32_t iotag_max; /* max iotag value to use */ | 137 | uint32_t iotag_max; /* max iotag value to use */ |
138 | struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by | ||
139 | iotag */ | ||
140 | struct list_head txq; | 138 | struct list_head txq; |
141 | uint16_t txq_cnt; /* current length of queue */ | 139 | uint16_t txq_cnt; /* current length of queue */ |
142 | uint16_t txq_max; /* max length */ | 140 | uint16_t txq_max; /* max length */ |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 6b737568b831..10e89c6ae823 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.1.6" | 21 | #define LPFC_DRIVER_VERSION "8.1.7" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 93edaa8696cf..89ef34df5a1d 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) | |||
378 | int nseg; | 378 | int nseg; |
379 | 379 | ||
380 | total = 0; | 380 | total = 0; |
381 | scl = (struct scatterlist *) cmd->buffer; | 381 | scl = (struct scatterlist *) cmd->request_buffer; |
382 | nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, | 382 | nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, |
383 | cmd->sc_data_direction); | 383 | cmd->sc_data_direction); |
384 | for (i = 0; i < nseg; ++i) { | 384 | for (i = 0; i < nseg; ++i) { |
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index c88717727be8..5572981a9f92 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c | |||
@@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd) | |||
1268 | if (cmd->use_sg > 0) { | 1268 | if (cmd->use_sg > 0) { |
1269 | int nseg; | 1269 | int nseg; |
1270 | total = 0; | 1270 | total = 0; |
1271 | scl = (struct scatterlist *) cmd->buffer; | 1271 | scl = (struct scatterlist *) cmd->request_buffer; |
1272 | off = ms->data_ptr; | 1272 | off = ms->data_ptr; |
1273 | nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg, | 1273 | nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg, |
1274 | cmd->sc_data_direction); | 1274 | cmd->sc_data_direction); |
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index 7abf64d1bfc9..0bd9c60e6455 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c | |||
@@ -169,8 +169,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
169 | SCpnt->request->rq_status = RQ_SCSI_BUSY; | 169 | SCpnt->request->rq_status = RQ_SCSI_BUSY; |
170 | 170 | ||
171 | SCpnt->done = pluto_detect_done; | 171 | SCpnt->done = pluto_detect_done; |
172 | SCpnt->bufflen = 256; | ||
173 | SCpnt->buffer = fcs[i].inquiry; | ||
174 | SCpnt->request_bufflen = 256; | 172 | SCpnt->request_bufflen = 256; |
175 | SCpnt->request_buffer = fcs[i].inquiry; | 173 | SCpnt->request_buffer = fcs[i].inquiry; |
176 | PLD(("set up %d %08lx\n", i, (long)SCpnt)) | 174 | PLD(("set up %d %08lx\n", i, (long)SCpnt)) |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 69e0551a81d2..5b2f0741a55b 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
@@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, | |||
874 | if (Cmnd->use_sg) { | 874 | if (Cmnd->use_sg) { |
875 | int sg_count; | 875 | int sg_count; |
876 | 876 | ||
877 | sg = (struct scatterlist *) Cmnd->buffer; | 877 | sg = (struct scatterlist *) Cmnd->request_buffer; |
878 | sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); | 878 | sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); |
879 | 879 | ||
880 | ds = cmd->dataseg; | 880 | ds = cmd->dataseg; |
@@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) | |||
1278 | 1278 | ||
1279 | if (Cmnd->use_sg) { | 1279 | if (Cmnd->use_sg) { |
1280 | sbus_unmap_sg(qpti->sdev, | 1280 | sbus_unmap_sg(qpti->sdev, |
1281 | (struct scatterlist *)Cmnd->buffer, | 1281 | (struct scatterlist *)Cmnd->request_buffer, |
1282 | Cmnd->use_sg, | 1282 | Cmnd->use_sg, |
1283 | Cmnd->sc_data_direction); | 1283 | Cmnd->sc_data_direction); |
1284 | } else { | 1284 | } else { |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 64631bd38952..4776f4e55839 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -269,8 +269,15 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { | |||
269 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 269 | { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
270 | board_20619 }, | 270 | board_20619 }, |
271 | 271 | ||
272 | /* TODO: remove all associated board_20771 code, as it completely | ||
273 | * duplicates board_2037x code, unless reason for separation can be | ||
274 | * divined. | ||
275 | */ | ||
276 | #if 0 | ||
272 | { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 277 | { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
273 | board_20771 }, | 278 | board_20771 }, |
279 | #endif | ||
280 | |||
274 | { } /* terminate list */ | 281 | { } /* terminate list */ |
275 | }; | 282 | }; |
276 | 283 | ||
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 2e0f4a4076af..3f368c7d3ef9 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1106 | 1106 | ||
1107 | probe_ent->irq = pdev->irq; | 1107 | probe_ent->irq = pdev->irq; |
1108 | probe_ent->irq_flags = IRQF_SHARED; | 1108 | probe_ent->irq_flags = IRQF_SHARED; |
1109 | probe_ent->mmio_base = port_base; | ||
1110 | probe_ent->private_data = hpriv; | 1109 | probe_ent->private_data = hpriv; |
1111 | 1110 | ||
1112 | hpriv->host_base = host_base; | 1111 | hpriv->host_base = host_base; |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2ab7df0dcfe8..b332caddd5b3 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) | |||
346 | if (level > 3) { | 346 | if (level > 3) { |
347 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," | 347 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," |
348 | " done = 0x%p, queuecommand 0x%p\n", | 348 | " done = 0x%p, queuecommand 0x%p\n", |
349 | cmd->buffer, cmd->bufflen, | 349 | cmd->request_buffer, cmd->request_bufflen, |
350 | cmd->done, | 350 | cmd->done, |
351 | sdev->host->hostt->queuecommand); | 351 | sdev->host->hostt->queuecommand); |
352 | 352 | ||
@@ -661,11 +661,6 @@ void __scsi_done(struct scsi_cmnd *cmd) | |||
661 | */ | 661 | */ |
662 | int scsi_retry_command(struct scsi_cmnd *cmd) | 662 | int scsi_retry_command(struct scsi_cmnd *cmd) |
663 | { | 663 | { |
664 | /* | ||
665 | * Restore the SCSI command state. | ||
666 | */ | ||
667 | scsi_setup_cmd_retry(cmd); | ||
668 | |||
669 | /* | 664 | /* |
670 | * Zero the sense information from the last time we tried | 665 | * Zero the sense information from the last time we tried |
671 | * this command. | 666 | * this command. |
@@ -711,10 +706,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
711 | "Notifying upper driver of completion " | 706 | "Notifying upper driver of completion " |
712 | "(result %x)\n", cmd->result)); | 707 | "(result %x)\n", cmd->result)); |
713 | 708 | ||
714 | /* | ||
715 | * We can get here with use_sg=0, causing a panic in the upper level | ||
716 | */ | ||
717 | cmd->use_sg = cmd->old_use_sg; | ||
718 | cmd->done(cmd); | 709 | cmd->done(cmd); |
719 | } | 710 | } |
720 | EXPORT_SYMBOL(scsi_finish_command); | 711 | EXPORT_SYMBOL(scsi_finish_command); |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9c63b00773c4..a80303c6b3fd 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, | |||
286 | int dev_id_num, const char * dev_id_str, | 286 | int dev_id_num, const char * dev_id_str, |
287 | int dev_id_str_len); | 287 | int dev_id_str_len); |
288 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | 288 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); |
289 | static void do_create_driverfs_files(void); | 289 | static int do_create_driverfs_files(void); |
290 | static void do_remove_driverfs_files(void); | 290 | static void do_remove_driverfs_files(void); |
291 | 291 | ||
292 | static int sdebug_add_adapter(void); | 292 | static int sdebug_add_adapter(void); |
@@ -2487,19 +2487,22 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp, | |||
2487 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, | 2487 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, |
2488 | sdebug_add_host_store); | 2488 | sdebug_add_host_store); |
2489 | 2489 | ||
2490 | static void do_create_driverfs_files(void) | 2490 | static int do_create_driverfs_files(void) |
2491 | { | 2491 | { |
2492 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); | 2492 | int ret; |
2493 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); | 2493 | |
2494 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); | 2494 | ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); |
2495 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); | 2495 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); |
2496 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); | 2496 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); |
2497 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); | 2497 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); |
2498 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); | 2498 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); |
2499 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); | 2499 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); |
2500 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); | 2500 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); |
2501 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); | 2501 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); |
2502 | driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); | 2502 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); |
2503 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); | ||
2504 | ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); | ||
2505 | return ret; | ||
2503 | } | 2506 | } |
2504 | 2507 | ||
2505 | static void do_remove_driverfs_files(void) | 2508 | static void do_remove_driverfs_files(void) |
@@ -2522,6 +2525,7 @@ static int __init scsi_debug_init(void) | |||
2522 | unsigned int sz; | 2525 | unsigned int sz; |
2523 | int host_to_add; | 2526 | int host_to_add; |
2524 | int k; | 2527 | int k; |
2528 | int ret; | ||
2525 | 2529 | ||
2526 | if (scsi_debug_dev_size_mb < 1) | 2530 | if (scsi_debug_dev_size_mb < 1) |
2527 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2531 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
@@ -2560,12 +2564,32 @@ static int __init scsi_debug_init(void) | |||
2560 | if (scsi_debug_num_parts > 0) | 2564 | if (scsi_debug_num_parts > 0) |
2561 | sdebug_build_parts(fake_storep); | 2565 | sdebug_build_parts(fake_storep); |
2562 | 2566 | ||
2563 | init_all_queued(); | 2567 | ret = device_register(&pseudo_primary); |
2568 | if (ret < 0) { | ||
2569 | printk(KERN_WARNING "scsi_debug: device_register error: %d\n", | ||
2570 | ret); | ||
2571 | goto free_vm; | ||
2572 | } | ||
2573 | ret = bus_register(&pseudo_lld_bus); | ||
2574 | if (ret < 0) { | ||
2575 | printk(KERN_WARNING "scsi_debug: bus_register error: %d\n", | ||
2576 | ret); | ||
2577 | goto dev_unreg; | ||
2578 | } | ||
2579 | ret = driver_register(&sdebug_driverfs_driver); | ||
2580 | if (ret < 0) { | ||
2581 | printk(KERN_WARNING "scsi_debug: driver_register error: %d\n", | ||
2582 | ret); | ||
2583 | goto bus_unreg; | ||
2584 | } | ||
2585 | ret = do_create_driverfs_files(); | ||
2586 | if (ret < 0) { | ||
2587 | printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n", | ||
2588 | ret); | ||
2589 | goto del_files; | ||
2590 | } | ||
2564 | 2591 | ||
2565 | device_register(&pseudo_primary); | 2592 | init_all_queued(); |
2566 | bus_register(&pseudo_lld_bus); | ||
2567 | driver_register(&sdebug_driverfs_driver); | ||
2568 | do_create_driverfs_files(); | ||
2569 | 2593 | ||
2570 | sdebug_driver_template.proc_name = (char *)sdebug_proc_name; | 2594 | sdebug_driver_template.proc_name = (char *)sdebug_proc_name; |
2571 | 2595 | ||
@@ -2585,6 +2609,18 @@ static int __init scsi_debug_init(void) | |||
2585 | scsi_debug_add_host); | 2609 | scsi_debug_add_host); |
2586 | } | 2610 | } |
2587 | return 0; | 2611 | return 0; |
2612 | |||
2613 | del_files: | ||
2614 | do_remove_driverfs_files(); | ||
2615 | driver_unregister(&sdebug_driverfs_driver); | ||
2616 | bus_unreg: | ||
2617 | bus_unregister(&pseudo_lld_bus); | ||
2618 | dev_unreg: | ||
2619 | device_unregister(&pseudo_primary); | ||
2620 | free_vm: | ||
2621 | vfree(fake_storep); | ||
2622 | |||
2623 | return ret; | ||
2588 | } | 2624 | } |
2589 | 2625 | ||
2590 | static void __exit scsi_debug_exit(void) | 2626 | static void __exit scsi_debug_exit(void) |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6683d596234a..6a5b731bd5ba 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -460,19 +460,67 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) | |||
460 | * Return value: | 460 | * Return value: |
461 | * SUCCESS or FAILED or NEEDS_RETRY | 461 | * SUCCESS or FAILED or NEEDS_RETRY |
462 | **/ | 462 | **/ |
463 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) | 463 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense) |
464 | { | 464 | { |
465 | struct scsi_device *sdev = scmd->device; | 465 | struct scsi_device *sdev = scmd->device; |
466 | struct Scsi_Host *shost = sdev->host; | 466 | struct Scsi_Host *shost = sdev->host; |
467 | int old_result = scmd->result; | ||
467 | DECLARE_COMPLETION(done); | 468 | DECLARE_COMPLETION(done); |
468 | unsigned long timeleft; | 469 | unsigned long timeleft; |
469 | unsigned long flags; | 470 | unsigned long flags; |
471 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; | ||
472 | enum dma_data_direction old_data_direction; | ||
473 | unsigned short old_use_sg; | ||
474 | unsigned char old_cmd_len; | ||
475 | unsigned old_bufflen; | ||
476 | void *old_buffer; | ||
470 | int rtn; | 477 | int rtn; |
471 | 478 | ||
479 | /* | ||
480 | * We need saved copies of a number of fields - this is because | ||
481 | * error handling may need to overwrite these with different values | ||
482 | * to run different commands, and once error handling is complete, | ||
483 | * we will need to restore these values prior to running the actual | ||
484 | * command. | ||
485 | */ | ||
486 | old_buffer = scmd->request_buffer; | ||
487 | old_bufflen = scmd->request_bufflen; | ||
488 | memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); | ||
489 | old_data_direction = scmd->sc_data_direction; | ||
490 | old_cmd_len = scmd->cmd_len; | ||
491 | old_use_sg = scmd->use_sg; | ||
492 | |||
493 | if (copy_sense) { | ||
494 | int gfp_mask = GFP_ATOMIC; | ||
495 | |||
496 | if (shost->hostt->unchecked_isa_dma) | ||
497 | gfp_mask |= __GFP_DMA; | ||
498 | |||
499 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
500 | scmd->request_bufflen = 252; | ||
501 | scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); | ||
502 | if (!scmd->request_buffer) | ||
503 | return FAILED; | ||
504 | } else { | ||
505 | scmd->request_buffer = NULL; | ||
506 | scmd->request_bufflen = 0; | ||
507 | scmd->sc_data_direction = DMA_NONE; | ||
508 | } | ||
509 | |||
510 | scmd->underflow = 0; | ||
511 | scmd->use_sg = 0; | ||
512 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
513 | |||
472 | if (sdev->scsi_level <= SCSI_2) | 514 | if (sdev->scsi_level <= SCSI_2) |
473 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | | 515 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | |
474 | (sdev->lun << 5 & 0xe0); | 516 | (sdev->lun << 5 & 0xe0); |
475 | 517 | ||
518 | /* | ||
519 | * Zero the sense buffer. The scsi spec mandates that any | ||
520 | * untransferred sense data should be interpreted as being zero. | ||
521 | */ | ||
522 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); | ||
523 | |||
476 | shost->eh_action = &done; | 524 | shost->eh_action = &done; |
477 | 525 | ||
478 | spin_lock_irqsave(shost->host_lock, flags); | 526 | spin_lock_irqsave(shost->host_lock, flags); |
@@ -522,6 +570,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) | |||
522 | rtn = FAILED; | 570 | rtn = FAILED; |
523 | } | 571 | } |
524 | 572 | ||
573 | |||
574 | /* | ||
575 | * Last chance to have valid sense data. | ||
576 | */ | ||
577 | if (copy_sense) { | ||
578 | if (!SCSI_SENSE_VALID(scmd)) { | ||
579 | memcpy(scmd->sense_buffer, scmd->request_buffer, | ||
580 | sizeof(scmd->sense_buffer)); | ||
581 | } | ||
582 | kfree(scmd->request_buffer); | ||
583 | } | ||
584 | |||
585 | |||
586 | /* | ||
587 | * Restore original data | ||
588 | */ | ||
589 | scmd->request_buffer = old_buffer; | ||
590 | scmd->request_bufflen = old_bufflen; | ||
591 | memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); | ||
592 | scmd->sc_data_direction = old_data_direction; | ||
593 | scmd->cmd_len = old_cmd_len; | ||
594 | scmd->use_sg = old_use_sg; | ||
595 | scmd->result = old_result; | ||
525 | return rtn; | 596 | return rtn; |
526 | } | 597 | } |
527 | 598 | ||
@@ -537,56 +608,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) | |||
537 | static int scsi_request_sense(struct scsi_cmnd *scmd) | 608 | static int scsi_request_sense(struct scsi_cmnd *scmd) |
538 | { | 609 | { |
539 | static unsigned char generic_sense[6] = | 610 | static unsigned char generic_sense[6] = |
540 | {REQUEST_SENSE, 0, 0, 0, 252, 0}; | 611 | {REQUEST_SENSE, 0, 0, 0, 252, 0}; |
541 | unsigned char *scsi_result; | ||
542 | int saved_result; | ||
543 | int rtn; | ||
544 | 612 | ||
545 | memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); | 613 | memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); |
546 | 614 | return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1); | |
547 | scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0)); | ||
548 | |||
549 | |||
550 | if (unlikely(!scsi_result)) { | ||
551 | printk(KERN_ERR "%s: cannot allocate scsi_result.\n", | ||
552 | __FUNCTION__); | ||
553 | return FAILED; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * zero the sense buffer. some host adapters automatically always | ||
558 | * request sense, so it is not a good idea that | ||
559 | * scmd->request_buffer and scmd->sense_buffer point to the same | ||
560 | * address (db). 0 is not a valid sense code. | ||
561 | */ | ||
562 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); | ||
563 | memset(scsi_result, 0, 252); | ||
564 | |||
565 | saved_result = scmd->result; | ||
566 | scmd->request_buffer = scsi_result; | ||
567 | scmd->request_bufflen = 252; | ||
568 | scmd->use_sg = 0; | ||
569 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
570 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
571 | scmd->underflow = 0; | ||
572 | |||
573 | rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); | ||
574 | |||
575 | /* last chance to have valid sense data */ | ||
576 | if(!SCSI_SENSE_VALID(scmd)) { | ||
577 | memcpy(scmd->sense_buffer, scmd->request_buffer, | ||
578 | sizeof(scmd->sense_buffer)); | ||
579 | } | ||
580 | |||
581 | kfree(scsi_result); | ||
582 | |||
583 | /* | ||
584 | * when we eventually call scsi_finish, we really wish to complete | ||
585 | * the original request, so let's restore the original data. (db) | ||
586 | */ | ||
587 | scsi_setup_cmd_retry(scmd); | ||
588 | scmd->result = saved_result; | ||
589 | return rtn; | ||
590 | } | 615 | } |
591 | 616 | ||
592 | /** | 617 | /** |
@@ -605,12 +630,6 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) | |||
605 | { | 630 | { |
606 | scmd->device->host->host_failed--; | 631 | scmd->device->host->host_failed--; |
607 | scmd->eh_eflags = 0; | 632 | scmd->eh_eflags = 0; |
608 | |||
609 | /* | ||
610 | * set this back so that the upper level can correctly free up | ||
611 | * things. | ||
612 | */ | ||
613 | scsi_setup_cmd_retry(scmd); | ||
614 | list_move_tail(&scmd->eh_entry, done_q); | 633 | list_move_tail(&scmd->eh_entry, done_q); |
615 | } | 634 | } |
616 | EXPORT_SYMBOL(scsi_eh_finish_cmd); | 635 | EXPORT_SYMBOL(scsi_eh_finish_cmd); |
@@ -715,47 +734,26 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) | |||
715 | { | 734 | { |
716 | static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; | 735 | static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; |
717 | int retry_cnt = 1, rtn; | 736 | int retry_cnt = 1, rtn; |
718 | int saved_result; | ||
719 | 737 | ||
720 | retry_tur: | 738 | retry_tur: |
721 | memcpy(scmd->cmnd, tur_command, sizeof(tur_command)); | 739 | memcpy(scmd->cmnd, tur_command, sizeof(tur_command)); |
722 | 740 | ||
723 | /* | ||
724 | * zero the sense buffer. the scsi spec mandates that any | ||
725 | * untransferred sense data should be interpreted as being zero. | ||
726 | */ | ||
727 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); | ||
728 | |||
729 | saved_result = scmd->result; | ||
730 | scmd->request_buffer = NULL; | ||
731 | scmd->request_bufflen = 0; | ||
732 | scmd->use_sg = 0; | ||
733 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
734 | scmd->underflow = 0; | ||
735 | scmd->sc_data_direction = DMA_NONE; | ||
736 | 741 | ||
737 | rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); | 742 | rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0); |
738 | 743 | ||
739 | /* | ||
740 | * when we eventually call scsi_finish, we really wish to complete | ||
741 | * the original request, so let's restore the original data. (db) | ||
742 | */ | ||
743 | scsi_setup_cmd_retry(scmd); | ||
744 | scmd->result = saved_result; | ||
745 | |||
746 | /* | ||
747 | * hey, we are done. let's look to see what happened. | ||
748 | */ | ||
749 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", | 744 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", |
750 | __FUNCTION__, scmd, rtn)); | 745 | __FUNCTION__, scmd, rtn)); |
751 | if (rtn == SUCCESS) | 746 | |
752 | return 0; | 747 | switch (rtn) { |
753 | else if (rtn == NEEDS_RETRY) { | 748 | case NEEDS_RETRY: |
754 | if (retry_cnt--) | 749 | if (retry_cnt--) |
755 | goto retry_tur; | 750 | goto retry_tur; |
751 | /*FALLTHRU*/ | ||
752 | case SUCCESS: | ||
756 | return 0; | 753 | return 0; |
754 | default: | ||
755 | return 1; | ||
757 | } | 756 | } |
758 | return 1; | ||
759 | } | 757 | } |
760 | 758 | ||
761 | /** | 759 | /** |
@@ -837,44 +835,16 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
837 | static int scsi_eh_try_stu(struct scsi_cmnd *scmd) | 835 | static int scsi_eh_try_stu(struct scsi_cmnd *scmd) |
838 | { | 836 | { |
839 | static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; | 837 | static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; |
840 | int rtn; | ||
841 | int saved_result; | ||
842 | 838 | ||
843 | if (!scmd->device->allow_restart) | 839 | if (scmd->device->allow_restart) { |
844 | return 1; | 840 | int rtn; |
845 | |||
846 | memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); | ||
847 | |||
848 | /* | ||
849 | * zero the sense buffer. the scsi spec mandates that any | ||
850 | * untransferred sense data should be interpreted as being zero. | ||
851 | */ | ||
852 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); | ||
853 | |||
854 | saved_result = scmd->result; | ||
855 | scmd->request_buffer = NULL; | ||
856 | scmd->request_bufflen = 0; | ||
857 | scmd->use_sg = 0; | ||
858 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
859 | scmd->underflow = 0; | ||
860 | scmd->sc_data_direction = DMA_NONE; | ||
861 | 841 | ||
862 | rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT); | 842 | memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); |
863 | 843 | rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0); | |
864 | /* | 844 | if (rtn == SUCCESS) |
865 | * when we eventually call scsi_finish, we really wish to complete | 845 | return 0; |
866 | * the original request, so let's restore the original data. (db) | 846 | } |
867 | */ | ||
868 | scsi_setup_cmd_retry(scmd); | ||
869 | scmd->result = saved_result; | ||
870 | 847 | ||
871 | /* | ||
872 | * hey, we are done. let's look to see what happened. | ||
873 | */ | ||
874 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", | ||
875 | __FUNCTION__, scmd, rtn)); | ||
876 | if (rtn == SUCCESS) | ||
877 | return 0; | ||
878 | return 1; | 848 | return 1; |
879 | } | 849 | } |
880 | 850 | ||
@@ -1684,8 +1654,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1684 | 1654 | ||
1685 | scmd->scsi_done = scsi_reset_provider_done_command; | 1655 | scmd->scsi_done = scsi_reset_provider_done_command; |
1686 | scmd->done = NULL; | 1656 | scmd->done = NULL; |
1687 | scmd->buffer = NULL; | ||
1688 | scmd->bufflen = 0; | ||
1689 | scmd->request_buffer = NULL; | 1657 | scmd->request_buffer = NULL; |
1690 | scmd->request_bufflen = 0; | 1658 | scmd->request_bufflen = 0; |
1691 | 1659 | ||
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index a89c4115cfba..32293f451669 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c | |||
@@ -110,11 +110,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, | |||
110 | sshdr.asc, sshdr.ascq); | 110 | sshdr.asc, sshdr.ascq); |
111 | break; | 111 | break; |
112 | case NOT_READY: /* This happens if there is no disc in drive */ | 112 | case NOT_READY: /* This happens if there is no disc in drive */ |
113 | if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) { | 113 | if (sdev->removable) |
114 | printk(KERN_INFO "Device not ready. Make sure" | ||
115 | " there is a disc in the drive.\n"); | ||
116 | break; | 114 | break; |
117 | } | ||
118 | case UNIT_ATTENTION: | 115 | case UNIT_ATTENTION: |
119 | if (sdev->removable) { | 116 | if (sdev->removable) { |
120 | sdev->changed = 1; | 117 | sdev->changed = 1; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 08af9aae7df3..077c1c691210 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -436,60 +436,16 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); | |||
436 | * | 436 | * |
437 | * Arguments: cmd - command that is ready to be queued. | 437 | * Arguments: cmd - command that is ready to be queued. |
438 | * | 438 | * |
439 | * Returns: Nothing | ||
440 | * | ||
441 | * Notes: This function has the job of initializing a number of | 439 | * Notes: This function has the job of initializing a number of |
442 | * fields related to error handling. Typically this will | 440 | * fields related to error handling. Typically this will |
443 | * be called once for each command, as required. | 441 | * be called once for each command, as required. |
444 | */ | 442 | */ |
445 | static int scsi_init_cmd_errh(struct scsi_cmnd *cmd) | 443 | static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) |
446 | { | 444 | { |
447 | cmd->serial_number = 0; | 445 | cmd->serial_number = 0; |
448 | |||
449 | memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); | 446 | memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); |
450 | |||
451 | if (cmd->cmd_len == 0) | 447 | if (cmd->cmd_len == 0) |
452 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); | 448 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); |
453 | |||
454 | /* | ||
455 | * We need saved copies of a number of fields - this is because | ||
456 | * error handling may need to overwrite these with different values | ||
457 | * to run different commands, and once error handling is complete, | ||
458 | * we will need to restore these values prior to running the actual | ||
459 | * command. | ||
460 | */ | ||
461 | cmd->old_use_sg = cmd->use_sg; | ||
462 | cmd->old_cmd_len = cmd->cmd_len; | ||
463 | cmd->sc_old_data_direction = cmd->sc_data_direction; | ||
464 | cmd->old_underflow = cmd->underflow; | ||
465 | memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd)); | ||
466 | cmd->buffer = cmd->request_buffer; | ||
467 | cmd->bufflen = cmd->request_bufflen; | ||
468 | |||
469 | return 1; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Function: scsi_setup_cmd_retry() | ||
474 | * | ||
475 | * Purpose: Restore the command state for a retry | ||
476 | * | ||
477 | * Arguments: cmd - command to be restored | ||
478 | * | ||
479 | * Returns: Nothing | ||
480 | * | ||
481 | * Notes: Immediately prior to retrying a command, we need | ||
482 | * to restore certain fields that we saved above. | ||
483 | */ | ||
484 | void scsi_setup_cmd_retry(struct scsi_cmnd *cmd) | ||
485 | { | ||
486 | memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd)); | ||
487 | cmd->request_buffer = cmd->buffer; | ||
488 | cmd->request_bufflen = cmd->bufflen; | ||
489 | cmd->use_sg = cmd->old_use_sg; | ||
490 | cmd->cmd_len = cmd->old_cmd_len; | ||
491 | cmd->sc_data_direction = cmd->sc_old_data_direction; | ||
492 | cmd->underflow = cmd->old_underflow; | ||
493 | } | 449 | } |
494 | 450 | ||
495 | void scsi_device_unbusy(struct scsi_device *sdev) | 451 | void scsi_device_unbusy(struct scsi_device *sdev) |
@@ -807,22 +763,13 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) | |||
807 | */ | 763 | */ |
808 | static void scsi_release_buffers(struct scsi_cmnd *cmd) | 764 | static void scsi_release_buffers(struct scsi_cmnd *cmd) |
809 | { | 765 | { |
810 | struct request *req = cmd->request; | ||
811 | |||
812 | /* | ||
813 | * Free up any indirection buffers we allocated for DMA purposes. | ||
814 | */ | ||
815 | if (cmd->use_sg) | 766 | if (cmd->use_sg) |
816 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); | 767 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); |
817 | else if (cmd->request_buffer != req->buffer) | ||
818 | kfree(cmd->request_buffer); | ||
819 | 768 | ||
820 | /* | 769 | /* |
821 | * Zero these out. They now point to freed memory, and it is | 770 | * Zero these out. They now point to freed memory, and it is |
822 | * dangerous to hang onto the pointers. | 771 | * dangerous to hang onto the pointers. |
823 | */ | 772 | */ |
824 | cmd->buffer = NULL; | ||
825 | cmd->bufflen = 0; | ||
826 | cmd->request_buffer = NULL; | 773 | cmd->request_buffer = NULL; |
827 | cmd->request_bufflen = 0; | 774 | cmd->request_bufflen = 0; |
828 | } | 775 | } |
@@ -858,7 +805,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | 805 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
859 | { | 806 | { |
860 | int result = cmd->result; | 807 | int result = cmd->result; |
861 | int this_count = cmd->bufflen; | 808 | int this_count = cmd->request_bufflen; |
862 | request_queue_t *q = cmd->device->request_queue; | 809 | request_queue_t *q = cmd->device->request_queue; |
863 | struct request *req = cmd->request; | 810 | struct request *req = cmd->request; |
864 | int clear_errors = 1; | 811 | int clear_errors = 1; |
@@ -866,28 +813,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
866 | int sense_valid = 0; | 813 | int sense_valid = 0; |
867 | int sense_deferred = 0; | 814 | int sense_deferred = 0; |
868 | 815 | ||
869 | /* | 816 | scsi_release_buffers(cmd); |
870 | * Free up any indirection buffers we allocated for DMA purposes. | ||
871 | * For the case of a READ, we need to copy the data out of the | ||
872 | * bounce buffer and into the real buffer. | ||
873 | */ | ||
874 | if (cmd->use_sg) | ||
875 | scsi_free_sgtable(cmd->buffer, cmd->sglist_len); | ||
876 | else if (cmd->buffer != req->buffer) { | ||
877 | if (rq_data_dir(req) == READ) { | ||
878 | unsigned long flags; | ||
879 | char *to = bio_kmap_irq(req->bio, &flags); | ||
880 | memcpy(to, cmd->buffer, cmd->bufflen); | ||
881 | bio_kunmap_irq(to, &flags); | ||
882 | } | ||
883 | kfree(cmd->buffer); | ||
884 | } | ||
885 | 817 | ||
886 | if (result) { | 818 | if (result) { |
887 | sense_valid = scsi_command_normalize_sense(cmd, &sshdr); | 819 | sense_valid = scsi_command_normalize_sense(cmd, &sshdr); |
888 | if (sense_valid) | 820 | if (sense_valid) |
889 | sense_deferred = scsi_sense_is_deferred(&sshdr); | 821 | sense_deferred = scsi_sense_is_deferred(&sshdr); |
890 | } | 822 | } |
823 | |||
891 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ | 824 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ |
892 | req->errors = result; | 825 | req->errors = result; |
893 | if (result) { | 826 | if (result) { |
@@ -908,15 +841,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
908 | } | 841 | } |
909 | 842 | ||
910 | /* | 843 | /* |
911 | * Zero these out. They now point to freed memory, and it is | ||
912 | * dangerous to hang onto the pointers. | ||
913 | */ | ||
914 | cmd->buffer = NULL; | ||
915 | cmd->bufflen = 0; | ||
916 | cmd->request_buffer = NULL; | ||
917 | cmd->request_bufflen = 0; | ||
918 | |||
919 | /* | ||
920 | * Next deal with any sectors which we were able to correctly | 844 | * Next deal with any sectors which we were able to correctly |
921 | * handle. | 845 | * handle. |
922 | */ | 846 | */ |
@@ -1012,7 +936,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
1012 | if (!(req->flags & REQ_QUIET)) { | 936 | if (!(req->flags & REQ_QUIET)) { |
1013 | scmd_printk(KERN_INFO, cmd, | 937 | scmd_printk(KERN_INFO, cmd, |
1014 | "Volume overflow, CDB: "); | 938 | "Volume overflow, CDB: "); |
1015 | __scsi_print_command(cmd->data_cmnd); | 939 | __scsi_print_command(cmd->cmnd); |
1016 | scsi_print_sense("", cmd); | 940 | scsi_print_sense("", cmd); |
1017 | } | 941 | } |
1018 | /* See SSC3rXX or current. */ | 942 | /* See SSC3rXX or current. */ |
@@ -1143,7 +1067,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1143 | * successfully. Since this is a REQ_BLOCK_PC command the | 1067 | * successfully. Since this is a REQ_BLOCK_PC command the |
1144 | * caller should check the request's errors value | 1068 | * caller should check the request's errors value |
1145 | */ | 1069 | */ |
1146 | scsi_io_completion(cmd, cmd->bufflen); | 1070 | scsi_io_completion(cmd, cmd->request_bufflen); |
1147 | } | 1071 | } |
1148 | 1072 | ||
1149 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1073 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index e2fbe9a9d5a9..ae24c85aaeea 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -57,7 +57,6 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); | |||
57 | 57 | ||
58 | /* scsi_lib.c */ | 58 | /* scsi_lib.c */ |
59 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); | 59 | extern int scsi_maybe_unblock_host(struct scsi_device *sdev); |
60 | extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd); | ||
61 | extern void scsi_device_unbusy(struct scsi_device *sdev); | 60 | extern void scsi_device_unbusy(struct scsi_device *sdev); |
62 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); | 61 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); |
63 | extern void scsi_next_command(struct scsi_cmnd *cmd); | 62 | extern void scsi_next_command(struct scsi_cmnd *cmd); |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index dd075627e605..5a625c3fddae 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -41,6 +41,7 @@ struct sas_host_attrs { | |||
41 | struct mutex lock; | 41 | struct mutex lock; |
42 | u32 next_target_id; | 42 | u32 next_target_id; |
43 | u32 next_expander_id; | 43 | u32 next_expander_id; |
44 | int next_port_id; | ||
44 | }; | 45 | }; |
45 | #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) | 46 | #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) |
46 | 47 | ||
@@ -146,6 +147,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, | |||
146 | mutex_init(&sas_host->lock); | 147 | mutex_init(&sas_host->lock); |
147 | sas_host->next_target_id = 0; | 148 | sas_host->next_target_id = 0; |
148 | sas_host->next_expander_id = 0; | 149 | sas_host->next_expander_id = 0; |
150 | sas_host->next_port_id = 0; | ||
149 | return 0; | 151 | return 0; |
150 | } | 152 | } |
151 | 153 | ||
@@ -327,7 +329,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, | |||
327 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", | 329 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", |
328 | unsigned long long); | 330 | unsigned long long); |
329 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); | 331 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); |
330 | //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); | 332 | //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int); |
331 | sas_phy_linkspeed_attr(negotiated_linkrate); | 333 | sas_phy_linkspeed_attr(negotiated_linkrate); |
332 | sas_phy_linkspeed_attr(minimum_linkrate_hw); | 334 | sas_phy_linkspeed_attr(minimum_linkrate_hw); |
333 | sas_phy_linkspeed_attr(minimum_linkrate); | 335 | sas_phy_linkspeed_attr(minimum_linkrate); |
@@ -590,6 +592,38 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id) | |||
590 | } | 592 | } |
591 | EXPORT_SYMBOL(sas_port_alloc); | 593 | EXPORT_SYMBOL(sas_port_alloc); |
592 | 594 | ||
595 | /** sas_port_alloc_num - allocate and initialize a SAS port structure | ||
596 | * | ||
597 | * @parent: parent device | ||
598 | * | ||
599 | * Allocates a SAS port structure and a number to go with it. This | ||
600 | * interface is really for adapters where the port number has no | ||
601 | * meansing, so the sas class should manage them. It will be added to | ||
602 | * the device tree below the device specified by @parent which must be | ||
603 | * either a Scsi_Host or a sas_expander_device. | ||
604 | * | ||
605 | * Returns %NULL on error | ||
606 | */ | ||
607 | struct sas_port *sas_port_alloc_num(struct device *parent) | ||
608 | { | ||
609 | int index; | ||
610 | struct Scsi_Host *shost = dev_to_shost(parent); | ||
611 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | ||
612 | |||
613 | /* FIXME: use idr for this eventually */ | ||
614 | mutex_lock(&sas_host->lock); | ||
615 | if (scsi_is_sas_expander_device(parent)) { | ||
616 | struct sas_rphy *rphy = dev_to_rphy(parent); | ||
617 | struct sas_expander_device *exp = rphy_to_expander_device(rphy); | ||
618 | |||
619 | index = exp->next_port_id++; | ||
620 | } else | ||
621 | index = sas_host->next_port_id++; | ||
622 | mutex_unlock(&sas_host->lock); | ||
623 | return sas_port_alloc(parent, index); | ||
624 | } | ||
625 | EXPORT_SYMBOL(sas_port_alloc_num); | ||
626 | |||
593 | /** | 627 | /** |
594 | * sas_port_add - add a SAS port to the device hierarchy | 628 | * sas_port_add - add a SAS port to the device hierarchy |
595 | * | 629 | * |
@@ -658,6 +692,13 @@ void sas_port_delete(struct sas_port *port) | |||
658 | } | 692 | } |
659 | mutex_unlock(&port->phy_list_mutex); | 693 | mutex_unlock(&port->phy_list_mutex); |
660 | 694 | ||
695 | if (port->is_backlink) { | ||
696 | struct device *parent = port->dev.parent; | ||
697 | |||
698 | sysfs_remove_link(&port->dev.kobj, parent->bus_id); | ||
699 | port->is_backlink = 0; | ||
700 | } | ||
701 | |||
661 | transport_remove_device(dev); | 702 | transport_remove_device(dev); |
662 | device_del(dev); | 703 | device_del(dev); |
663 | transport_destroy_device(dev); | 704 | transport_destroy_device(dev); |
@@ -733,6 +774,19 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) | |||
733 | } | 774 | } |
734 | EXPORT_SYMBOL(sas_port_delete_phy); | 775 | EXPORT_SYMBOL(sas_port_delete_phy); |
735 | 776 | ||
777 | void sas_port_mark_backlink(struct sas_port *port) | ||
778 | { | ||
779 | struct device *parent = port->dev.parent->parent->parent; | ||
780 | |||
781 | if (port->is_backlink) | ||
782 | return; | ||
783 | port->is_backlink = 1; | ||
784 | sysfs_create_link(&port->dev.kobj, &parent->kobj, | ||
785 | parent->bus_id); | ||
786 | |||
787 | } | ||
788 | EXPORT_SYMBOL(sas_port_mark_backlink); | ||
789 | |||
736 | /* | 790 | /* |
737 | * SAS remote PHY attributes. | 791 | * SAS remote PHY attributes. |
738 | */ | 792 | */ |
@@ -1140,7 +1194,7 @@ int sas_rphy_add(struct sas_rphy *rphy) | |||
1140 | 1194 | ||
1141 | if (identify->device_type == SAS_END_DEVICE && | 1195 | if (identify->device_type == SAS_END_DEVICE && |
1142 | rphy->scsi_target_id != -1) { | 1196 | rphy->scsi_target_id != -1) { |
1143 | scsi_scan_target(&rphy->dev, parent->port_identifier, | 1197 | scsi_scan_target(&rphy->dev, 0, |
1144 | rphy->scsi_target_id, ~0, 0); | 1198 | rphy->scsi_target_id, ~0, 0); |
1145 | } | 1199 | } |
1146 | 1200 | ||
@@ -1242,15 +1296,13 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1242 | 1296 | ||
1243 | mutex_lock(&sas_host->lock); | 1297 | mutex_lock(&sas_host->lock); |
1244 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { | 1298 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { |
1245 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); | ||
1246 | |||
1247 | if (rphy->identify.device_type != SAS_END_DEVICE || | 1299 | if (rphy->identify.device_type != SAS_END_DEVICE || |
1248 | rphy->scsi_target_id == -1) | 1300 | rphy->scsi_target_id == -1) |
1249 | continue; | 1301 | continue; |
1250 | 1302 | ||
1251 | if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) && | 1303 | if ((channel == SCAN_WILD_CARD || channel == 0) && |
1252 | (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { | 1304 | (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { |
1253 | scsi_scan_target(&rphy->dev, parent->port_identifier, | 1305 | scsi_scan_target(&rphy->dev, 0, |
1254 | rphy->scsi_target_id, lun, 1); | 1306 | rphy->scsi_target_id, lun, 1); |
1255 | } | 1307 | } |
1256 | } | 1308 | } |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3225d31449e1..98bd3aab9739 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -502,8 +502,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
502 | SCpnt->cmnd[4] = (unsigned char) this_count; | 502 | SCpnt->cmnd[4] = (unsigned char) this_count; |
503 | SCpnt->cmnd[5] = 0; | 503 | SCpnt->cmnd[5] = 0; |
504 | } | 504 | } |
505 | SCpnt->request_bufflen = SCpnt->bufflen = | 505 | SCpnt->request_bufflen = this_count * sdp->sector_size; |
506 | this_count * sdp->sector_size; | ||
507 | 506 | ||
508 | /* | 507 | /* |
509 | * We shouldn't disconnect in the middle of a sector, so with a dumb | 508 | * We shouldn't disconnect in the middle of a sector, so with a dumb |
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 3f312a84c6a7..2679ea8bff1a 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c | |||
@@ -1002,7 +1002,7 @@ connect_loop: | |||
1002 | } | 1002 | } |
1003 | #endif | 1003 | #endif |
1004 | 1004 | ||
1005 | buffer = (struct scatterlist *) SCint->buffer; | 1005 | buffer = (struct scatterlist *) SCint->request_buffer; |
1006 | len = buffer->length; | 1006 | len = buffer->length; |
1007 | data = page_address(buffer->page) + buffer->offset; | 1007 | data = page_address(buffer->page) + buffer->offset; |
1008 | } else { | 1008 | } else { |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index fd94408577e5..fae6e95a6298 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
360 | "mismatch count %d, bytes %d\n", | 360 | "mismatch count %d, bytes %d\n", |
361 | size, SCpnt->request_bufflen); | 361 | size, SCpnt->request_bufflen); |
362 | if (SCpnt->request_bufflen > size) | 362 | if (SCpnt->request_bufflen > size) |
363 | SCpnt->request_bufflen = SCpnt->bufflen = size; | 363 | SCpnt->request_bufflen = size; |
364 | } | 364 | } |
365 | } | 365 | } |
366 | 366 | ||
@@ -387,8 +387,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
387 | 387 | ||
388 | if (this_count > 0xffff) { | 388 | if (this_count > 0xffff) { |
389 | this_count = 0xffff; | 389 | this_count = 0xffff; |
390 | SCpnt->request_bufflen = SCpnt->bufflen = | 390 | SCpnt->request_bufflen = this_count * s_size; |
391 | this_count * s_size; | ||
392 | } | 391 | } |
393 | 392 | ||
394 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; | 393 | SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 756ceb93ddc8..7f669b600677 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) | |||
368 | SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], | 368 | SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], |
369 | SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); | 369 | SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); |
370 | if (cmdstatp->have_sense) | 370 | if (cmdstatp->have_sense) |
371 | __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); | 371 | __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); |
372 | } ) /* end DEB */ | 372 | } ) /* end DEB */ |
373 | if (!debugging) { /* Abnormal conditions for tape */ | 373 | if (!debugging) { /* Abnormal conditions for tape */ |
374 | if (!cmdstatp->have_sense) | 374 | if (!cmdstatp->have_sense) |
@@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) | |||
384 | scode != VOLUME_OVERFLOW && | 384 | scode != VOLUME_OVERFLOW && |
385 | SRpnt->cmd[0] != MODE_SENSE && | 385 | SRpnt->cmd[0] != MODE_SENSE && |
386 | SRpnt->cmd[0] != TEST_UNIT_READY) { | 386 | SRpnt->cmd[0] != TEST_UNIT_READY) { |
387 | printk(KERN_WARNING "%s: Error with sense data: ", name); | 387 | |
388 | __scsi_print_sense("st", SRpnt->sense, | 388 | __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); |
389 | SCSI_SENSE_BUFFERSIZE); | ||
390 | } | 389 | } |
391 | } | 390 | } |
392 | 391 | ||
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 2ebe0d663899..2f8073b73bf3 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c | |||
@@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) | |||
517 | */ | 517 | */ |
518 | 518 | ||
519 | if (cmd->use_sg) { | 519 | if (cmd->use_sg) { |
520 | cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; | 520 | cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; |
521 | cmd->SCp.buffers_residual = cmd->use_sg - 1; | 521 | cmd->SCp.buffers_residual = cmd->use_sg - 1; |
522 | cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer); | 522 | cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer); |
523 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | 523 | cmd->SCp.this_residual = cmd->SCp.buffer->length; |
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 1f328cae5c05..6b60536ac92b 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c | |||
@@ -347,7 +347,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) | |||
347 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) | 347 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) |
348 | { | 348 | { |
349 | int sz = sp->use_sg - 1; | 349 | int sz = sp->use_sg - 1; |
350 | struct scatterlist *sg = (struct scatterlist *)sp->buffer; | 350 | struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; |
351 | 351 | ||
352 | while(sz >= 0) { | 352 | while(sz >= 0) { |
353 | dvma_unmap((char *)sg[sz].dma_address); | 353 | dvma_unmap((char *)sg[sz].dma_address); |
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 680f38ab60d8..2083454db511 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c | |||
@@ -373,7 +373,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, | |||
373 | */ | 373 | */ |
374 | 374 | ||
375 | if (cmd->use_sg) { | 375 | if (cmd->use_sg) { |
376 | cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; | 376 | cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; |
377 | cmd->SCp.buffers_residual = cmd->use_sg - 1; | 377 | cmd->SCp.buffers_residual = cmd->use_sg - 1; |
378 | cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + | 378 | cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + |
379 | cmd->SCp.buffer->offset; | 379 | cmd->SCp.buffer->offset; |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 979497f108c8..dc673e1b6fd9 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -1047,12 +1047,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1047 | up = &sunsab_ports[inst * 2]; | 1047 | up = &sunsab_ports[inst * 2]; |
1048 | 1048 | ||
1049 | err = sunsab_init_one(&up[0], op, | 1049 | err = sunsab_init_one(&up[0], op, |
1050 | sizeof(union sab82532_async_regs), | 1050 | 0, |
1051 | (inst * 2) + 0); | 1051 | (inst * 2) + 0); |
1052 | if (err) | 1052 | if (err) |
1053 | return err; | 1053 | return err; |
1054 | 1054 | ||
1055 | err = sunsab_init_one(&up[1], op, 0, | 1055 | err = sunsab_init_one(&up[1], op, |
1056 | sizeof(union sab82532_async_regs), | ||
1056 | (inst * 2) + 1); | 1057 | (inst * 2) + 1); |
1057 | if (err) { | 1058 | if (err) { |
1058 | of_iounmap(up[0].port.membase, | 1059 | of_iounmap(up[0].port.membase, |
@@ -1117,7 +1118,7 @@ static int __init sunsab_init(void) | |||
1117 | int err; | 1118 | int err; |
1118 | 1119 | ||
1119 | num_channels = 0; | 1120 | num_channels = 0; |
1120 | for_each_node_by_name(dp, "su") | 1121 | for_each_node_by_name(dp, "se") |
1121 | num_channels += 2; | 1122 | num_channels += 2; |
1122 | for_each_node_by_name(dp, "serial") { | 1123 | for_each_node_by_name(dp, "serial") { |
1123 | if (of_device_is_compatible(dp, "sab82532")) | 1124 | if (of_device_is_compatible(dp, "sab82532")) |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index a1456d9352cb..47bc3d57e019 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -68,9 +68,6 @@ static int num_sunzilog; | |||
68 | #define NUM_SUNZILOG num_sunzilog | 68 | #define NUM_SUNZILOG num_sunzilog |
69 | #define NUM_CHANNELS (NUM_SUNZILOG * 2) | 69 | #define NUM_CHANNELS (NUM_SUNZILOG * 2) |
70 | 70 | ||
71 | #define KEYBOARD_LINE 0x2 | ||
72 | #define MOUSE_LINE 0x3 | ||
73 | |||
74 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ | 71 | #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ |
75 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ | 72 | #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ |
76 | 73 | ||
@@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe | |||
1225 | { | 1222 | { |
1226 | int baud, brg; | 1223 | int baud, brg; |
1227 | 1224 | ||
1228 | if (channel == KEYBOARD_LINE) { | 1225 | if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { |
1229 | up->flags |= SUNZILOG_FLAG_CONS_KEYB; | ||
1230 | up->cflag = B1200 | CS8 | CLOCAL | CREAD; | 1226 | up->cflag = B1200 | CS8 | CLOCAL | CREAD; |
1231 | baud = 1200; | 1227 | baud = 1200; |
1232 | } else { | 1228 | } else { |
1233 | up->flags |= SUNZILOG_FLAG_CONS_MOUSE; | ||
1234 | up->cflag = B4800 | CS8 | CLOCAL | CREAD; | 1229 | up->cflag = B4800 | CS8 | CLOCAL | CREAD; |
1235 | baud = 4800; | 1230 | baud = 4800; |
1236 | } | 1231 | } |
@@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe | |||
1243 | } | 1238 | } |
1244 | 1239 | ||
1245 | #ifdef CONFIG_SERIO | 1240 | #ifdef CONFIG_SERIO |
1246 | static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) | 1241 | static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) |
1247 | { | 1242 | { |
1248 | struct serio *serio = &up->serio; | 1243 | struct serio *serio = &up->serio; |
1249 | 1244 | ||
1250 | serio->port_data = up; | 1245 | serio->port_data = up; |
1251 | 1246 | ||
1252 | serio->id.type = SERIO_RS232; | 1247 | serio->id.type = SERIO_RS232; |
1253 | if (channel == KEYBOARD_LINE) { | 1248 | if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { |
1254 | serio->id.proto = SERIO_SUNKBD; | 1249 | serio->id.proto = SERIO_SUNKBD; |
1255 | strlcpy(serio->name, "zskbd", sizeof(serio->name)); | 1250 | strlcpy(serio->name, "zskbd", sizeof(serio->name)); |
1256 | } else { | 1251 | } else { |
@@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch | |||
1259 | strlcpy(serio->name, "zsms", sizeof(serio->name)); | 1254 | strlcpy(serio->name, "zsms", sizeof(serio->name)); |
1260 | } | 1255 | } |
1261 | strlcpy(serio->phys, | 1256 | strlcpy(serio->phys, |
1262 | (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"), | 1257 | ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ? |
1258 | "zs/serio0" : "zs/serio1"), | ||
1263 | sizeof(serio->phys)); | 1259 | sizeof(serio->phys)); |
1264 | 1260 | ||
1265 | serio->write = sunzilog_serio_write; | 1261 | serio->write = sunzilog_serio_write; |
@@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1286 | (void) read_zsreg(channel, R0); | 1282 | (void) read_zsreg(channel, R0); |
1287 | } | 1283 | } |
1288 | 1284 | ||
1289 | if (up->port.line == KEYBOARD_LINE || | 1285 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | |
1290 | up->port.line == MOUSE_LINE) { | 1286 | SUNZILOG_FLAG_CONS_MOUSE)) { |
1291 | sunzilog_init_kbdms(up, up->port.line); | 1287 | sunzilog_init_kbdms(up, up->port.line); |
1292 | up->curregs[R9] |= (NV | MIE); | 1288 | up->curregs[R9] |= (NV | MIE); |
1293 | write_zsreg(channel, R9, up->curregs[R9]); | 1289 | write_zsreg(channel, R9, up->curregs[R9]); |
@@ -1313,37 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) | |||
1313 | spin_unlock_irqrestore(&up->port.lock, flags); | 1309 | spin_unlock_irqrestore(&up->port.lock, flags); |
1314 | 1310 | ||
1315 | #ifdef CONFIG_SERIO | 1311 | #ifdef CONFIG_SERIO |
1316 | if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE) | 1312 | if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | |
1317 | sunzilog_register_serio(up, up->port.line); | 1313 | SUNZILOG_FLAG_CONS_MOUSE)) |
1314 | sunzilog_register_serio(up); | ||
1318 | #endif | 1315 | #endif |
1319 | } | 1316 | } |
1320 | 1317 | ||
1321 | static int __devinit zs_get_instance(struct device_node *dp) | ||
1322 | { | ||
1323 | int ret; | ||
1324 | |||
1325 | ret = of_getintprop_default(dp, "slave", -1); | ||
1326 | if (ret != -1) | ||
1327 | return ret; | ||
1328 | |||
1329 | if (of_find_property(dp, "keyboard", NULL)) | ||
1330 | ret = 1; | ||
1331 | else | ||
1332 | ret = 0; | ||
1333 | |||
1334 | return ret; | ||
1335 | } | ||
1336 | |||
1337 | static int zilog_irq = -1; | 1318 | static int zilog_irq = -1; |
1338 | 1319 | ||
1339 | static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) | 1320 | static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) |
1340 | { | 1321 | { |
1341 | struct of_device *op = to_of_device(&dev->dev); | 1322 | static int inst; |
1342 | struct uart_sunzilog_port *up; | 1323 | struct uart_sunzilog_port *up; |
1343 | struct zilog_layout __iomem *rp; | 1324 | struct zilog_layout __iomem *rp; |
1344 | int inst = zs_get_instance(dev->node); | 1325 | int keyboard_mouse; |
1345 | int err; | 1326 | int err; |
1346 | 1327 | ||
1328 | keyboard_mouse = 0; | ||
1329 | if (of_find_property(op->node, "keyboard", NULL)) | ||
1330 | keyboard_mouse = 1; | ||
1331 | |||
1347 | sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, | 1332 | sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, |
1348 | sizeof(struct zilog_layout), | 1333 | sizeof(struct zilog_layout), |
1349 | "zs"); | 1334 | "zs"); |
@@ -1352,16 +1337,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1352 | 1337 | ||
1353 | rp = sunzilog_chip_regs[inst]; | 1338 | rp = sunzilog_chip_regs[inst]; |
1354 | 1339 | ||
1355 | if (zilog_irq == -1) { | 1340 | if (zilog_irq == -1) |
1356 | zilog_irq = op->irqs[0]; | 1341 | zilog_irq = op->irqs[0]; |
1357 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | ||
1358 | "zs", sunzilog_irq_chain); | ||
1359 | if (err) { | ||
1360 | of_iounmap(rp, sizeof(struct zilog_layout)); | ||
1361 | |||
1362 | return err; | ||
1363 | } | ||
1364 | } | ||
1365 | 1342 | ||
1366 | up = &sunzilog_port_table[inst * 2]; | 1343 | up = &sunzilog_port_table[inst * 2]; |
1367 | 1344 | ||
@@ -1378,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1378 | up[0].port.line = (inst * 2) + 0; | 1355 | up[0].port.line = (inst * 2) + 0; |
1379 | up[0].port.dev = &op->dev; | 1356 | up[0].port.dev = &op->dev; |
1380 | up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; | 1357 | up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; |
1381 | if (inst == 1) | 1358 | if (keyboard_mouse) |
1382 | up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; | 1359 | up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; |
1383 | sunzilog_init_hw(&up[0]); | 1360 | sunzilog_init_hw(&up[0]); |
1384 | 1361 | ||
@@ -1395,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1395 | up[1].port.line = (inst * 2) + 1; | 1372 | up[1].port.line = (inst * 2) + 1; |
1396 | up[1].port.dev = &op->dev; | 1373 | up[1].port.dev = &op->dev; |
1397 | up[1].flags |= 0; | 1374 | up[1].flags |= 0; |
1398 | if (inst == 1) | 1375 | if (keyboard_mouse) |
1399 | up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; | 1376 | up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; |
1400 | sunzilog_init_hw(&up[1]); | 1377 | sunzilog_init_hw(&up[1]); |
1401 | 1378 | ||
1402 | if (inst != 1) { | 1379 | if (!keyboard_mouse) { |
1403 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | 1380 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); |
1404 | if (err) { | 1381 | if (err) { |
1405 | of_iounmap(rp, sizeof(struct zilog_layout)); | 1382 | of_iounmap(rp, sizeof(struct zilog_layout)); |
@@ -1411,9 +1388,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id * | |||
1411 | of_iounmap(rp, sizeof(struct zilog_layout)); | 1388 | of_iounmap(rp, sizeof(struct zilog_layout)); |
1412 | return err; | 1389 | return err; |
1413 | } | 1390 | } |
1391 | } else { | ||
1392 | printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) " | ||
1393 | "is a zs\n", | ||
1394 | op->dev.bus_id, up[0].port.mapbase, op->irqs[0]); | ||
1395 | printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) " | ||
1396 | "is a zs\n", | ||
1397 | op->dev.bus_id, up[1].port.mapbase, op->irqs[0]); | ||
1414 | } | 1398 | } |
1415 | 1399 | ||
1416 | dev_set_drvdata(&dev->dev, &up[0]); | 1400 | dev_set_drvdata(&op->dev, &up[0]); |
1401 | |||
1402 | inst++; | ||
1417 | 1403 | ||
1418 | return 0; | 1404 | return 0; |
1419 | } | 1405 | } |
@@ -1462,36 +1448,65 @@ static struct of_platform_driver zs_driver = { | |||
1462 | static int __init sunzilog_init(void) | 1448 | static int __init sunzilog_init(void) |
1463 | { | 1449 | { |
1464 | struct device_node *dp; | 1450 | struct device_node *dp; |
1465 | int err; | 1451 | int err, uart_count; |
1452 | int num_keybms; | ||
1466 | 1453 | ||
1467 | NUM_SUNZILOG = 0; | 1454 | NUM_SUNZILOG = 0; |
1468 | for_each_node_by_name(dp, "zs") | 1455 | num_keybms = 0; |
1456 | for_each_node_by_name(dp, "zs") { | ||
1469 | NUM_SUNZILOG++; | 1457 | NUM_SUNZILOG++; |
1458 | if (of_find_property(dp, "keyboard", NULL)) | ||
1459 | num_keybms++; | ||
1460 | } | ||
1470 | 1461 | ||
1462 | uart_count = 0; | ||
1471 | if (NUM_SUNZILOG) { | 1463 | if (NUM_SUNZILOG) { |
1472 | int uart_count; | 1464 | int uart_count; |
1473 | 1465 | ||
1474 | err = sunzilog_alloc_tables(); | 1466 | err = sunzilog_alloc_tables(); |
1475 | if (err) | 1467 | if (err) |
1476 | return err; | 1468 | goto out; |
1477 | 1469 | ||
1478 | /* Subtract 1 for keyboard, 1 for mouse. */ | 1470 | uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); |
1479 | uart_count = (NUM_SUNZILOG * 2) - 2; | ||
1480 | 1471 | ||
1481 | sunzilog_reg.nr = uart_count; | 1472 | sunzilog_reg.nr = uart_count; |
1482 | sunzilog_reg.minor = sunserial_current_minor; | 1473 | sunzilog_reg.minor = sunserial_current_minor; |
1483 | err = uart_register_driver(&sunzilog_reg); | 1474 | err = uart_register_driver(&sunzilog_reg); |
1484 | if (err) { | 1475 | if (err) |
1485 | sunzilog_free_tables(); | 1476 | goto out_free_tables; |
1486 | return err; | 1477 | |
1487 | } | ||
1488 | sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; | 1478 | sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; |
1489 | sunzilog_reg.cons = SUNZILOG_CONSOLE(); | 1479 | sunzilog_reg.cons = SUNZILOG_CONSOLE(); |
1490 | 1480 | ||
1491 | sunserial_current_minor += uart_count; | 1481 | sunserial_current_minor += uart_count; |
1492 | } | 1482 | } |
1493 | 1483 | ||
1494 | return of_register_driver(&zs_driver, &of_bus_type); | 1484 | err = of_register_driver(&zs_driver, &of_bus_type); |
1485 | if (err) | ||
1486 | goto out_unregister_uart; | ||
1487 | |||
1488 | if (zilog_irq != -1) { | ||
1489 | err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, | ||
1490 | "zs", sunzilog_irq_chain); | ||
1491 | if (err) | ||
1492 | goto out_unregister_driver; | ||
1493 | } | ||
1494 | |||
1495 | out: | ||
1496 | return err; | ||
1497 | |||
1498 | out_unregister_driver: | ||
1499 | of_unregister_driver(&zs_driver); | ||
1500 | |||
1501 | out_unregister_uart: | ||
1502 | if (NUM_SUNZILOG) { | ||
1503 | uart_unregister_driver(&sunzilog_reg); | ||
1504 | sunzilog_reg.cons = NULL; | ||
1505 | } | ||
1506 | |||
1507 | out_free_tables: | ||
1508 | sunzilog_free_tables(); | ||
1509 | goto out; | ||
1495 | } | 1510 | } |
1496 | 1511 | ||
1497 | static void __exit sunzilog_exit(void) | 1512 | static void __exit sunzilog_exit(void) |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 2ee742d40c43..005043197527 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI | |||
24 | default y if ARCH_S3C2410 | 24 | default y if ARCH_S3C2410 |
25 | default y if PXA27x | 25 | default y if PXA27x |
26 | default y if ARCH_EP93XX | 26 | default y if ARCH_EP93XX |
27 | default y if ARCH_AT91RM9200 | 27 | default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261) |
28 | # PPC: | 28 | # PPC: |
29 | default y if STB03xxx | 29 | default y if STB03xxx |
30 | default y if PPC_MPC52xx | 30 | default y if PPC_MPC52xx |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index f7bdd94b3aa8..218621b9958e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
517 | 517 | ||
518 | static struct usb_device *usbdev_lookup_minor(int minor) | 518 | static struct usb_device *usbdev_lookup_minor(int minor) |
519 | { | 519 | { |
520 | struct device *device; | 520 | struct class_device *class_dev; |
521 | struct usb_device *udev = NULL; | 521 | struct usb_device *dev = NULL; |
522 | 522 | ||
523 | down(&usb_device_class->sem); | 523 | down(&usb_device_class->sem); |
524 | list_for_each_entry(device, &usb_device_class->devices, node) { | 524 | list_for_each_entry(class_dev, &usb_device_class->children, node) { |
525 | if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | 525 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { |
526 | udev = device->platform_data; | 526 | dev = class_dev->class_data; |
527 | break; | 527 | break; |
528 | } | 528 | } |
529 | } | 529 | } |
530 | up(&usb_device_class->sem); | 530 | up(&usb_device_class->sem); |
531 | 531 | ||
532 | return udev; | 532 | return dev; |
533 | }; | 533 | }; |
534 | 534 | ||
535 | /* | 535 | /* |
@@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev) | |||
1580 | { | 1580 | { |
1581 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1581 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1582 | 1582 | ||
1583 | dev->usbfs_dev = device_create(usb_device_class, &dev->dev, | 1583 | dev->class_dev = class_device_create(usb_device_class, NULL, |
1584 | MKDEV(USB_DEVICE_MAJOR, minor), | 1584 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, |
1585 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | 1585 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); |
1586 | 1586 | ||
1587 | dev->usbfs_dev->platform_data = dev; | 1587 | dev->class_dev->class_data = dev; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | static void usbdev_remove(struct usb_device *dev) | 1590 | static void usbdev_remove(struct usb_device *dev) |
1591 | { | 1591 | { |
1592 | device_unregister(dev->usbfs_dev); | 1592 | class_device_unregister(dev->class_dev); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | 1595 | static int usbdev_notify(struct notifier_block *self, unsigned long action, |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index abee0f5b6a66..8de4f8c99d61 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -194,13 +194,14 @@ int usb_register_dev(struct usb_interface *intf, | |||
194 | ++temp; | 194 | ++temp; |
195 | else | 195 | else |
196 | temp = name; | 196 | temp = name; |
197 | intf->usb_dev = device_create(usb_class->class, &intf->dev, | 197 | intf->class_dev = class_device_create(usb_class->class, NULL, |
198 | MKDEV(USB_MAJOR, minor), "%s", temp); | 198 | MKDEV(USB_MAJOR, minor), |
199 | if (IS_ERR(intf->usb_dev)) { | 199 | &intf->dev, "%s", temp); |
200 | if (IS_ERR(intf->class_dev)) { | ||
200 | spin_lock (&minor_lock); | 201 | spin_lock (&minor_lock); |
201 | usb_minors[intf->minor] = NULL; | 202 | usb_minors[intf->minor] = NULL; |
202 | spin_unlock (&minor_lock); | 203 | spin_unlock (&minor_lock); |
203 | retval = PTR_ERR(intf->usb_dev); | 204 | retval = PTR_ERR(intf->class_dev); |
204 | } | 205 | } |
205 | exit: | 206 | exit: |
206 | return retval; | 207 | return retval; |
@@ -241,8 +242,8 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
241 | spin_unlock (&minor_lock); | 242 | spin_unlock (&minor_lock); |
242 | 243 | ||
243 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 244 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
244 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | 245 | class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); |
245 | intf->usb_dev = NULL; | 246 | intf->class_dev = NULL; |
246 | intf->minor = -1; | 247 | intf->minor = -1; |
247 | destroy_usb_class(); | 248 | destroy_usb_class(); |
248 | } | 249 | } |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 363b2ad74ae6..1a32d96774b4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -207,7 +207,7 @@ config USB_AT91 | |||
207 | 207 | ||
208 | config USB_GADGET_DUMMY_HCD | 208 | config USB_GADGET_DUMMY_HCD |
209 | boolean "Dummy HCD (DEVELOPMENT)" | 209 | boolean "Dummy HCD (DEVELOPMENT)" |
210 | depends on USB && EXPERIMENTAL | 210 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL |
211 | select USB_GADGET_DUALSPEED | 211 | select USB_GADGET_DUALSPEED |
212 | help | 212 | help |
213 | This host controller driver emulates USB, looping all data transfer | 213 | This host controller driver emulates USB, looping all data transfer |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 1c459ff037ce..cfebca05ead5 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -57,19 +57,23 @@ | |||
57 | 57 | ||
58 | /* | 58 | /* |
59 | * This controller is simple and PIO-only. It's used in many AT91-series | 59 | * This controller is simple and PIO-only. It's used in many AT91-series |
60 | * ARMv4T controllers, including the at91rm9200 (arm920T, with MMU), | 60 | * full speed USB controllers, including the at91rm9200 (arm920T, with MMU), |
61 | * at91sam9261 (arm926ejs, with MMU), and several no-mmu versions. | 61 | * at91sam926x (arm926ejs, with MMU), and several no-mmu versions. |
62 | * | 62 | * |
63 | * This driver expects the board has been wired with two GPIOs suppporting | 63 | * This driver expects the board has been wired with two GPIOs suppporting |
64 | * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the | 64 | * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the |
65 | * testing hasn't covered such cases.) The pullup is most important; it | 65 | * testing hasn't covered such cases.) |
66 | * | ||
67 | * The pullup is most important (so it's integrated on sam926x parts). It | ||
66 | * provides software control over whether the host enumerates the device. | 68 | * provides software control over whether the host enumerates the device. |
69 | * | ||
67 | * The VBUS sensing helps during enumeration, and allows both USB clocks | 70 | * The VBUS sensing helps during enumeration, and allows both USB clocks |
68 | * (and the transceiver) to stay gated off until they're necessary, saving | 71 | * (and the transceiver) to stay gated off until they're necessary, saving |
69 | * power. During USB suspend, the 48 MHz clock is gated off. | 72 | * power. During USB suspend, the 48 MHz clock is gated off in hardware; |
73 | * it may also be gated off by software during some Linux sleep states. | ||
70 | */ | 74 | */ |
71 | 75 | ||
72 | #define DRIVER_VERSION "8 March 2005" | 76 | #define DRIVER_VERSION "3 May 2006" |
73 | 77 | ||
74 | static const char driver_name [] = "at91_udc"; | 78 | static const char driver_name [] = "at91_udc"; |
75 | static const char ep0name[] = "ep0"; | 79 | static const char ep0name[] = "ep0"; |
@@ -316,9 +320,15 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status) | |||
316 | * | 320 | * |
317 | * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE | 321 | * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE |
318 | * that shouldn't normally be changed. | 322 | * that shouldn't normally be changed. |
323 | * | ||
324 | * NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains, | ||
325 | * implying a need to wait for one write to complete (test relevant bits) | ||
326 | * before starting the next write. This shouldn't be an issue given how | ||
327 | * infrequently we write, except maybe for write-then-read idioms. | ||
319 | */ | 328 | */ |
320 | #define SET_FX (AT91_UDP_TXPKTRDY) | 329 | #define SET_FX (AT91_UDP_TXPKTRDY) |
321 | #define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP) | 330 | #define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \ |
331 | | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP) | ||
322 | 332 | ||
323 | /* pull OUT packet data from the endpoint's fifo */ | 333 | /* pull OUT packet data from the endpoint's fifo */ |
324 | static int read_fifo (struct at91_ep *ep, struct at91_request *req) | 334 | static int read_fifo (struct at91_ep *ep, struct at91_request *req) |
@@ -472,7 +482,8 @@ static void nuke(struct at91_ep *ep, int status) | |||
472 | 482 | ||
473 | /*-------------------------------------------------------------------------*/ | 483 | /*-------------------------------------------------------------------------*/ |
474 | 484 | ||
475 | static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | 485 | static int at91_ep_enable(struct usb_ep *_ep, |
486 | const struct usb_endpoint_descriptor *desc) | ||
476 | { | 487 | { |
477 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 488 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
478 | struct at91_udc *dev = ep->udc; | 489 | struct at91_udc *dev = ep->udc; |
@@ -582,11 +593,12 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
582 | * interesting for request or buffer allocation. | 593 | * interesting for request or buffer allocation. |
583 | */ | 594 | */ |
584 | 595 | ||
585 | static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags) | 596 | static struct usb_request * |
597 | at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags) | ||
586 | { | 598 | { |
587 | struct at91_request *req; | 599 | struct at91_request *req; |
588 | 600 | ||
589 | req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL); | 601 | req = kcalloc(1, sizeof (struct at91_request), gfp_flags); |
590 | if (!req) | 602 | if (!req) |
591 | return NULL; | 603 | return NULL; |
592 | 604 | ||
@@ -862,6 +874,7 @@ static void stop_activity(struct at91_udc *udc) | |||
862 | if (udc->gadget.speed == USB_SPEED_UNKNOWN) | 874 | if (udc->gadget.speed == USB_SPEED_UNKNOWN) |
863 | driver = NULL; | 875 | driver = NULL; |
864 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 876 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
877 | udc->suspended = 0; | ||
865 | 878 | ||
866 | for (i = 0; i < NUM_ENDPOINTS; i++) { | 879 | for (i = 0; i < NUM_ENDPOINTS; i++) { |
867 | struct at91_ep *ep = &udc->ep[i]; | 880 | struct at91_ep *ep = &udc->ep[i]; |
@@ -889,8 +902,8 @@ static void clk_off(struct at91_udc *udc) | |||
889 | return; | 902 | return; |
890 | udc->clocked = 0; | 903 | udc->clocked = 0; |
891 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 904 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
892 | clk_disable(udc->iclk); | ||
893 | clk_disable(udc->fclk); | 905 | clk_disable(udc->fclk); |
906 | clk_disable(udc->iclk); | ||
894 | } | 907 | } |
895 | 908 | ||
896 | /* | 909 | /* |
@@ -911,9 +924,6 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
911 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 924 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
912 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 925 | at91_set_gpio_value(udc->board.pullup_pin, 0); |
913 | clk_off(udc); | 926 | clk_off(udc); |
914 | |||
915 | // REVISIT: with transceiver disabled, will D- float | ||
916 | // so that a host would falsely detect a device? | ||
917 | } | 927 | } |
918 | } | 928 | } |
919 | 929 | ||
@@ -1290,7 +1300,8 @@ static void handle_ep0(struct at91_udc *udc) | |||
1290 | if (udc->wait_for_addr_ack) { | 1300 | if (udc->wait_for_addr_ack) { |
1291 | u32 tmp; | 1301 | u32 tmp; |
1292 | 1302 | ||
1293 | at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr); | 1303 | at91_udp_write(AT91_UDP_FADDR, |
1304 | AT91_UDP_FEN | udc->addr); | ||
1294 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1305 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); |
1295 | tmp &= ~AT91_UDP_FADDEN; | 1306 | tmp &= ~AT91_UDP_FADDEN; |
1296 | if (udc->addr) | 1307 | if (udc->addr) |
@@ -1361,9 +1372,10 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) | |||
1361 | u32 rescans = 5; | 1372 | u32 rescans = 5; |
1362 | 1373 | ||
1363 | while (rescans--) { | 1374 | while (rescans--) { |
1364 | u32 status = at91_udp_read(AT91_UDP_ISR); | 1375 | u32 status; |
1365 | 1376 | ||
1366 | status &= at91_udp_read(AT91_UDP_IMR); | 1377 | status = at91_udp_read(AT91_UDP_ISR) |
1378 | & at91_udp_read(AT91_UDP_IMR); | ||
1367 | if (!status) | 1379 | if (!status) |
1368 | break; | 1380 | break; |
1369 | 1381 | ||
@@ -1379,18 +1391,17 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) | |||
1379 | stop_activity(udc); | 1391 | stop_activity(udc); |
1380 | 1392 | ||
1381 | /* enable ep0 */ | 1393 | /* enable ep0 */ |
1382 | at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); | 1394 | at91_udp_write(AT91_UDP_CSR(0), |
1395 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); | ||
1383 | udc->gadget.speed = USB_SPEED_FULL; | 1396 | udc->gadget.speed = USB_SPEED_FULL; |
1384 | udc->suspended = 0; | 1397 | udc->suspended = 0; |
1385 | at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); | 1398 | at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); |
1386 | 1399 | ||
1387 | /* | 1400 | /* |
1388 | * NOTE: this driver keeps clocks off unless the | 1401 | * NOTE: this driver keeps clocks off unless the |
1389 | * USB host is present. That saves power, and also | 1402 | * USB host is present. That saves power, but for |
1390 | * eliminates IRQs (reset, resume, suspend) that can | 1403 | * boards that don't support VBUS detection, both |
1391 | * otherwise flood from the controller. If your | 1404 | * clocks need to be active most of the time. |
1392 | * board doesn't support VBUS detection, suspend and | ||
1393 | * resume irq logic may need more attention... | ||
1394 | */ | 1405 | */ |
1395 | 1406 | ||
1396 | /* host initiated suspend (3+ms bus idle) */ | 1407 | /* host initiated suspend (3+ms bus idle) */ |
@@ -1452,13 +1463,19 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) | |||
1452 | 1463 | ||
1453 | /*-------------------------------------------------------------------------*/ | 1464 | /*-------------------------------------------------------------------------*/ |
1454 | 1465 | ||
1466 | static void nop_release(struct device *dev) | ||
1467 | { | ||
1468 | /* nothing to free */ | ||
1469 | } | ||
1470 | |||
1455 | static struct at91_udc controller = { | 1471 | static struct at91_udc controller = { |
1456 | .gadget = { | 1472 | .gadget = { |
1457 | .ops = &at91_udc_ops, | 1473 | .ops = &at91_udc_ops, |
1458 | .ep0 = &controller.ep[0].ep, | 1474 | .ep0 = &controller.ep[0].ep, |
1459 | .name = driver_name, | 1475 | .name = driver_name, |
1460 | .dev = { | 1476 | .dev = { |
1461 | .bus_id = "gadget" | 1477 | .bus_id = "gadget", |
1478 | .release = nop_release, | ||
1462 | } | 1479 | } |
1463 | }, | 1480 | }, |
1464 | .ep[0] = { | 1481 | .ep[0] = { |
@@ -1468,7 +1485,8 @@ static struct at91_udc controller = { | |||
1468 | }, | 1485 | }, |
1469 | .udc = &controller, | 1486 | .udc = &controller, |
1470 | .maxpacket = 8, | 1487 | .maxpacket = 8, |
1471 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)), | 1488 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1489 | + AT91_UDP_CSR(0)), | ||
1472 | .int_mask = 1 << 0, | 1490 | .int_mask = 1 << 0, |
1473 | }, | 1491 | }, |
1474 | .ep[1] = { | 1492 | .ep[1] = { |
@@ -1479,7 +1497,8 @@ static struct at91_udc controller = { | |||
1479 | .udc = &controller, | 1497 | .udc = &controller, |
1480 | .is_pingpong = 1, | 1498 | .is_pingpong = 1, |
1481 | .maxpacket = 64, | 1499 | .maxpacket = 64, |
1482 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)), | 1500 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1501 | + AT91_UDP_CSR(1)), | ||
1483 | .int_mask = 1 << 1, | 1502 | .int_mask = 1 << 1, |
1484 | }, | 1503 | }, |
1485 | .ep[2] = { | 1504 | .ep[2] = { |
@@ -1490,7 +1509,8 @@ static struct at91_udc controller = { | |||
1490 | .udc = &controller, | 1509 | .udc = &controller, |
1491 | .is_pingpong = 1, | 1510 | .is_pingpong = 1, |
1492 | .maxpacket = 64, | 1511 | .maxpacket = 64, |
1493 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)), | 1512 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1513 | + AT91_UDP_CSR(2)), | ||
1494 | .int_mask = 1 << 2, | 1514 | .int_mask = 1 << 2, |
1495 | }, | 1515 | }, |
1496 | .ep[3] = { | 1516 | .ep[3] = { |
@@ -1501,7 +1521,8 @@ static struct at91_udc controller = { | |||
1501 | }, | 1521 | }, |
1502 | .udc = &controller, | 1522 | .udc = &controller, |
1503 | .maxpacket = 8, | 1523 | .maxpacket = 8, |
1504 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)), | 1524 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1525 | + AT91_UDP_CSR(3)), | ||
1505 | .int_mask = 1 << 3, | 1526 | .int_mask = 1 << 3, |
1506 | }, | 1527 | }, |
1507 | .ep[4] = { | 1528 | .ep[4] = { |
@@ -1512,7 +1533,8 @@ static struct at91_udc controller = { | |||
1512 | .udc = &controller, | 1533 | .udc = &controller, |
1513 | .is_pingpong = 1, | 1534 | .is_pingpong = 1, |
1514 | .maxpacket = 256, | 1535 | .maxpacket = 256, |
1515 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)), | 1536 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1537 | + AT91_UDP_CSR(4)), | ||
1516 | .int_mask = 1 << 4, | 1538 | .int_mask = 1 << 4, |
1517 | }, | 1539 | }, |
1518 | .ep[5] = { | 1540 | .ep[5] = { |
@@ -1523,10 +1545,11 @@ static struct at91_udc controller = { | |||
1523 | .udc = &controller, | 1545 | .udc = &controller, |
1524 | .is_pingpong = 1, | 1546 | .is_pingpong = 1, |
1525 | .maxpacket = 256, | 1547 | .maxpacket = 256, |
1526 | .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)), | 1548 | .creg = (void __iomem *)(AT91_VA_BASE_UDP |
1549 | + AT91_UDP_CSR(5)), | ||
1527 | .int_mask = 1 << 5, | 1550 | .int_mask = 1 << 5, |
1528 | }, | 1551 | }, |
1529 | /* ep6 and ep7 are also reserved */ | 1552 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ |
1530 | }; | 1553 | }; |
1531 | 1554 | ||
1532 | static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r) | 1555 | static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r) |
@@ -1593,6 +1616,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
1593 | 1616 | ||
1594 | local_irq_disable(); | 1617 | local_irq_disable(); |
1595 | udc->enabled = 0; | 1618 | udc->enabled = 0; |
1619 | at91_udp_write(AT91_UDP_IDR, ~0); | ||
1596 | pullup(udc, 0); | 1620 | pullup(udc, 0); |
1597 | local_irq_enable(); | 1621 | local_irq_enable(); |
1598 | 1622 | ||
@@ -1624,6 +1648,16 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1624 | return -ENODEV; | 1648 | return -ENODEV; |
1625 | } | 1649 | } |
1626 | 1650 | ||
1651 | if (pdev->num_resources != 2) { | ||
1652 | DBG("invalid num_resources"); | ||
1653 | return -ENODEV; | ||
1654 | } | ||
1655 | if ((pdev->resource[0].flags != IORESOURCE_MEM) | ||
1656 | || (pdev->resource[1].flags != IORESOURCE_IRQ)) { | ||
1657 | DBG("invalid resource type"); | ||
1658 | return -ENODEV; | ||
1659 | } | ||
1660 | |||
1627 | if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) { | 1661 | if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) { |
1628 | DBG("someone's using UDC memory\n"); | 1662 | DBG("someone's using UDC memory\n"); |
1629 | return -EBUSY; | 1663 | return -EBUSY; |
@@ -1649,19 +1683,26 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1649 | if (retval < 0) | 1683 | if (retval < 0) |
1650 | goto fail0; | 1684 | goto fail0; |
1651 | 1685 | ||
1652 | /* disable everything until there's a gadget driver and vbus */ | 1686 | /* don't do anything until we have both gadget driver and VBUS */ |
1653 | pullup(udc, 0); | 1687 | clk_enable(udc->iclk); |
1688 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | ||
1689 | at91_udp_write(AT91_UDP_IDR, 0xffffffff); | ||
1690 | clk_disable(udc->iclk); | ||
1654 | 1691 | ||
1655 | /* request UDC and maybe VBUS irqs */ | 1692 | /* request UDC and maybe VBUS irqs */ |
1656 | if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) { | 1693 | udc->udp_irq = platform_get_irq(pdev, 0); |
1657 | DBG("request irq %d failed\n", AT91_ID_UDP); | 1694 | if (request_irq(udc->udp_irq, at91_udc_irq, |
1695 | IRQF_DISABLED, driver_name, udc)) { | ||
1696 | DBG("request irq %d failed\n", udc->udp_irq); | ||
1658 | retval = -EBUSY; | 1697 | retval = -EBUSY; |
1659 | goto fail1; | 1698 | goto fail1; |
1660 | } | 1699 | } |
1661 | if (udc->board.vbus_pin > 0) { | 1700 | if (udc->board.vbus_pin > 0) { |
1662 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) { | 1701 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1663 | DBG("request vbus irq %d failed\n", udc->board.vbus_pin); | 1702 | IRQF_DISABLED, driver_name, udc)) { |
1664 | free_irq(AT91_ID_UDP, udc); | 1703 | DBG("request vbus irq %d failed\n", |
1704 | udc->board.vbus_pin); | ||
1705 | free_irq(udc->udp_irq, udc); | ||
1665 | retval = -EBUSY; | 1706 | retval = -EBUSY; |
1666 | goto fail1; | 1707 | goto fail1; |
1667 | } | 1708 | } |
@@ -1670,6 +1711,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1670 | udc->vbus = 1; | 1711 | udc->vbus = 1; |
1671 | } | 1712 | } |
1672 | dev_set_drvdata(dev, udc); | 1713 | dev_set_drvdata(dev, udc); |
1714 | device_init_wakeup(dev, 1); | ||
1673 | create_debug_file(udc); | 1715 | create_debug_file(udc); |
1674 | 1716 | ||
1675 | INFO("%s version %s\n", driver_name, DRIVER_VERSION); | 1717 | INFO("%s version %s\n", driver_name, DRIVER_VERSION); |
@@ -1678,14 +1720,14 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1678 | fail1: | 1720 | fail1: |
1679 | device_unregister(&udc->gadget.dev); | 1721 | device_unregister(&udc->gadget.dev); |
1680 | fail0: | 1722 | fail0: |
1681 | release_mem_region(AT91_VA_BASE_UDP, SZ_16K); | 1723 | release_mem_region(AT91_BASE_UDP, SZ_16K); |
1682 | DBG("%s probe failed, %d\n", driver_name, retval); | 1724 | DBG("%s probe failed, %d\n", driver_name, retval); |
1683 | return retval; | 1725 | return retval; |
1684 | } | 1726 | } |
1685 | 1727 | ||
1686 | static int __devexit at91udc_remove(struct platform_device *dev) | 1728 | static int __devexit at91udc_remove(struct platform_device *pdev) |
1687 | { | 1729 | { |
1688 | struct at91_udc *udc = platform_get_drvdata(dev); | 1730 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1689 | 1731 | ||
1690 | DBG("remove\n"); | 1732 | DBG("remove\n"); |
1691 | 1733 | ||
@@ -1694,10 +1736,11 @@ static int __devexit at91udc_remove(struct platform_device *dev) | |||
1694 | if (udc->driver != 0) | 1736 | if (udc->driver != 0) |
1695 | usb_gadget_unregister_driver(udc->driver); | 1737 | usb_gadget_unregister_driver(udc->driver); |
1696 | 1738 | ||
1739 | device_init_wakeup(&pdev->dev, 0); | ||
1697 | remove_debug_file(udc); | 1740 | remove_debug_file(udc); |
1698 | if (udc->board.vbus_pin > 0) | 1741 | if (udc->board.vbus_pin > 0) |
1699 | free_irq(udc->board.vbus_pin, udc); | 1742 | free_irq(udc->board.vbus_pin, udc); |
1700 | free_irq(AT91_ID_UDP, udc); | 1743 | free_irq(udc->udp_irq, udc); |
1701 | device_unregister(&udc->gadget.dev); | 1744 | device_unregister(&udc->gadget.dev); |
1702 | release_mem_region(AT91_BASE_UDP, SZ_16K); | 1745 | release_mem_region(AT91_BASE_UDP, SZ_16K); |
1703 | 1746 | ||
@@ -1708,31 +1751,36 @@ static int __devexit at91udc_remove(struct platform_device *dev) | |||
1708 | } | 1751 | } |
1709 | 1752 | ||
1710 | #ifdef CONFIG_PM | 1753 | #ifdef CONFIG_PM |
1711 | static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg) | 1754 | static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) |
1712 | { | 1755 | { |
1713 | struct at91_udc *udc = platform_get_drvdata(dev); | 1756 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1757 | int wake = udc->driver && device_may_wakeup(&pdev->dev); | ||
1714 | 1758 | ||
1715 | /* | 1759 | /* Unless we can act normally to the host (letting it wake us up |
1716 | * The "safe" suspend transitions are opportunistic ... e.g. when | 1760 | * whenever it has work for us) force disconnect. Wakeup requires |
1717 | * the USB link is suspended (48MHz clock autogated off), or when | 1761 | * PLLB for USB events (signaling for reset, wakeup, or incoming |
1718 | * it's disconnected (programmatically gated off, elsewhere). | 1762 | * tokens) and VBUS irqs (on systems which support them). |
1719 | * Then we can suspend, and the chip can enter slow clock mode. | ||
1720 | * | ||
1721 | * The problem case is some component (user mode?) suspending this | ||
1722 | * device while it's active, with the 48 MHz clock in use. There | ||
1723 | * are two basic approaches: (a) veto suspend levels involving slow | ||
1724 | * clock mode, (b) disconnect, so 48 MHz will no longer be in use | ||
1725 | * and we can enter slow clock mode. This uses (b) for now, since | ||
1726 | * it's simplest until AT91 PM exists and supports the other option. | ||
1727 | */ | 1763 | */ |
1728 | if (udc->vbus && !udc->suspended) | 1764 | if ((!udc->suspended && udc->addr) |
1765 | || !wake | ||
1766 | || at91_suspend_entering_slow_clock()) { | ||
1729 | pullup(udc, 0); | 1767 | pullup(udc, 0); |
1768 | disable_irq_wake(udc->udp_irq); | ||
1769 | } else | ||
1770 | enable_irq_wake(udc->udp_irq); | ||
1771 | |||
1772 | if (udc->board.vbus_pin > 0) { | ||
1773 | if (wake) | ||
1774 | enable_irq_wake(udc->board.vbus_pin); | ||
1775 | else | ||
1776 | disable_irq_wake(udc->board.vbus_pin); | ||
1777 | } | ||
1730 | return 0; | 1778 | return 0; |
1731 | } | 1779 | } |
1732 | 1780 | ||
1733 | static int at91udc_resume(struct platform_device *dev) | 1781 | static int at91udc_resume(struct platform_device *pdev) |
1734 | { | 1782 | { |
1735 | struct at91_udc *udc = platform_get_drvdata(dev); | 1783 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1736 | 1784 | ||
1737 | /* maybe reconnect to host; if so, clocks on */ | 1785 | /* maybe reconnect to host; if so, clocks on */ |
1738 | pullup(udc, 1); | 1786 | pullup(udc, 1); |
@@ -1748,7 +1796,7 @@ static struct platform_driver at91_udc = { | |||
1748 | .remove = __devexit_p(at91udc_remove), | 1796 | .remove = __devexit_p(at91udc_remove), |
1749 | .shutdown = at91udc_shutdown, | 1797 | .shutdown = at91udc_shutdown, |
1750 | .suspend = at91udc_suspend, | 1798 | .suspend = at91udc_suspend, |
1751 | .resume = at91udc_resume, | 1799 | .resume = at91udc_resume, |
1752 | .driver = { | 1800 | .driver = { |
1753 | .name = (char *) driver_name, | 1801 | .name = (char *) driver_name, |
1754 | .owner = THIS_MODULE, | 1802 | .owner = THIS_MODULE, |
@@ -1767,6 +1815,6 @@ static void __devexit udc_exit_module(void) | |||
1767 | } | 1815 | } |
1768 | module_exit(udc_exit_module); | 1816 | module_exit(udc_exit_module); |
1769 | 1817 | ||
1770 | MODULE_DESCRIPTION("AT91RM9200 udc driver"); | 1818 | MODULE_DESCRIPTION("AT91 udc driver"); |
1771 | MODULE_AUTHOR("Thomas Rathbone, David Brownell"); | 1819 | MODULE_AUTHOR("Thomas Rathbone, David Brownell"); |
1772 | MODULE_LICENSE("GPL"); | 1820 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 5a4799cedd19..882af42e86cc 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -141,6 +141,7 @@ struct at91_udc { | |||
141 | struct clk *iclk, *fclk; | 141 | struct clk *iclk, *fclk; |
142 | struct platform_device *pdev; | 142 | struct platform_device *pdev; |
143 | struct proc_dir_entry *pde; | 143 | struct proc_dir_entry *pde; |
144 | int udp_irq; | ||
144 | }; | 145 | }; |
145 | 146 | ||
146 | static inline struct at91_udc *to_udc(struct usb_gadget *g) | 147 | static inline struct at91_udc *to_udc(struct usb_gadget *g) |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 4be47195bd38..7d1c22c34957 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -609,7 +609,8 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) | |||
609 | if (!dum->driver) | 609 | if (!dum->driver) |
610 | return -ESHUTDOWN; | 610 | return -ESHUTDOWN; |
611 | 611 | ||
612 | spin_lock_irqsave (&dum->lock, flags); | 612 | local_irq_save (flags); |
613 | spin_lock (&dum->lock); | ||
613 | list_for_each_entry (req, &ep->queue, queue) { | 614 | list_for_each_entry (req, &ep->queue, queue) { |
614 | if (&req->req == _req) { | 615 | if (&req->req == _req) { |
615 | list_del_init (&req->queue); | 616 | list_del_init (&req->queue); |
@@ -618,7 +619,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) | |||
618 | break; | 619 | break; |
619 | } | 620 | } |
620 | } | 621 | } |
621 | spin_unlock_irqrestore (&dum->lock, flags); | 622 | spin_unlock (&dum->lock); |
622 | 623 | ||
623 | if (retval == 0) { | 624 | if (retval == 0) { |
624 | dev_dbg (udc_dev(dum), | 625 | dev_dbg (udc_dev(dum), |
@@ -626,6 +627,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) | |||
626 | req, _ep->name, _req->length, _req->buf); | 627 | req, _ep->name, _req->length, _req->buf); |
627 | _req->complete (_ep, _req); | 628 | _req->complete (_ep, _req); |
628 | } | 629 | } |
630 | local_irq_restore (flags); | ||
629 | return retval; | 631 | return retval; |
630 | } | 632 | } |
631 | 633 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 85b0b4ad4c16..d63177a8eaea 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL"); | |||
892 | #define PCI_DRIVER ehci_pci_driver | 892 | #define PCI_DRIVER ehci_pci_driver |
893 | #endif | 893 | #endif |
894 | 894 | ||
895 | #ifdef CONFIG_PPC_83xx | 895 | #ifdef CONFIG_MPC834x |
896 | #include "ehci-fsl.c" | 896 | #include "ehci-fsl.c" |
897 | #define PLATFORM_DRIVER ehci_fsl_driver | 897 | #define PLATFORM_DRIVER ehci_fsl_driver |
898 | #endif | 898 | #endif |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index cdbafb710000..85cc059705a6 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2004 SAN People (Pty) Ltd. | 4 | * Copyright (C) 2004 SAN People (Pty) Ltd. |
5 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 5 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> |
6 | * | 6 | * |
7 | * AT91RM9200 Bus Glue | 7 | * AT91 Bus Glue |
8 | * | 8 | * |
9 | * Based on fragments of 2.4 driver by Rick Bronson. | 9 | * Based on fragments of 2.4 driver by Rick Bronson. |
10 | * Based on ohci-omap.c | 10 | * Based on ohci-omap.c |
@@ -19,12 +19,13 @@ | |||
19 | #include <asm/hardware.h> | 19 | #include <asm/hardware.h> |
20 | #include <asm/arch/board.h> | 20 | #include <asm/arch/board.h> |
21 | 21 | ||
22 | #ifndef CONFIG_ARCH_AT91RM9200 | 22 | #ifndef CONFIG_ARCH_AT91 |
23 | #error "CONFIG_ARCH_AT91RM9200 must be defined." | 23 | #error "CONFIG_ARCH_AT91 must be defined." |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | /* interface and function clocks */ | 26 | /* interface and function clocks */ |
27 | static struct clk *iclk, *fclk; | 27 | static struct clk *iclk, *fclk; |
28 | static int clocked; | ||
28 | 29 | ||
29 | extern int usb_disabled(void); | 30 | extern int usb_disabled(void); |
30 | 31 | ||
@@ -35,13 +36,14 @@ static void at91_start_hc(struct platform_device *pdev) | |||
35 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 36 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
36 | struct ohci_regs __iomem *regs = hcd->regs; | 37 | struct ohci_regs __iomem *regs = hcd->regs; |
37 | 38 | ||
38 | dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n"); | 39 | dev_dbg(&pdev->dev, "start\n"); |
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Start the USB clocks. | 42 | * Start the USB clocks. |
42 | */ | 43 | */ |
43 | clk_enable(iclk); | 44 | clk_enable(iclk); |
44 | clk_enable(fclk); | 45 | clk_enable(fclk); |
46 | clocked = 1; | ||
45 | 47 | ||
46 | /* | 48 | /* |
47 | * The USB host controller must remain in reset. | 49 | * The USB host controller must remain in reset. |
@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
54 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 56 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
55 | struct ohci_regs __iomem *regs = hcd->regs; | 57 | struct ohci_regs __iomem *regs = hcd->regs; |
56 | 58 | ||
57 | dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n"); | 59 | dev_dbg(&pdev->dev, "stop\n"); |
58 | 60 | ||
59 | /* | 61 | /* |
60 | * Put the USB host controller into reset. | 62 | * Put the USB host controller into reset. |
@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
66 | */ | 68 | */ |
67 | clk_disable(fclk); | 69 | clk_disable(fclk); |
68 | clk_disable(iclk); | 70 | clk_disable(iclk); |
71 | clocked = 0; | ||
69 | } | 72 | } |
70 | 73 | ||
71 | 74 | ||
@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); | |||
78 | 81 | ||
79 | 82 | ||
80 | /** | 83 | /** |
81 | * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs | 84 | * usb_hcd_at91_probe - initialize AT91-based HCDs |
82 | * Context: !in_interrupt() | 85 | * Context: !in_interrupt() |
83 | * | 86 | * |
84 | * Allocates basic resources for this USB host controller, and | 87 | * Allocates basic resources for this USB host controller, and |
85 | * then invokes the start() method for the HCD associated with it | 88 | * then invokes the start() method for the HCD associated with it |
86 | * through the hotplug entry's driver_data. | 89 | * through the hotplug entry's driver_data. |
87 | */ | 90 | */ |
88 | int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) | 91 | static int usb_hcd_at91_probe(const struct hc_driver *driver, |
92 | struct platform_device *pdev) | ||
89 | { | 93 | { |
90 | int retval; | 94 | int retval; |
91 | struct usb_hcd *hcd = NULL; | 95 | struct usb_hcd *hcd = NULL; |
@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * | |||
95 | return -ENODEV; | 99 | return -ENODEV; |
96 | } | 100 | } |
97 | 101 | ||
98 | if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) { | 102 | if ((pdev->resource[0].flags != IORESOURCE_MEM) |
103 | || (pdev->resource[1].flags != IORESOURCE_IRQ)) { | ||
99 | pr_debug("hcd probe: invalid resource type\n"); | 104 | pr_debug("hcd probe: invalid resource type\n"); |
100 | return -ENODEV; | 105 | return -ENODEV; |
101 | } | 106 | } |
102 | 107 | ||
103 | hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200"); | 108 | hcd = usb_create_hcd(driver, &pdev->dev, "at91"); |
104 | if (!hcd) | 109 | if (!hcd) |
105 | return -ENOMEM; | 110 | return -ENOMEM; |
106 | hcd->rsrc_start = pdev->resource[0].start; | 111 | hcd->rsrc_start = pdev->resource[0].start; |
@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device * | |||
149 | /* may be called with controller, bus, and devices active */ | 154 | /* may be called with controller, bus, and devices active */ |
150 | 155 | ||
151 | /** | 156 | /** |
152 | * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs | 157 | * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs |
153 | * @dev: USB Host Controller being removed | 158 | * @dev: USB Host Controller being removed |
154 | * Context: !in_interrupt() | 159 | * Context: !in_interrupt() |
155 | * | 160 | * |
156 | * Reverses the effect of usb_hcd_at91_probe(), first invoking | 161 | * Reverses the effect of usb_hcd_at91_probe(), first invoking |
157 | * the HCD's stop() method. It is always called from a thread | 162 | * the HCD's stop() method. It is always called from a thread |
158 | * context, normally "rmmod", "apmd", or something similar. | 163 | * context, "rmmod" or something similar. |
159 | * | 164 | * |
160 | */ | 165 | */ |
161 | static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev) | 166 | static int usb_hcd_at91_remove(struct usb_hcd *hcd, |
167 | struct platform_device *pdev) | ||
162 | { | 168 | { |
163 | usb_remove_hcd(hcd); | 169 | usb_remove_hcd(hcd); |
164 | at91_stop_hc(pdev); | 170 | at91_stop_hc(pdev); |
165 | iounmap(hcd->regs); | 171 | iounmap(hcd->regs); |
166 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
173 | disable_irq_wake(hcd->irq); | ||
167 | 174 | ||
168 | clk_put(fclk); | 175 | clk_put(fclk); |
169 | clk_put(iclk); | 176 | clk_put(iclk); |
@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pde | |||
178 | static int __devinit | 185 | static int __devinit |
179 | ohci_at91_start (struct usb_hcd *hcd) | 186 | ohci_at91_start (struct usb_hcd *hcd) |
180 | { | 187 | { |
181 | // struct at91_ohci_data *board = hcd->self.controller->platform_data; | 188 | struct at91_usbh_data *board = hcd->self.controller->platform_data; |
182 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 189 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
190 | struct usb_device *root = hcd->self.root_hub; | ||
183 | int ret; | 191 | int ret; |
184 | 192 | ||
185 | if ((ret = ohci_init(ohci)) < 0) | 193 | if ((ret = ohci_init(ohci)) < 0) |
186 | return ret; | 194 | return ret; |
187 | 195 | ||
196 | root->maxchild = board->ports; | ||
197 | |||
188 | if ((ret = ohci_run(ohci)) < 0) { | 198 | if ((ret = ohci_run(ohci)) < 0) { |
189 | err("can't start %s", hcd->self.bus_name); | 199 | err("can't start %s", hcd->self.bus_name); |
190 | ohci_stop(hcd); | 200 | ohci_stop(hcd); |
191 | return ret; | 201 | return ret; |
192 | } | 202 | } |
193 | // hcd->self.root_hub->maxchild = board->ports; | ||
194 | return 0; | 203 | return 0; |
195 | } | 204 | } |
196 | 205 | ||
@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd) | |||
198 | 207 | ||
199 | static const struct hc_driver ohci_at91_hc_driver = { | 208 | static const struct hc_driver ohci_at91_hc_driver = { |
200 | .description = hcd_name, | 209 | .description = hcd_name, |
201 | .product_desc = "AT91RM9200 OHCI", | 210 | .product_desc = "AT91 OHCI", |
202 | .hcd_priv_size = sizeof(struct ohci_hcd), | 211 | .hcd_priv_size = sizeof(struct ohci_hcd), |
203 | 212 | ||
204 | /* | 213 | /* |
@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
240 | 249 | ||
241 | /*-------------------------------------------------------------------------*/ | 250 | /*-------------------------------------------------------------------------*/ |
242 | 251 | ||
243 | static int ohci_hcd_at91_drv_probe(struct platform_device *dev) | 252 | static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) |
244 | { | 253 | { |
245 | return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev); | 254 | device_init_wakeup(&pdev->dev, 1); |
255 | return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); | ||
246 | } | 256 | } |
247 | 257 | ||
248 | static int ohci_hcd_at91_drv_remove(struct platform_device *dev) | 258 | static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) |
249 | { | 259 | { |
250 | return usb_hcd_at91_remove(platform_get_drvdata(dev), dev); | 260 | device_init_wakeup(&pdev->dev, 0); |
261 | return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev); | ||
251 | } | 262 | } |
252 | 263 | ||
253 | #ifdef CONFIG_PM | 264 | #ifdef CONFIG_PM |
254 | 265 | ||
255 | /* REVISIT suspend/resume look "too" simple here */ | ||
256 | |||
257 | static int | 266 | static int |
258 | ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) | 267 | ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) |
259 | { | 268 | { |
260 | clk_disable(fclk); | 269 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
261 | clk_disable(iclk); | 270 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
271 | |||
272 | if (device_may_wakeup(&pdev->dev)) | ||
273 | enable_irq_wake(hcd->irq); | ||
274 | else | ||
275 | disable_irq_wake(hcd->irq); | ||
276 | |||
277 | /* | ||
278 | * The integrated transceivers seem unable to notice disconnect, | ||
279 | * reconnect, or wakeup without the 48 MHz clock active. so for | ||
280 | * correctness, always discard connection state (using reset). | ||
281 | * | ||
282 | * REVISIT: some boards will be able to turn VBUS off... | ||
283 | */ | ||
284 | if (at91_suspend_entering_slow_clock()) { | ||
285 | ohci_usb_reset (ohci); | ||
286 | clk_disable(fclk); | ||
287 | clk_disable(iclk); | ||
288 | clocked = 0; | ||
289 | } | ||
262 | 290 | ||
263 | return 0; | 291 | return 0; |
264 | } | 292 | } |
265 | 293 | ||
266 | static int ohci_hcd_at91_drv_resume(struct platform_device *dev) | 294 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) |
267 | { | 295 | { |
268 | clk_enable(iclk); | 296 | if (!clocked) { |
269 | clk_enable(fclk); | 297 | clk_enable(iclk); |
298 | clk_enable(fclk); | ||
299 | } | ||
270 | 300 | ||
271 | return 0; | 301 | return 0; |
272 | } | 302 | } |
@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *dev) | |||
275 | #define ohci_hcd_at91_drv_resume NULL | 305 | #define ohci_hcd_at91_drv_resume NULL |
276 | #endif | 306 | #endif |
277 | 307 | ||
278 | MODULE_ALIAS("at91rm9200-ohci"); | 308 | MODULE_ALIAS("at91_ohci"); |
279 | 309 | ||
280 | static struct platform_driver ohci_hcd_at91_driver = { | 310 | static struct platform_driver ohci_hcd_at91_driver = { |
281 | .probe = ohci_hcd_at91_drv_probe, | 311 | .probe = ohci_hcd_at91_drv_probe, |
@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_at91_driver = { | |||
283 | .suspend = ohci_hcd_at91_drv_suspend, | 313 | .suspend = ohci_hcd_at91_drv_suspend, |
284 | .resume = ohci_hcd_at91_drv_resume, | 314 | .resume = ohci_hcd_at91_drv_resume, |
285 | .driver = { | 315 | .driver = { |
286 | .name = "at91rm9200-ohci", | 316 | .name = "at91_ohci", |
287 | .owner = THIS_MODULE, | 317 | .owner = THIS_MODULE, |
288 | }, | 318 | }, |
289 | }; | 319 | }; |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index afef5ac35b4a..94d8cf4b36c1 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL"); | |||
913 | #include "ohci-ppc-soc.c" | 913 | #include "ohci-ppc-soc.c" |
914 | #endif | 914 | #endif |
915 | 915 | ||
916 | #ifdef CONFIG_ARCH_AT91RM9200 | 916 | #if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261) |
917 | #include "ohci-at91.c" | 917 | #include "ohci-at91.c" |
918 | #endif | 918 | #endif |
919 | 919 | ||
@@ -927,6 +927,7 @@ MODULE_LICENSE ("GPL"); | |||
927 | || defined (CONFIG_SOC_AU1X00) \ | 927 | || defined (CONFIG_SOC_AU1X00) \ |
928 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 928 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ |
929 | || defined (CONFIG_ARCH_AT91RM9200) \ | 929 | || defined (CONFIG_ARCH_AT91RM9200) \ |
930 | || defined (CONFIG_ARCH_AT91SAM9261) \ | ||
930 | ) | 931 | ) |
931 | #error "missing bus glue for ohci-hcd" | 932 | #error "missing bus glue for ohci-hcd" |
932 | #endif | 933 | #endif |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index c9d72ac0a1d7..66c3f61bc9d1 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -943,7 +943,9 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
943 | /* We received a short packet */ | 943 | /* We received a short packet */ |
944 | if (urb->transfer_flags & URB_SHORT_NOT_OK) | 944 | if (urb->transfer_flags & URB_SHORT_NOT_OK) |
945 | ret = -EREMOTEIO; | 945 | ret = -EREMOTEIO; |
946 | else if (ctrlstat & TD_CTRL_SPD) | 946 | |
947 | /* Fixup needed only if this isn't the URB's last TD */ | ||
948 | else if (&td->list != urbp->td_list.prev) | ||
947 | ret = 1; | 949 | ret = 1; |
948 | } | 950 | } |
949 | 951 | ||
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 05d2d6012eb2..3719fcb04b8f 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -111,14 +111,28 @@ | |||
111 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ | 111 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ |
112 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ | 112 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ |
113 | 113 | ||
114 | /* | ||
115 | * Duplicate event filtering time. | ||
116 | * Sequential, identical KIND_FILTERED inputs with less than | ||
117 | * FILTER_TIME milliseconds between them are considered as repeat | ||
118 | * events. The hardware generates 5 events for the first keypress | ||
119 | * and we have to take this into account for an accurate repeat | ||
120 | * behaviour. | ||
121 | */ | ||
122 | #define FILTER_TIME 60 /* msec */ | ||
123 | |||
114 | static unsigned long channel_mask; | 124 | static unsigned long channel_mask; |
115 | module_param(channel_mask, ulong, 0444); | 125 | module_param(channel_mask, ulong, 0644); |
116 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); | 126 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); |
117 | 127 | ||
118 | static int debug; | 128 | static int debug; |
119 | module_param(debug, int, 0444); | 129 | module_param(debug, int, 0644); |
120 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | 130 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); |
121 | 131 | ||
132 | static int repeat_filter = FILTER_TIME; | ||
133 | module_param(repeat_filter, int, 0644); | ||
134 | MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); | ||
135 | |||
122 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) | 136 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) |
123 | #undef err | 137 | #undef err |
124 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | 138 | #define err(format, arg...) printk(KERN_ERR format , ## arg) |
@@ -143,19 +157,6 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table); | |||
143 | static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | 157 | static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; |
144 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | 158 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; |
145 | 159 | ||
146 | /* Acceleration curve for directional control pad */ | ||
147 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | ||
148 | |||
149 | /* Duplicate event filtering time. | ||
150 | * Sequential, identical KIND_FILTERED inputs with less than | ||
151 | * FILTER_TIME jiffies between them are considered as repeat | ||
152 | * events. The hardware generates 5 events for the first keypress | ||
153 | * and we have to take this into account for an accurate repeat | ||
154 | * behaviour. | ||
155 | * (HZ / 20) == 50 ms and works well for me. | ||
156 | */ | ||
157 | #define FILTER_TIME (HZ / 20) | ||
158 | |||
159 | struct ati_remote { | 160 | struct ati_remote { |
160 | struct input_dev *idev; | 161 | struct input_dev *idev; |
161 | struct usb_device *udev; | 162 | struct usb_device *udev; |
@@ -413,6 +414,43 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | |||
413 | } | 414 | } |
414 | 415 | ||
415 | /* | 416 | /* |
417 | * ati_remote_compute_accel | ||
418 | * | ||
419 | * Implements acceleration curve for directional control pad | ||
420 | * If elapsed time since last event is > 1/4 second, user "stopped", | ||
421 | * so reset acceleration. Otherwise, user is probably holding the control | ||
422 | * pad down, so we increase acceleration, ramping up over two seconds to | ||
423 | * a maximum speed. | ||
424 | */ | ||
425 | static int ati_remote_compute_accel(struct ati_remote *ati_remote) | ||
426 | { | ||
427 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | ||
428 | unsigned long now = jiffies; | ||
429 | int acc; | ||
430 | |||
431 | if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) { | ||
432 | acc = 1; | ||
433 | ati_remote->acc_jiffies = now; | ||
434 | } | ||
435 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125))) | ||
436 | acc = accel[0]; | ||
437 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250))) | ||
438 | acc = accel[1]; | ||
439 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500))) | ||
440 | acc = accel[2]; | ||
441 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000))) | ||
442 | acc = accel[3]; | ||
443 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500))) | ||
444 | acc = accel[4]; | ||
445 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000))) | ||
446 | acc = accel[5]; | ||
447 | else | ||
448 | acc = accel[6]; | ||
449 | |||
450 | return acc; | ||
451 | } | ||
452 | |||
453 | /* | ||
416 | * ati_remote_report_input | 454 | * ati_remote_report_input |
417 | */ | 455 | */ |
418 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | 456 | static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) |
@@ -465,9 +503,9 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
465 | 503 | ||
466 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { | 504 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { |
467 | /* Filter duplicate events which happen "too close" together. */ | 505 | /* Filter duplicate events which happen "too close" together. */ |
468 | if ((ati_remote->old_data[0] == data[1]) && | 506 | if (ati_remote->old_data[0] == data[1] && |
469 | (ati_remote->old_data[1] == data[2]) && | 507 | ati_remote->old_data[1] == data[2] && |
470 | time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { | 508 | time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { |
471 | ati_remote->repeat_count++; | 509 | ati_remote->repeat_count++; |
472 | } else { | 510 | } else { |
473 | ati_remote->repeat_count = 0; | 511 | ati_remote->repeat_count = 0; |
@@ -477,75 +515,61 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
477 | ati_remote->old_data[1] = data[2]; | 515 | ati_remote->old_data[1] = data[2]; |
478 | ati_remote->old_jiffies = jiffies; | 516 | ati_remote->old_jiffies = jiffies; |
479 | 517 | ||
480 | if ((ati_remote->repeat_count > 0) | 518 | if (ati_remote->repeat_count > 0 && |
481 | && (ati_remote->repeat_count < 5)) | 519 | ati_remote->repeat_count < 5) |
482 | return; | 520 | return; |
483 | 521 | ||
484 | 522 | ||
485 | input_regs(dev, regs); | 523 | input_regs(dev, regs); |
486 | input_event(dev, ati_remote_tbl[index].type, | 524 | input_event(dev, ati_remote_tbl[index].type, |
487 | ati_remote_tbl[index].code, 1); | 525 | ati_remote_tbl[index].code, 1); |
526 | input_sync(dev); | ||
488 | input_event(dev, ati_remote_tbl[index].type, | 527 | input_event(dev, ati_remote_tbl[index].type, |
489 | ati_remote_tbl[index].code, 0); | 528 | ati_remote_tbl[index].code, 0); |
490 | input_sync(dev); | 529 | input_sync(dev); |
491 | 530 | ||
492 | return; | 531 | } else { |
493 | } | ||
494 | 532 | ||
495 | /* | 533 | /* |
496 | * Other event kinds are from the directional control pad, and have an | 534 | * Other event kinds are from the directional control pad, and have an |
497 | * acceleration factor applied to them. Without this acceleration, the | 535 | * acceleration factor applied to them. Without this acceleration, the |
498 | * control pad is mostly unusable. | 536 | * control pad is mostly unusable. |
499 | * | 537 | */ |
500 | * If elapsed time since last event is > 1/4 second, user "stopped", | 538 | acc = ati_remote_compute_accel(ati_remote); |
501 | * so reset acceleration. Otherwise, user is probably holding the control | 539 | |
502 | * pad down, so we increase acceleration, ramping up over two seconds to | 540 | input_regs(dev, regs); |
503 | * a maximum speed. The acceleration curve is #defined above. | 541 | switch (ati_remote_tbl[index].kind) { |
504 | */ | 542 | case KIND_ACCEL: |
505 | if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { | 543 | input_event(dev, ati_remote_tbl[index].type, |
506 | acc = 1; | 544 | ati_remote_tbl[index].code, |
507 | ati_remote->acc_jiffies = jiffies; | 545 | ati_remote_tbl[index].value * acc); |
508 | } | 546 | break; |
509 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; | 547 | case KIND_LU: |
510 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; | 548 | input_report_rel(dev, REL_X, -acc); |
511 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; | 549 | input_report_rel(dev, REL_Y, -acc); |
512 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; | 550 | break; |
513 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; | 551 | case KIND_RU: |
514 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; | 552 | input_report_rel(dev, REL_X, acc); |
515 | else acc = accel[6]; | 553 | input_report_rel(dev, REL_Y, -acc); |
516 | 554 | break; | |
517 | input_regs(dev, regs); | 555 | case KIND_LD: |
518 | switch (ati_remote_tbl[index].kind) { | 556 | input_report_rel(dev, REL_X, -acc); |
519 | case KIND_ACCEL: | 557 | input_report_rel(dev, REL_Y, acc); |
520 | input_event(dev, ati_remote_tbl[index].type, | 558 | break; |
521 | ati_remote_tbl[index].code, | 559 | case KIND_RD: |
522 | ati_remote_tbl[index].value * acc); | 560 | input_report_rel(dev, REL_X, acc); |
523 | break; | 561 | input_report_rel(dev, REL_Y, acc); |
524 | case KIND_LU: | 562 | break; |
525 | input_report_rel(dev, REL_X, -acc); | 563 | default: |
526 | input_report_rel(dev, REL_Y, -acc); | 564 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", |
527 | break; | 565 | ati_remote_tbl[index].kind); |
528 | case KIND_RU: | 566 | } |
529 | input_report_rel(dev, REL_X, acc); | 567 | input_sync(dev); |
530 | input_report_rel(dev, REL_Y, -acc); | ||
531 | break; | ||
532 | case KIND_LD: | ||
533 | input_report_rel(dev, REL_X, -acc); | ||
534 | input_report_rel(dev, REL_Y, acc); | ||
535 | break; | ||
536 | case KIND_RD: | ||
537 | input_report_rel(dev, REL_X, acc); | ||
538 | input_report_rel(dev, REL_Y, acc); | ||
539 | break; | ||
540 | default: | ||
541 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", | ||
542 | ati_remote_tbl[index].kind); | ||
543 | } | ||
544 | input_sync(dev); | ||
545 | 568 | ||
546 | ati_remote->old_jiffies = jiffies; | 569 | ati_remote->old_jiffies = jiffies; |
547 | ati_remote->old_data[0] = data[1]; | 570 | ati_remote->old_data[0] = data[1]; |
548 | ati_remote->old_data[1] = data[2]; | 571 | ati_remote->old_data[1] = data[2]; |
572 | } | ||
549 | } | 573 | } |
550 | 574 | ||
551 | /* | 575 | /* |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 028e1ad89f5d..7208839f2dbf 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -607,7 +607,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
607 | 607 | ||
608 | } | 608 | } |
609 | 609 | ||
610 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 610 | if (usage->type == EV_ABS && |
611 | (usage->hat_min < usage->hat_max || usage->hat_dir)) { | ||
611 | int i; | 612 | int i; |
612 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { | 613 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { |
613 | input_set_abs_params(input, i, -1, 1, 0, 0); | 614 | input_set_abs_params(input, i, -1, 1, 0, 0); |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 70477f02cc29..f6b839c257a7 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -49,7 +49,7 @@ struct hiddev { | |||
49 | int open; | 49 | int open; |
50 | wait_queue_head_t wait; | 50 | wait_queue_head_t wait; |
51 | struct hid_device *hid; | 51 | struct hid_device *hid; |
52 | struct hiddev_list *list; | 52 | struct list_head list; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct hiddev_list { | 55 | struct hiddev_list { |
@@ -59,7 +59,7 @@ struct hiddev_list { | |||
59 | unsigned flags; | 59 | unsigned flags; |
60 | struct fasync_struct *fasync; | 60 | struct fasync_struct *fasync; |
61 | struct hiddev *hiddev; | 61 | struct hiddev *hiddev; |
62 | struct hiddev_list *next; | 62 | struct list_head node; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct hiddev *hiddev_table[HIDDEV_MINORS]; | 65 | static struct hiddev *hiddev_table[HIDDEV_MINORS]; |
@@ -73,12 +73,15 @@ static struct hiddev *hiddev_table[HIDDEV_MINORS]; | |||
73 | static struct hid_report * | 73 | static struct hid_report * |
74 | hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | 74 | hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) |
75 | { | 75 | { |
76 | unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK; | 76 | unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK; |
77 | unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK; | ||
77 | struct hid_report_enum *report_enum; | 78 | struct hid_report_enum *report_enum; |
79 | struct hid_report *report; | ||
78 | struct list_head *list; | 80 | struct list_head *list; |
79 | 81 | ||
80 | if (rinfo->report_type < HID_REPORT_TYPE_MIN || | 82 | if (rinfo->report_type < HID_REPORT_TYPE_MIN || |
81 | rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL; | 83 | rinfo->report_type > HID_REPORT_TYPE_MAX) |
84 | return NULL; | ||
82 | 85 | ||
83 | report_enum = hid->report_enum + | 86 | report_enum = hid->report_enum + |
84 | (rinfo->report_type - HID_REPORT_TYPE_MIN); | 87 | (rinfo->report_type - HID_REPORT_TYPE_MIN); |
@@ -88,21 +91,25 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) | |||
88 | break; | 91 | break; |
89 | 92 | ||
90 | case HID_REPORT_ID_FIRST: | 93 | case HID_REPORT_ID_FIRST: |
91 | list = report_enum->report_list.next; | 94 | if (list_empty(&report_enum->report_list)) |
92 | if (list == &report_enum->report_list) | ||
93 | return NULL; | 95 | return NULL; |
94 | rinfo->report_id = ((struct hid_report *) list)->id; | 96 | |
97 | list = report_enum->report_list.next; | ||
98 | report = list_entry(list, struct hid_report, list); | ||
99 | rinfo->report_id = report->id; | ||
95 | break; | 100 | break; |
96 | 101 | ||
97 | case HID_REPORT_ID_NEXT: | 102 | case HID_REPORT_ID_NEXT: |
98 | list = (struct list_head *) | 103 | report = report_enum->report_id_hash[rid]; |
99 | report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; | 104 | if (!report) |
100 | if (list == NULL) | ||
101 | return NULL; | 105 | return NULL; |
102 | list = list->next; | 106 | |
107 | list = report->list.next; | ||
103 | if (list == &report_enum->report_list) | 108 | if (list == &report_enum->report_list) |
104 | return NULL; | 109 | return NULL; |
105 | rinfo->report_id = ((struct hid_report *) list)->id; | 110 | |
111 | report = list_entry(list, struct hid_report, list); | ||
112 | rinfo->report_id = report->id; | ||
106 | break; | 113 | break; |
107 | 114 | ||
108 | default: | 115 | default: |
@@ -125,12 +132,13 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) | |||
125 | struct hid_field *field; | 132 | struct hid_field *field; |
126 | 133 | ||
127 | if (uref->report_type < HID_REPORT_TYPE_MIN || | 134 | if (uref->report_type < HID_REPORT_TYPE_MIN || |
128 | uref->report_type > HID_REPORT_TYPE_MAX) return NULL; | 135 | uref->report_type > HID_REPORT_TYPE_MAX) |
136 | return NULL; | ||
129 | 137 | ||
130 | report_enum = hid->report_enum + | 138 | report_enum = hid->report_enum + |
131 | (uref->report_type - HID_REPORT_TYPE_MIN); | 139 | (uref->report_type - HID_REPORT_TYPE_MIN); |
132 | 140 | ||
133 | list_for_each_entry(report, &report_enum->report_list, list) | 141 | list_for_each_entry(report, &report_enum->report_list, list) { |
134 | for (i = 0; i < report->maxfield; i++) { | 142 | for (i = 0; i < report->maxfield; i++) { |
135 | field = report->field[i]; | 143 | field = report->field[i]; |
136 | for (j = 0; j < field->maxusage; j++) { | 144 | for (j = 0; j < field->maxusage; j++) { |
@@ -142,6 +150,7 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) | |||
142 | } | 150 | } |
143 | } | 151 | } |
144 | } | 152 | } |
153 | } | ||
145 | 154 | ||
146 | return NULL; | 155 | return NULL; |
147 | } | 156 | } |
@@ -150,9 +159,9 @@ static void hiddev_send_event(struct hid_device *hid, | |||
150 | struct hiddev_usage_ref *uref) | 159 | struct hiddev_usage_ref *uref) |
151 | { | 160 | { |
152 | struct hiddev *hiddev = hid->hiddev; | 161 | struct hiddev *hiddev = hid->hiddev; |
153 | struct hiddev_list *list = hiddev->list; | 162 | struct hiddev_list *list; |
154 | 163 | ||
155 | while (list) { | 164 | list_for_each_entry(list, &hiddev->list, node) { |
156 | if (uref->field_index != HID_FIELD_INDEX_NONE || | 165 | if (uref->field_index != HID_FIELD_INDEX_NONE || |
157 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { | 166 | (list->flags & HIDDEV_FLAG_REPORT) != 0) { |
158 | list->buffer[list->head] = *uref; | 167 | list->buffer[list->head] = *uref; |
@@ -160,8 +169,6 @@ static void hiddev_send_event(struct hid_device *hid, | |||
160 | (HIDDEV_BUFFER_SIZE - 1); | 169 | (HIDDEV_BUFFER_SIZE - 1); |
161 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 170 | kill_fasync(&list->fasync, SIGIO, POLL_IN); |
162 | } | 171 | } |
163 | |||
164 | list = list->next; | ||
165 | } | 172 | } |
166 | 173 | ||
167 | wake_up_interruptible(&hiddev->wait); | 174 | wake_up_interruptible(&hiddev->wait); |
@@ -180,7 +187,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | |||
180 | uref.report_type = | 187 | uref.report_type = |
181 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 188 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
182 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 189 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
183 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 190 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); |
184 | uref.report_id = field->report->id; | 191 | uref.report_id = field->report->id; |
185 | uref.field_index = field->index; | 192 | uref.field_index = field->index; |
186 | uref.usage_index = (usage - field->usage); | 193 | uref.usage_index = (usage - field->usage); |
@@ -200,7 +207,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | |||
200 | uref.report_type = | 207 | uref.report_type = |
201 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : | 208 | (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : |
202 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : | 209 | ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : |
203 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); | 210 | ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); |
204 | uref.report_id = report->id; | 211 | uref.report_id = report->id; |
205 | uref.field_index = HID_FIELD_INDEX_NONE; | 212 | uref.field_index = HID_FIELD_INDEX_NONE; |
206 | 213 | ||
@@ -213,7 +220,9 @@ static int hiddev_fasync(int fd, struct file *file, int on) | |||
213 | { | 220 | { |
214 | int retval; | 221 | int retval; |
215 | struct hiddev_list *list = file->private_data; | 222 | struct hiddev_list *list = file->private_data; |
223 | |||
216 | retval = fasync_helper(fd, file, on, &list->fasync); | 224 | retval = fasync_helper(fd, file, on, &list->fasync); |
225 | |||
217 | return retval < 0 ? retval : 0; | 226 | return retval < 0 ? retval : 0; |
218 | } | 227 | } |
219 | 228 | ||
@@ -224,14 +233,9 @@ static int hiddev_fasync(int fd, struct file *file, int on) | |||
224 | static int hiddev_release(struct inode * inode, struct file * file) | 233 | static int hiddev_release(struct inode * inode, struct file * file) |
225 | { | 234 | { |
226 | struct hiddev_list *list = file->private_data; | 235 | struct hiddev_list *list = file->private_data; |
227 | struct hiddev_list **listptr; | ||
228 | 236 | ||
229 | listptr = &list->hiddev->list; | ||
230 | hiddev_fasync(-1, file, 0); | 237 | hiddev_fasync(-1, file, 0); |
231 | 238 | list_del(&list->node); | |
232 | while (*listptr && (*listptr != list)) | ||
233 | listptr = &((*listptr)->next); | ||
234 | *listptr = (*listptr)->next; | ||
235 | 239 | ||
236 | if (!--list->hiddev->open) { | 240 | if (!--list->hiddev->open) { |
237 | if (list->hiddev->exist) | 241 | if (list->hiddev->exist) |
@@ -248,7 +252,8 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
248 | /* | 252 | /* |
249 | * open file op | 253 | * open file op |
250 | */ | 254 | */ |
251 | static int hiddev_open(struct inode * inode, struct file * file) { | 255 | static int hiddev_open(struct inode *inode, struct file *file) |
256 | { | ||
252 | struct hiddev_list *list; | 257 | struct hiddev_list *list; |
253 | 258 | ||
254 | int i = iminor(inode) - HIDDEV_MINOR_BASE; | 259 | int i = iminor(inode) - HIDDEV_MINOR_BASE; |
@@ -260,9 +265,7 @@ static int hiddev_open(struct inode * inode, struct file * file) { | |||
260 | return -ENOMEM; | 265 | return -ENOMEM; |
261 | 266 | ||
262 | list->hiddev = hiddev_table[i]; | 267 | list->hiddev = hiddev_table[i]; |
263 | list->next = hiddev_table[i]->list; | 268 | list_add_tail(&list->node, &hiddev_table[i]->list); |
264 | hiddev_table[i]->list = list; | ||
265 | |||
266 | file->private_data = list; | 269 | file->private_data = list; |
267 | 270 | ||
268 | if (!list->hiddev->open++) | 271 | if (!list->hiddev->open++) |
@@ -362,6 +365,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun | |||
362 | static unsigned int hiddev_poll(struct file *file, poll_table *wait) | 365 | static unsigned int hiddev_poll(struct file *file, poll_table *wait) |
363 | { | 366 | { |
364 | struct hiddev_list *list = file->private_data; | 367 | struct hiddev_list *list = file->private_data; |
368 | |||
365 | poll_wait(file, &list->hiddev->wait, wait); | 369 | poll_wait(file, &list->hiddev->wait, wait); |
366 | if (list->head != list->tail) | 370 | if (list->head != list->tail) |
367 | return POLLIN | POLLRDNORM; | 371 | return POLLIN | POLLRDNORM; |
@@ -382,7 +386,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
382 | struct hiddev_collection_info cinfo; | 386 | struct hiddev_collection_info cinfo; |
383 | struct hiddev_report_info rinfo; | 387 | struct hiddev_report_info rinfo; |
384 | struct hiddev_field_info finfo; | 388 | struct hiddev_field_info finfo; |
385 | struct hiddev_usage_ref_multi *uref_multi=NULL; | 389 | struct hiddev_usage_ref_multi *uref_multi = NULL; |
386 | struct hiddev_usage_ref *uref; | 390 | struct hiddev_usage_ref *uref; |
387 | struct hiddev_devinfo dinfo; | 391 | struct hiddev_devinfo dinfo; |
388 | struct hid_report *report; | 392 | struct hid_report *report; |
@@ -764,15 +768,15 @@ int hiddev_connect(struct hid_device *hid) | |||
764 | } | 768 | } |
765 | 769 | ||
766 | init_waitqueue_head(&hiddev->wait); | 770 | init_waitqueue_head(&hiddev->wait); |
767 | 771 | INIT_LIST_HEAD(&hiddev->list); | |
768 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | ||
769 | |||
770 | hiddev->hid = hid; | 772 | hiddev->hid = hid; |
771 | hiddev->exist = 1; | 773 | hiddev->exist = 1; |
772 | 774 | ||
773 | hid->minor = hid->intf->minor; | 775 | hid->minor = hid->intf->minor; |
774 | hid->hiddev = hiddev; | 776 | hid->hiddev = hiddev; |
775 | 777 | ||
778 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | ||
779 | |||
776 | return 0; | 780 | return 0; |
777 | } | 781 | } |
778 | 782 | ||
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index e091d327bd9e..a4062a6adbb8 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c | |||
@@ -12,8 +12,13 @@ | |||
12 | * the single I/O ports of the device. | 12 | * the single I/O ports of the device. |
13 | * | 13 | * |
14 | * Supported vendors: AK Modul-Bus Computer GmbH | 14 | * Supported vendors: AK Modul-Bus Computer GmbH |
15 | * Supported devices: CY7C63001A-PC (to be continued...) | 15 | * (Firmware "Port-Chip") |
16 | * Supported functions: Read/Write Ports (to be continued...) | 16 | * |
17 | * Supported devices: CY7C63001A-PC | ||
18 | * CY7C63001C-PXC | ||
19 | * CY7C63001C-SXC | ||
20 | * | ||
21 | * Supported functions: Read/Write Ports | ||
17 | * | 22 | * |
18 | * | 23 | * |
19 | * This program is free software; you can redistribute it and/or | 24 | * This program is free software; you can redistribute it and/or |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index e5e6e4f3ef87..bd09232ce13c 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *); | |||
175 | static void rtl8150_disconnect(struct usb_interface *intf); | 175 | static void rtl8150_disconnect(struct usb_interface *intf); |
176 | static int rtl8150_probe(struct usb_interface *intf, | 176 | static int rtl8150_probe(struct usb_interface *intf, |
177 | const struct usb_device_id *id); | 177 | const struct usb_device_id *id); |
178 | static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message); | ||
179 | static int rtl8150_resume(struct usb_interface *intf); | ||
178 | 180 | ||
179 | static const char driver_name [] = "rtl8150"; | 181 | static const char driver_name [] = "rtl8150"; |
180 | 182 | ||
@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver = { | |||
183 | .probe = rtl8150_probe, | 185 | .probe = rtl8150_probe, |
184 | .disconnect = rtl8150_disconnect, | 186 | .disconnect = rtl8150_disconnect, |
185 | .id_table = rtl8150_table, | 187 | .id_table = rtl8150_table, |
188 | .suspend = rtl8150_suspend, | ||
189 | .resume = rtl8150_resume | ||
186 | }; | 190 | }; |
187 | 191 | ||
188 | /* | 192 | /* |
@@ -238,9 +242,11 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) | |||
238 | usb_fill_control_urb(dev->ctrl_urb, dev->udev, | 242 | usb_fill_control_urb(dev->ctrl_urb, dev->udev, |
239 | usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, | 243 | usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, |
240 | &dev->rx_creg, size, ctrl_callback, dev); | 244 | &dev->rx_creg, size, ctrl_callback, dev); |
241 | if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) | 245 | if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) { |
246 | if (ret == -ENODEV) | ||
247 | netif_device_detach(dev->netdev); | ||
242 | err("control request submission failed: %d", ret); | 248 | err("control request submission failed: %d", ret); |
243 | else | 249 | } else |
244 | set_bit(RX_REG_SET, &dev->flags); | 250 | set_bit(RX_REG_SET, &dev->flags); |
245 | 251 | ||
246 | return ret; | 252 | return ret; |
@@ -416,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
416 | struct sk_buff *skb; | 422 | struct sk_buff *skb; |
417 | struct net_device *netdev; | 423 | struct net_device *netdev; |
418 | u16 rx_stat; | 424 | u16 rx_stat; |
425 | int status; | ||
419 | 426 | ||
420 | dev = urb->context; | 427 | dev = urb->context; |
421 | if (!dev) | 428 | if (!dev) |
@@ -465,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
465 | goon: | 472 | goon: |
466 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), | 473 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), |
467 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); | 474 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); |
468 | if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { | 475 | status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); |
476 | if (status == -ENODEV) | ||
477 | netif_device_detach(dev->netdev); | ||
478 | else if (status) { | ||
469 | set_bit(RX_URB_FAIL, &dev->flags); | 479 | set_bit(RX_URB_FAIL, &dev->flags); |
470 | goto resched; | 480 | goto resched; |
471 | } else { | 481 | } else { |
@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data) | |||
481 | { | 491 | { |
482 | rtl8150_t *dev; | 492 | rtl8150_t *dev; |
483 | struct sk_buff *skb; | 493 | struct sk_buff *skb; |
494 | int status; | ||
484 | 495 | ||
485 | dev = (rtl8150_t *)data; | 496 | dev = (rtl8150_t *)data; |
486 | 497 | ||
@@ -499,10 +510,13 @@ static void rx_fixup(unsigned long data) | |||
499 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), | 510 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), |
500 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); | 511 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); |
501 | try_again: | 512 | try_again: |
502 | if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { | 513 | status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); |
514 | if (status == -ENODEV) { | ||
515 | netif_device_detach(dev->netdev); | ||
516 | } else if (status) { | ||
503 | set_bit(RX_URB_FAIL, &dev->flags); | 517 | set_bit(RX_URB_FAIL, &dev->flags); |
504 | goto tlsched; | 518 | goto tlsched; |
505 | } else { | 519 | } else { |
506 | clear_bit(RX_URB_FAIL, &dev->flags); | 520 | clear_bit(RX_URB_FAIL, &dev->flags); |
507 | } | 521 | } |
508 | 522 | ||
@@ -574,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs) | |||
574 | 588 | ||
575 | resubmit: | 589 | resubmit: |
576 | status = usb_submit_urb (urb, SLAB_ATOMIC); | 590 | status = usb_submit_urb (urb, SLAB_ATOMIC); |
577 | if (status) | 591 | if (status == -ENODEV) |
592 | netif_device_detach(dev->netdev); | ||
593 | else if (status) | ||
578 | err ("can't resubmit intr, %s-%s/input0, status %d", | 594 | err ("can't resubmit intr, %s-%s/input0, status %d", |
579 | dev->udev->bus->bus_name, | 595 | dev->udev->bus->bus_name, |
580 | dev->udev->devpath, status); | 596 | dev->udev->devpath, status); |
581 | } | 597 | } |
582 | 598 | ||
599 | static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message) | ||
600 | { | ||
601 | rtl8150_t *dev = usb_get_intfdata(intf); | ||
602 | |||
603 | netif_device_detach(dev->netdev); | ||
604 | |||
605 | if (netif_running(dev->netdev)) { | ||
606 | usb_kill_urb(dev->rx_urb); | ||
607 | usb_kill_urb(dev->intr_urb); | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static int rtl8150_resume(struct usb_interface *intf) | ||
613 | { | ||
614 | rtl8150_t *dev = usb_get_intfdata(intf); | ||
615 | |||
616 | netif_device_attach(dev->netdev); | ||
617 | if (netif_running(dev->netdev)) { | ||
618 | dev->rx_urb->status = 0; | ||
619 | dev->rx_urb->actual_length = 0; | ||
620 | read_bulk_callback(dev->rx_urb, NULL); | ||
621 | |||
622 | dev->intr_urb->status = 0; | ||
623 | dev->intr_urb->actual_length = 0; | ||
624 | intr_callback(dev->intr_urb, NULL); | ||
625 | } | ||
626 | return 0; | ||
627 | } | ||
583 | 628 | ||
584 | /* | 629 | /* |
585 | ** | 630 | ** |
@@ -690,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
690 | usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), | 735 | usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), |
691 | skb->data, count, write_bulk_callback, dev); | 736 | skb->data, count, write_bulk_callback, dev); |
692 | if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { | 737 | if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { |
693 | warn("failed tx_urb %d\n", res); | 738 | /* Can we get/handle EPIPE here? */ |
694 | dev->stats.tx_errors++; | 739 | if (res == -ENODEV) |
695 | netif_start_queue(netdev); | 740 | netif_device_detach(dev->netdev); |
741 | else { | ||
742 | warn("failed tx_urb %d\n", res); | ||
743 | dev->stats.tx_errors++; | ||
744 | netif_start_queue(netdev); | ||
745 | } | ||
696 | } else { | 746 | } else { |
697 | dev->stats.tx_packets++; | 747 | dev->stats.tx_packets++; |
698 | dev->stats.tx_bytes += skb->len; | 748 | dev->stats.tx_bytes += skb->len; |
@@ -729,16 +779,25 @@ static int rtl8150_open(struct net_device *netdev) | |||
729 | 779 | ||
730 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), | 780 | usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), |
731 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); | 781 | dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); |
732 | if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) | 782 | if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) { |
783 | if (res == -ENODEV) | ||
784 | netif_device_detach(dev->netdev); | ||
733 | warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); | 785 | warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); |
786 | return res; | ||
787 | } | ||
734 | usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), | 788 | usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), |
735 | dev->intr_buff, INTBUFSIZE, intr_callback, | 789 | dev->intr_buff, INTBUFSIZE, intr_callback, |
736 | dev, dev->intr_interval); | 790 | dev, dev->intr_interval); |
737 | if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) | 791 | if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) { |
792 | if (res == -ENODEV) | ||
793 | netif_device_detach(dev->netdev); | ||
738 | warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); | 794 | warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); |
739 | netif_start_queue(netdev); | 795 | usb_kill_urb(dev->rx_urb); |
796 | return res; | ||
797 | } | ||
740 | enable_net_traffic(dev); | 798 | enable_net_traffic(dev); |
741 | set_carrier(netdev); | 799 | set_carrier(netdev); |
800 | netif_start_queue(netdev); | ||
742 | 801 | ||
743 | return res; | 802 | return res; |
744 | } | 803 | } |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index ac33bd47cfce..f5b9438c94f0 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -62,15 +62,6 @@ config USB_SERIAL_AIRPRIME | |||
62 | To compile this driver as a module, choose M here: the | 62 | To compile this driver as a module, choose M here: the |
63 | module will be called airprime. | 63 | module will be called airprime. |
64 | 64 | ||
65 | config USB_SERIAL_ANYDATA | ||
66 | tristate "USB AnyData CDMA Wireless Driver" | ||
67 | depends on USB_SERIAL | ||
68 | help | ||
69 | Say Y here if you want to use a AnyData CDMA device. | ||
70 | |||
71 | To compile this driver as a module, choose M here: the | ||
72 | module will be called anydata. | ||
73 | |||
74 | config USB_SERIAL_ARK3116 | 65 | config USB_SERIAL_ARK3116 |
75 | tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" | 66 | tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" |
76 | depends on USB_SERIAL && EXPERIMENTAL | 67 | depends on USB_SERIAL && EXPERIMENTAL |
@@ -502,15 +493,18 @@ config USB_SERIAL_XIRCOM | |||
502 | module will be called keyspan_pda. | 493 | module will be called keyspan_pda. |
503 | 494 | ||
504 | config USB_SERIAL_OPTION | 495 | config USB_SERIAL_OPTION |
505 | tristate "USB driver for GSM modems" | 496 | tristate "USB driver for GSM and CDMA modems" |
506 | depends on USB_SERIAL | 497 | depends on USB_SERIAL |
507 | help | 498 | help |
508 | Say Y here if you have an "Option" GSM PCMCIA card | 499 | Say Y here if you have a GSM or CDMA modem that's connected to USB. |
509 | (or an OEM version: branded Huawei, Audiovox, or Novatel). | 500 | |
501 | This driver also supports several PCMCIA cards which have a | ||
502 | built-in OHCI-USB adapter and an internally-connected GSM modem. | ||
503 | The USB bus on these cards is not accessible externally. | ||
510 | 504 | ||
511 | These cards feature a built-in OHCI-USB adapter and an | 505 | Supported devices include (some of?) those made by: |
512 | internally-connected GSM modem. The USB bus is not | 506 | Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or |
513 | accessible externally. | 507 | Anydata. |
514 | 508 | ||
515 | To compile this driver as a module, choose M here: the | 509 | To compile this driver as a module, choose M here: the |
516 | module will be called option. | 510 | module will be called option. |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 35d4acc7f1d3..8efed2ce1ba3 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -12,7 +12,6 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o | |||
12 | usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) | 12 | usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) |
13 | 13 | ||
14 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o | 14 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o |
15 | obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o | ||
16 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o | 15 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o |
17 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
18 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 17 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o |
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c deleted file mode 100644 index 01843ef8c11e..000000000000 --- a/drivers/usb/serial/anydata.c +++ /dev/null | |||
@@ -1,123 +0,0 @@ | |||
1 | /* | ||
2 | * AnyData CDMA Serial USB driver | ||
3 | * | ||
4 | * Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/usb.h> | ||
16 | #include <linux/usb/serial.h> | ||
17 | |||
18 | static struct usb_device_id id_table [] = { | ||
19 | { USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */ | ||
20 | { }, | ||
21 | }; | ||
22 | MODULE_DEVICE_TABLE(usb, id_table); | ||
23 | |||
24 | /* if overridden by the user, then use their value for the size of the | ||
25 | * read and write urbs */ | ||
26 | static int buffer_size; | ||
27 | static int debug; | ||
28 | |||
29 | static struct usb_driver anydata_driver = { | ||
30 | .name = "anydata", | ||
31 | .probe = usb_serial_probe, | ||
32 | .disconnect = usb_serial_disconnect, | ||
33 | .id_table = id_table, | ||
34 | .no_dynamic_id = 1, | ||
35 | }; | ||
36 | |||
37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) | ||
38 | { | ||
39 | char *buffer; | ||
40 | int result = 0; | ||
41 | |||
42 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
43 | |||
44 | if (buffer_size) { | ||
45 | /* override the default buffer sizes */ | ||
46 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
47 | if (!buffer) { | ||
48 | dev_err(&port->dev, "%s - out of memory.\n", | ||
49 | __FUNCTION__); | ||
50 | return -ENOMEM; | ||
51 | } | ||
52 | kfree (port->read_urb->transfer_buffer); | ||
53 | port->read_urb->transfer_buffer = buffer; | ||
54 | port->read_urb->transfer_buffer_length = buffer_size; | ||
55 | |||
56 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
57 | if (!buffer) { | ||
58 | dev_err(&port->dev, "%s - out of memory.\n", | ||
59 | __FUNCTION__); | ||
60 | return -ENOMEM; | ||
61 | } | ||
62 | kfree (port->write_urb->transfer_buffer); | ||
63 | port->write_urb->transfer_buffer = buffer; | ||
64 | port->write_urb->transfer_buffer_length = buffer_size; | ||
65 | port->bulk_out_size = buffer_size; | ||
66 | } | ||
67 | |||
68 | /* Start reading from the device */ | ||
69 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | ||
70 | usb_rcvbulkpipe(port->serial->dev, | ||
71 | port->bulk_in_endpointAddress), | ||
72 | port->read_urb->transfer_buffer, | ||
73 | port->read_urb->transfer_buffer_length, | ||
74 | usb_serial_generic_read_bulk_callback, port); | ||
75 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | ||
76 | if (result) | ||
77 | dev_err(&port->dev, | ||
78 | "%s - failed submitting read urb, error %d\n", | ||
79 | __FUNCTION__, result); | ||
80 | |||
81 | return result; | ||
82 | } | ||
83 | |||
84 | static struct usb_serial_driver anydata_device = { | ||
85 | .driver = { | ||
86 | .owner = THIS_MODULE, | ||
87 | .name = "anydata", | ||
88 | }, | ||
89 | .id_table = id_table, | ||
90 | .num_interrupt_in = NUM_DONT_CARE, | ||
91 | .num_bulk_in = NUM_DONT_CARE, | ||
92 | .num_bulk_out = NUM_DONT_CARE, | ||
93 | .num_ports = 1, | ||
94 | .open = anydata_open, | ||
95 | }; | ||
96 | |||
97 | static int __init anydata_init(void) | ||
98 | { | ||
99 | int retval; | ||
100 | |||
101 | retval = usb_serial_register(&anydata_device); | ||
102 | if (retval) | ||
103 | return retval; | ||
104 | retval = usb_register(&anydata_driver); | ||
105 | if (retval) | ||
106 | usb_serial_deregister(&anydata_device); | ||
107 | return retval; | ||
108 | } | ||
109 | |||
110 | static void __exit anydata_exit(void) | ||
111 | { | ||
112 | usb_deregister(&anydata_driver); | ||
113 | usb_serial_deregister(&anydata_device); | ||
114 | } | ||
115 | |||
116 | module_init(anydata_init); | ||
117 | module_exit(anydata_exit); | ||
118 | MODULE_LICENSE("GPL"); | ||
119 | |||
120 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
121 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
122 | module_param(buffer_size, int, 0); | ||
123 | MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers"); | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b458aedc5fb6..a20da8528a5f 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -337,6 +337,7 @@ static struct usb_device_id id_table_combined [] = { | |||
337 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 337 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
338 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, | 338 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
339 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 339 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
340 | { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, | ||
340 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, | 341 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, |
341 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, | 342 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, |
342 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, | 343 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 04ef90fcb876..9f7343a45424 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -182,6 +182,10 @@ | |||
182 | /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ | 182 | /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ |
183 | #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ | 183 | #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ |
184 | 184 | ||
185 | /* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ | ||
186 | |||
187 | #define FTDI_TNC_X_PID 0xEBE0 | ||
188 | |||
185 | /* | 189 | /* |
186 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | 190 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). |
187 | * All of these devices use FTDI's vendor ID (0x0403). | 191 | * All of these devices use FTDI's vendor ID (0x0403). |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 59c5d999009a..7e1bd5d6dfa0 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -250,6 +250,7 @@ static struct usb_device_id ipaq_id_table [] = { | |||
250 | { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ | 250 | { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ |
251 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ | 251 | { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ |
252 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ | 252 | { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ |
253 | { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ | ||
253 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | 254 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ |
254 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | 255 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ |
255 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | 256 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f0530c1d7b7a..c856e6f40e22 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -9,40 +9,14 @@ | |||
9 | 9 | ||
10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
11 | 11 | ||
12 | History: | 12 | History: see the git log. |
13 | |||
14 | 2005-05-19 v0.1 Initial version, based on incomplete docs | ||
15 | and analysis of misbehavior with the standard driver | ||
16 | 2005-05-20 v0.2 Extended the input buffer to avoid losing | ||
17 | random 64-byte chunks of data | ||
18 | 2005-05-21 v0.3 implemented chars_in_buffer() | ||
19 | turned on low_latency | ||
20 | simplified the code somewhat | ||
21 | 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load | ||
22 | removed some dead code | ||
23 | added sponsor notice | ||
24 | coding style clean-up | ||
25 | 2005-06-20 v0.4.1 add missing braces :-/ | ||
26 | killed end-of-line whitespace | ||
27 | 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2 | ||
28 | 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard | ||
29 | 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes | ||
30 | wants to send >2000 bytes. | ||
31 | 2006-04-10 v0.5 fixed two array overrun errors :-/ | ||
32 | 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755 | ||
33 | 2006-05-15 v0.6 re-enable multi-port support | ||
34 | 2006-06-01 v0.6.1 add COBRA | ||
35 | 2006-06-01 v0.6.2 add backwards-compatibility stuff | ||
36 | 2006-06-01 v0.6.3 add Novatel Wireless | ||
37 | 2006-06-01 v0.7 Option => GSM | ||
38 | 2006-06-01 v0.7.1 add COBRA2 | ||
39 | 13 | ||
40 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> | 14 | Work sponsored by: Sigos GmbH, Germany <info@sigos.de> |
41 | 15 | ||
42 | This driver exists because the "normal" serial driver doesn't work too well | 16 | This driver exists because the "normal" serial driver doesn't work too well |
43 | with GSM modems. Issues: | 17 | with GSM modems. Issues: |
44 | - data loss -- one single Receive URB is not nearly enough | 18 | - data loss -- one single Receive URB is not nearly enough |
45 | - nonstandard flow (Option devices) and multiplex (Sierra) control | 19 | - nonstandard flow (Option devices) control |
46 | - controlling the baud rate doesn't make sense | 20 | - controlling the baud rate doesn't make sense |
47 | 21 | ||
48 | This driver is named "option" because the most common device it's | 22 | This driver is named "option" because the most common device it's |
@@ -96,8 +70,8 @@ static int option_send_setup(struct usb_serial_port *port); | |||
96 | #define OPTION_VENDOR_ID 0x0AF0 | 70 | #define OPTION_VENDOR_ID 0x0AF0 |
97 | #define HUAWEI_VENDOR_ID 0x12D1 | 71 | #define HUAWEI_VENDOR_ID 0x12D1 |
98 | #define AUDIOVOX_VENDOR_ID 0x0F3D | 72 | #define AUDIOVOX_VENDOR_ID 0x0F3D |
99 | #define SIERRAWIRELESS_VENDOR_ID 0x1199 | ||
100 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 73 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
74 | #define ANYDATA_VENDOR_ID 0x16d5 | ||
101 | 75 | ||
102 | #define OPTION_PRODUCT_OLD 0x5000 | 76 | #define OPTION_PRODUCT_OLD 0x5000 |
103 | #define OPTION_PRODUCT_FUSION 0x6000 | 77 | #define OPTION_PRODUCT_FUSION 0x6000 |
@@ -106,8 +80,8 @@ static int option_send_setup(struct usb_serial_port *port); | |||
106 | #define OPTION_PRODUCT_COBRA2 0x6600 | 80 | #define OPTION_PRODUCT_COBRA2 0x6600 |
107 | #define HUAWEI_PRODUCT_E600 0x1001 | 81 | #define HUAWEI_PRODUCT_E600 0x1001 |
108 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 | 82 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 |
109 | #define SIERRAWIRELESS_PRODUCT_MC8755 0x6802 | ||
110 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 | 83 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 |
84 | #define ANYDATA_PRODUCT_ID 0x6501 | ||
111 | 85 | ||
112 | static struct usb_device_id option_ids[] = { | 86 | static struct usb_device_id option_ids[] = { |
113 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, | 87 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, |
@@ -117,8 +91,8 @@ static struct usb_device_id option_ids[] = { | |||
117 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | 91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, |
118 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 92 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
119 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 93 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
120 | { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, | ||
121 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 94 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
95 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | ||
122 | { } /* Terminating entry */ | 96 | { } /* Terminating entry */ |
123 | }; | 97 | }; |
124 | 98 | ||
@@ -131,10 +105,7 @@ static struct usb_device_id option_ids1[] = { | |||
131 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 105 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
132 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 106 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
133 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 107 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
134 | { } /* Terminating entry */ | 108 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
135 | }; | ||
136 | static struct usb_device_id option_ids3[] = { | ||
137 | { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, | ||
138 | { } /* Terminating entry */ | 109 | { } /* Terminating entry */ |
139 | }; | 110 | }; |
140 | 111 | ||
@@ -151,37 +122,11 @@ static struct usb_driver option_driver = { | |||
151 | /* The card has three separate interfaces, which the serial driver | 122 | /* The card has three separate interfaces, which the serial driver |
152 | * recognizes separately, thus num_port=1. | 123 | * recognizes separately, thus num_port=1. |
153 | */ | 124 | */ |
154 | static struct usb_serial_driver option_3port_device = { | ||
155 | .driver = { | ||
156 | .owner = THIS_MODULE, | ||
157 | .name = "option", | ||
158 | }, | ||
159 | .description = "GSM modem (3-port)", | ||
160 | .id_table = option_ids3, | ||
161 | .num_interrupt_in = NUM_DONT_CARE, | ||
162 | .num_bulk_in = NUM_DONT_CARE, | ||
163 | .num_bulk_out = NUM_DONT_CARE, | ||
164 | .num_ports = 3, | ||
165 | .open = option_open, | ||
166 | .close = option_close, | ||
167 | .write = option_write, | ||
168 | .write_room = option_write_room, | ||
169 | .chars_in_buffer = option_chars_in_buffer, | ||
170 | .throttle = option_rx_throttle, | ||
171 | .unthrottle = option_rx_unthrottle, | ||
172 | .set_termios = option_set_termios, | ||
173 | .break_ctl = option_break_ctl, | ||
174 | .tiocmget = option_tiocmget, | ||
175 | .tiocmset = option_tiocmset, | ||
176 | .attach = option_startup, | ||
177 | .shutdown = option_shutdown, | ||
178 | .read_int_callback = option_instat_callback, | ||
179 | }; | ||
180 | 125 | ||
181 | static struct usb_serial_driver option_1port_device = { | 126 | static struct usb_serial_driver option_1port_device = { |
182 | .driver = { | 127 | .driver = { |
183 | .owner = THIS_MODULE, | 128 | .owner = THIS_MODULE, |
184 | .name = "option", | 129 | .name = "option1", |
185 | }, | 130 | }, |
186 | .description = "GSM modem (1-port)", | 131 | .description = "GSM modem (1-port)", |
187 | .id_table = option_ids1, | 132 | .id_table = option_ids1, |
@@ -245,9 +190,6 @@ static int __init option_init(void) | |||
245 | retval = usb_serial_register(&option_1port_device); | 190 | retval = usb_serial_register(&option_1port_device); |
246 | if (retval) | 191 | if (retval) |
247 | goto failed_1port_device_register; | 192 | goto failed_1port_device_register; |
248 | retval = usb_serial_register(&option_3port_device); | ||
249 | if (retval) | ||
250 | goto failed_3port_device_register; | ||
251 | retval = usb_register(&option_driver); | 193 | retval = usb_register(&option_driver); |
252 | if (retval) | 194 | if (retval) |
253 | goto failed_driver_register; | 195 | goto failed_driver_register; |
@@ -257,8 +199,6 @@ static int __init option_init(void) | |||
257 | return 0; | 199 | return 0; |
258 | 200 | ||
259 | failed_driver_register: | 201 | failed_driver_register: |
260 | usb_serial_deregister (&option_3port_device); | ||
261 | failed_3port_device_register: | ||
262 | usb_serial_deregister (&option_1port_device); | 202 | usb_serial_deregister (&option_1port_device); |
263 | failed_1port_device_register: | 203 | failed_1port_device_register: |
264 | return retval; | 204 | return retval; |
@@ -267,7 +207,6 @@ failed_1port_device_register: | |||
267 | static void __exit option_exit(void) | 207 | static void __exit option_exit(void) |
268 | { | 208 | { |
269 | usb_deregister (&option_driver); | 209 | usb_deregister (&option_driver); |
270 | usb_serial_deregister (&option_3port_device); | ||
271 | usb_serial_deregister (&option_1port_device); | 210 | usb_serial_deregister (&option_1port_device); |
272 | } | 211 | } |
273 | 212 | ||
@@ -656,7 +595,6 @@ static void option_setup_urbs(struct usb_serial *serial) | |||
656 | 595 | ||
657 | dbg("%s", __FUNCTION__); | 596 | dbg("%s", __FUNCTION__); |
658 | 597 | ||
659 | |||
660 | for (i = 0; i < serial->num_ports; i++) { | 598 | for (i = 0; i < serial->num_ports; i++) { |
661 | port = serial->port[i]; | 599 | port = serial->port[i]; |
662 | portdata = usb_get_serial_port_data(port); | 600 | portdata = usb_get_serial_port_data(port); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 259db31b65c1..efbbc0adb89a 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -81,6 +81,7 @@ static struct usb_device_id id_table [] = { | |||
81 | { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, | 81 | { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, |
82 | { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, | 82 | { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, |
83 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, | 83 | { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, |
84 | { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, | ||
84 | { } /* Terminating entry */ | 85 | { } /* Terminating entry */ |
85 | }; | 86 | }; |
86 | 87 | ||
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index d9c1e6e0b4b3..a692ac66ca6c 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -89,3 +89,7 @@ | |||
89 | /* DATAPILOT Universal-2 Phone Cable */ | 89 | /* DATAPILOT Universal-2 Phone Cable */ |
90 | #define DATAPILOT_U2_VENDOR_ID 0x0731 | 90 | #define DATAPILOT_U2_VENDOR_ID 0x0731 |
91 | #define DATAPILOT_U2_PRODUCT_ID 0x2003 | 91 | #define DATAPILOT_U2_PRODUCT_ID 0x2003 |
92 | |||
93 | /* Belkin "F5U257" Serial Adapter */ | ||
94 | #define BELKIN_VENDOR_ID 0x050d | ||
95 | #define BELKIN_PRODUCT_ID 0x0257 | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a5ca449f6e64..2793f9a912b4 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -145,6 +145,13 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, | |||
145 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 145 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
146 | US_FL_IGNORE_RESIDUE ), | 146 | US_FL_IGNORE_RESIDUE ), |
147 | 147 | ||
148 | /* Reported by Mario Rettig <mariorettig@web.de> */ | ||
149 | UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, | ||
150 | "Nokia", | ||
151 | "Nokia 3250", | ||
152 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
153 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | ||
154 | |||
148 | /* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and | 155 | /* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and |
149 | * Einar Th. Einarsson <einarthered@gmail.com> */ | 156 | * Einar Th. Einarsson <einarthered@gmail.com> */ |
150 | UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, | 157 | UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, |
@@ -627,18 +634,6 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, | |||
627 | "Digital Camera EX-20 DSC", | 634 | "Digital Camera EX-20 DSC", |
628 | US_SC_8070, US_PR_DEVICE, NULL, 0 ), | 635 | US_SC_8070, US_PR_DEVICE, NULL, 0 ), |
629 | 636 | ||
630 | /* The entry was here before I took over, and had US_SC_RBC. It turns | ||
631 | * out that isn't needed. Additionally, Torsten Eriksson | ||
632 | * <Torsten.Eriksson@bergianska.se> is able to use his device fine | ||
633 | * without this entry at all - but I don't suspect that will be true | ||
634 | * for all users (the protocol is likely needed), so is staying at | ||
635 | * this time. - Phil Dibowitz <phil@ipom.com> | ||
636 | */ | ||
637 | UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, | ||
638 | "LaCie", | ||
639 | "USB Hard Disk", | ||
640 | US_SC_DEVICE, US_PR_CB, NULL, 0 ), | ||
641 | |||
642 | /* Submitted by Joel Bourquard <numlock@freesurf.ch> | 637 | /* Submitted by Joel Bourquard <numlock@freesurf.ch> |
643 | * Some versions of this device need the SubClass and Protocol overrides | 638 | * Some versions of this device need the SubClass and Protocol overrides |
644 | * while others don't. | 639 | * while others don't. |
@@ -1106,7 +1101,15 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, | |||
1106 | "Optio S/S4", | 1101 | "Optio S/S4", |
1107 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1102 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1108 | US_FL_FIX_INQUIRY ), | 1103 | US_FL_FIX_INQUIRY ), |
1109 | 1104 | ||
1105 | /* This is a virtual windows driver CD, which the zd1211rw driver automatically | ||
1106 | * converts into a WLAN device. */ | ||
1107 | UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, | ||
1108 | "ZyXEL", | ||
1109 | "G-220F USB-WLAN Install", | ||
1110 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1111 | US_FL_IGNORE_DEVICE ), | ||
1112 | |||
1110 | #ifdef CONFIG_USB_STORAGE_ISD200 | 1113 | #ifdef CONFIG_USB_STORAGE_ISD200 |
1111 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | 1114 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, |
1112 | "ATI", | 1115 | "ATI", |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 5ee19be52f65..8d7bdcb5924d 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -483,7 +483,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | |||
483 | } | 483 | } |
484 | 484 | ||
485 | /* Get the unusual_devs entries and the string descriptors */ | 485 | /* Get the unusual_devs entries and the string descriptors */ |
486 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) | 486 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) |
487 | { | 487 | { |
488 | struct usb_device *dev = us->pusb_dev; | 488 | struct usb_device *dev = us->pusb_dev; |
489 | struct usb_interface_descriptor *idesc = | 489 | struct usb_interface_descriptor *idesc = |
@@ -500,6 +500,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
500 | unusual_dev->useTransport; | 500 | unusual_dev->useTransport; |
501 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); | 501 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
502 | 502 | ||
503 | if (us->flags & US_FL_IGNORE_DEVICE) { | ||
504 | printk(KERN_INFO USB_STORAGE "device ignored\n"); | ||
505 | return -ENODEV; | ||
506 | } | ||
507 | |||
503 | /* | 508 | /* |
504 | * This flag is only needed when we're in high-speed, so let's | 509 | * This flag is only needed when we're in high-speed, so let's |
505 | * disable it if we're in full-speed | 510 | * disable it if we're in full-speed |
@@ -541,6 +546,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
541 | msgs[msg], | 546 | msgs[msg], |
542 | UTS_RELEASE); | 547 | UTS_RELEASE); |
543 | } | 548 | } |
549 | |||
550 | return 0; | ||
544 | } | 551 | } |
545 | 552 | ||
546 | /* Get the transport settings */ | 553 | /* Get the transport settings */ |
@@ -969,7 +976,9 @@ static int storage_probe(struct usb_interface *intf, | |||
969 | * of the match from the usb_device_id table, so we can find the | 976 | * of the match from the usb_device_id table, so we can find the |
970 | * corresponding entry in the private table. | 977 | * corresponding entry in the private table. |
971 | */ | 978 | */ |
972 | get_device_info(us, id); | 979 | result = get_device_info(us, id); |
980 | if (result) | ||
981 | goto BadDevice; | ||
973 | 982 | ||
974 | /* Get the transport, protocol, and pipe settings */ | 983 | /* Get the transport, protocol, and pipe settings */ |
975 | result = get_transport(us); | 984 | result = get_transport(us); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6533b0f39231..c40b9b8b1e7e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -86,9 +86,11 @@ config FB_MACMODES | |||
86 | default n | 86 | default n |
87 | 87 | ||
88 | config FB_BACKLIGHT | 88 | config FB_BACKLIGHT |
89 | bool | 89 | bool |
90 | depends on FB | 90 | depends on FB |
91 | default n | 91 | select BACKLIGHT_LCD_SUPPORT |
92 | select BACKLIGHT_CLASS_DEVICE | ||
93 | default n | ||
92 | 94 | ||
93 | config FB_MODE_HELPERS | 95 | config FB_MODE_HELPERS |
94 | bool "Enable Video Mode Handling Helpers" | 96 | bool "Enable Video Mode Handling Helpers" |
@@ -420,7 +422,7 @@ config FB_OF | |||
420 | 422 | ||
421 | config FB_CONTROL | 423 | config FB_CONTROL |
422 | bool "Apple \"control\" display support" | 424 | bool "Apple \"control\" display support" |
423 | depends on (FB = y) && PPC_PMAC | 425 | depends on (FB = y) && PPC_PMAC && PPC32 |
424 | select FB_CFB_FILLRECT | 426 | select FB_CFB_FILLRECT |
425 | select FB_CFB_COPYAREA | 427 | select FB_CFB_COPYAREA |
426 | select FB_CFB_IMAGEBLIT | 428 | select FB_CFB_IMAGEBLIT |
@@ -431,7 +433,7 @@ config FB_CONTROL | |||
431 | 433 | ||
432 | config FB_PLATINUM | 434 | config FB_PLATINUM |
433 | bool "Apple \"platinum\" display support" | 435 | bool "Apple \"platinum\" display support" |
434 | depends on (FB = y) && PPC_PMAC | 436 | depends on (FB = y) && PPC_PMAC && PPC32 |
435 | select FB_CFB_FILLRECT | 437 | select FB_CFB_FILLRECT |
436 | select FB_CFB_COPYAREA | 438 | select FB_CFB_COPYAREA |
437 | select FB_CFB_IMAGEBLIT | 439 | select FB_CFB_IMAGEBLIT |
@@ -442,7 +444,7 @@ config FB_PLATINUM | |||
442 | 444 | ||
443 | config FB_VALKYRIE | 445 | config FB_VALKYRIE |
444 | bool "Apple \"valkyrie\" display support" | 446 | bool "Apple \"valkyrie\" display support" |
445 | depends on (FB = y) && (MAC || PPC_PMAC) | 447 | depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) |
446 | select FB_CFB_FILLRECT | 448 | select FB_CFB_FILLRECT |
447 | select FB_CFB_COPYAREA | 449 | select FB_CFB_COPYAREA |
448 | select FB_CFB_IMAGEBLIT | 450 | select FB_CFB_IMAGEBLIT |
@@ -453,7 +455,7 @@ config FB_VALKYRIE | |||
453 | 455 | ||
454 | config FB_CT65550 | 456 | config FB_CT65550 |
455 | bool "Chips 65550 display support" | 457 | bool "Chips 65550 display support" |
456 | depends on (FB = y) && PPC | 458 | depends on (FB = y) && PPC32 |
457 | select FB_CFB_FILLRECT | 459 | select FB_CFB_FILLRECT |
458 | select FB_CFB_COPYAREA | 460 | select FB_CFB_COPYAREA |
459 | select FB_CFB_IMAGEBLIT | 461 | select FB_CFB_IMAGEBLIT |
@@ -721,10 +723,8 @@ config FB_NVIDIA_I2C | |||
721 | 723 | ||
722 | config FB_NVIDIA_BACKLIGHT | 724 | config FB_NVIDIA_BACKLIGHT |
723 | bool "Support for backlight control" | 725 | bool "Support for backlight control" |
724 | depends on FB_NVIDIA && PPC_PMAC | 726 | depends on FB_NVIDIA && PMAC_BACKLIGHT |
725 | select FB_BACKLIGHT | 727 | select FB_BACKLIGHT |
726 | select BACKLIGHT_LCD_SUPPORT | ||
727 | select BACKLIGHT_CLASS_DEVICE | ||
728 | default y | 728 | default y |
729 | help | 729 | help |
730 | Say Y here if you want to control the backlight of your display. | 730 | Say Y here if you want to control the backlight of your display. |
@@ -769,10 +769,8 @@ config FB_RIVA_DEBUG | |||
769 | 769 | ||
770 | config FB_RIVA_BACKLIGHT | 770 | config FB_RIVA_BACKLIGHT |
771 | bool "Support for backlight control" | 771 | bool "Support for backlight control" |
772 | depends on FB_RIVA && PPC_PMAC | 772 | depends on FB_RIVA && PMAC_BACKLIGHT |
773 | select FB_BACKLIGHT | 773 | select FB_BACKLIGHT |
774 | select BACKLIGHT_LCD_SUPPORT | ||
775 | select BACKLIGHT_CLASS_DEVICE | ||
776 | default y | 774 | default y |
777 | help | 775 | help |
778 | Say Y here if you want to control the backlight of your display. | 776 | Say Y here if you want to control the backlight of your display. |
@@ -1025,10 +1023,8 @@ config FB_RADEON_I2C | |||
1025 | 1023 | ||
1026 | config FB_RADEON_BACKLIGHT | 1024 | config FB_RADEON_BACKLIGHT |
1027 | bool "Support for backlight control" | 1025 | bool "Support for backlight control" |
1028 | depends on FB_RADEON && PPC_PMAC | 1026 | depends on FB_RADEON && PMAC_BACKLIGHT |
1029 | select FB_BACKLIGHT | 1027 | select FB_BACKLIGHT |
1030 | select BACKLIGHT_LCD_SUPPORT | ||
1031 | select BACKLIGHT_CLASS_DEVICE | ||
1032 | default y | 1028 | default y |
1033 | help | 1029 | help |
1034 | Say Y here if you want to control the backlight of your display. | 1030 | Say Y here if you want to control the backlight of your display. |
@@ -1059,10 +1055,8 @@ config FB_ATY128 | |||
1059 | 1055 | ||
1060 | config FB_ATY128_BACKLIGHT | 1056 | config FB_ATY128_BACKLIGHT |
1061 | bool "Support for backlight control" | 1057 | bool "Support for backlight control" |
1062 | depends on FB_ATY128 && PPC_PMAC | 1058 | depends on FB_ATY128 && PMAC_BACKLIGHT |
1063 | select FB_BACKLIGHT | 1059 | select FB_BACKLIGHT |
1064 | select BACKLIGHT_LCD_SUPPORT | ||
1065 | select BACKLIGHT_CLASS_DEVICE | ||
1066 | default y | 1060 | default y |
1067 | help | 1061 | help |
1068 | Say Y here if you want to control the backlight of your display. | 1062 | Say Y here if you want to control the backlight of your display. |
@@ -1111,10 +1105,8 @@ config FB_ATY_GX | |||
1111 | 1105 | ||
1112 | config FB_ATY_BACKLIGHT | 1106 | config FB_ATY_BACKLIGHT |
1113 | bool "Support for backlight control" | 1107 | bool "Support for backlight control" |
1114 | depends on FB_ATY && PPC_PMAC | 1108 | depends on FB_ATY && PMAC_BACKLIGHT |
1115 | select FB_BACKLIGHT | 1109 | select FB_BACKLIGHT |
1116 | select BACKLIGHT_LCD_SUPPORT | ||
1117 | select BACKLIGHT_CLASS_DEVICE | ||
1118 | default y | 1110 | default y |
1119 | help | 1111 | help |
1120 | Say Y here if you want to control the backlight of your display. | 1112 | Say Y here if you want to control the backlight of your display. |
@@ -1620,7 +1612,7 @@ if FB || SGI_NEWPORT_CONSOLE | |||
1620 | source "drivers/video/logo/Kconfig" | 1612 | source "drivers/video/logo/Kconfig" |
1621 | endif | 1613 | endif |
1622 | 1614 | ||
1623 | if FB && SYSFS | 1615 | if SYSFS |
1624 | source "drivers/video/backlight/Kconfig" | 1616 | source "drivers/video/backlight/Kconfig" |
1625 | endif | 1617 | endif |
1626 | 1618 | ||
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 95563c9c6b9c..481c6c9695f8 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-y += fb_notify.o | ||
7 | obj-$(CONFIG_FB) += fb.o | 8 | obj-$(CONFIG_FB) += fb.o |
8 | fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ | 9 | fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ |
9 | modedb.o fbcvt.o | 10 | modedb.o fbcvt.o |
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index c64a717e2d4b..3e827e04a2aa 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -455,7 +455,10 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par); | |||
455 | static void wait_for_fifo(u16 entries, struct aty128fb_par *par); | 455 | static void wait_for_fifo(u16 entries, struct aty128fb_par *par); |
456 | static void wait_for_idle(struct aty128fb_par *par); | 456 | static void wait_for_idle(struct aty128fb_par *par); |
457 | static u32 depth_to_dst(u32 depth); | 457 | static u32 depth_to_dst(u32 depth); |
458 | |||
459 | #ifdef CONFIG_FB_ATY128_BACKLIGHT | ||
458 | static void aty128_bl_set_power(struct fb_info *info, int power); | 460 | static void aty128_bl_set_power(struct fb_info *info, int power); |
461 | #endif | ||
459 | 462 | ||
460 | #define BIOS_IN8(v) (readb(bios + (v))) | 463 | #define BIOS_IN8(v) (readb(bios + (v))) |
461 | #define BIOS_IN16(v) (readb(bios + (v)) | \ | 464 | #define BIOS_IN16(v) (readb(bios + (v)) | \ |
@@ -1910,9 +1913,6 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i | |||
1910 | u8 chip_rev; | 1913 | u8 chip_rev; |
1911 | u32 dac; | 1914 | u32 dac; |
1912 | 1915 | ||
1913 | if (!par->vram_size) /* may have already been probed */ | ||
1914 | par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; | ||
1915 | |||
1916 | /* Get the chip revision */ | 1916 | /* Get the chip revision */ |
1917 | chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; | 1917 | chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; |
1918 | 1918 | ||
@@ -2025,9 +2025,6 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i | |||
2025 | 2025 | ||
2026 | aty128_init_engine(par); | 2026 | aty128_init_engine(par); |
2027 | 2027 | ||
2028 | if (register_framebuffer(info) < 0) | ||
2029 | return 0; | ||
2030 | |||
2031 | par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); | 2028 | par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); |
2032 | par->pdev = pdev; | 2029 | par->pdev = pdev; |
2033 | par->asleep = 0; | 2030 | par->asleep = 0; |
@@ -2037,6 +2034,9 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i | |||
2037 | aty128_bl_init(par); | 2034 | aty128_bl_init(par); |
2038 | #endif | 2035 | #endif |
2039 | 2036 | ||
2037 | if (register_framebuffer(info) < 0) | ||
2038 | return 0; | ||
2039 | |||
2040 | printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", | 2040 | printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", |
2041 | info->node, info->fix.id, video_card); | 2041 | info->node, info->fix.id, video_card); |
2042 | 2042 | ||
@@ -2086,7 +2086,6 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_ | |||
2086 | par = info->par; | 2086 | par = info->par; |
2087 | 2087 | ||
2088 | info->pseudo_palette = par->pseudo_palette; | 2088 | info->pseudo_palette = par->pseudo_palette; |
2089 | info->fix = aty128fb_fix; | ||
2090 | 2089 | ||
2091 | /* Virtualize mmio region */ | 2090 | /* Virtualize mmio region */ |
2092 | info->fix.mmio_start = reg_addr; | 2091 | info->fix.mmio_start = reg_addr; |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 1507d19f481f..053ff63365b7 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2812,7 +2812,7 @@ static int atyfb_blank(int blank, struct fb_info *info) | |||
2812 | if (par->lock_blank || par->asleep) | 2812 | if (par->lock_blank || par->asleep) |
2813 | return 0; | 2813 | return 0; |
2814 | 2814 | ||
2815 | #ifdef CONFIG_PMAC_BACKLIGHT | 2815 | #ifdef CONFIG_FB_ATY_BACKLIGHT |
2816 | if (machine_is(powermac) && blank > FB_BLANK_NORMAL) | 2816 | if (machine_is(powermac) && blank > FB_BLANK_NORMAL) |
2817 | aty_bl_set_power(info, FB_BLANK_POWERDOWN); | 2817 | aty_bl_set_power(info, FB_BLANK_POWERDOWN); |
2818 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) | 2818 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) |
@@ -2844,7 +2844,7 @@ static int atyfb_blank(int blank, struct fb_info *info) | |||
2844 | } | 2844 | } |
2845 | aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); | 2845 | aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); |
2846 | 2846 | ||
2847 | #ifdef CONFIG_PMAC_BACKLIGHT | 2847 | #ifdef CONFIG_FB_ATY_BACKLIGHT |
2848 | if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) | 2848 | if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) |
2849 | aty_bl_set_power(info, FB_BLANK_UNBLANK); | 2849 | aty_bl_set_power(info, FB_BLANK_UNBLANK); |
2850 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) | 2850 | #elif defined(CONFIG_FB_ATY_GENERIC_LCD) |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 8d85fc58142e..8e3400d5dd21 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -266,6 +266,8 @@ static int force_measure_pll = 0; | |||
266 | #ifdef CONFIG_MTRR | 266 | #ifdef CONFIG_MTRR |
267 | static int nomtrr = 0; | 267 | static int nomtrr = 0; |
268 | #endif | 268 | #endif |
269 | static int force_sleep; | ||
270 | static int ignore_devlist; | ||
269 | 271 | ||
270 | /* | 272 | /* |
271 | * prototypes | 273 | * prototypes |
@@ -2327,9 +2329,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, | |||
2327 | /* -2 is special: means ON on mobility chips and do not | 2329 | /* -2 is special: means ON on mobility chips and do not |
2328 | * change on others | 2330 | * change on others |
2329 | */ | 2331 | */ |
2330 | radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); | 2332 | radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep); |
2331 | } else | 2333 | } else |
2332 | radeonfb_pm_init(rinfo, default_dynclk); | 2334 | radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep); |
2333 | 2335 | ||
2334 | pci_set_drvdata(pdev, info); | 2336 | pci_set_drvdata(pdev, info); |
2335 | 2337 | ||
@@ -2477,6 +2479,12 @@ static int __init radeonfb_setup (char *options) | |||
2477 | force_measure_pll = 1; | 2479 | force_measure_pll = 1; |
2478 | } else if (!strncmp(this_opt, "ignore_edid", 11)) { | 2480 | } else if (!strncmp(this_opt, "ignore_edid", 11)) { |
2479 | ignore_edid = 1; | 2481 | ignore_edid = 1; |
2482 | #if defined(CONFIG_PM) && defined(CONFIG_X86) | ||
2483 | } else if (!strncmp(this_opt, "force_sleep", 11)) { | ||
2484 | force_sleep = 1; | ||
2485 | } else if (!strncmp(this_opt, "ignore_devlist", 14)) { | ||
2486 | ignore_devlist = 1; | ||
2487 | #endif | ||
2480 | } else | 2488 | } else |
2481 | mode_option = this_opt; | 2489 | mode_option = this_opt; |
2482 | } | 2490 | } |
@@ -2532,3 +2540,9 @@ module_param(panel_yres, int, 0); | |||
2532 | MODULE_PARM_DESC(panel_yres, "int: set panel yres"); | 2540 | MODULE_PARM_DESC(panel_yres, "int: set panel yres"); |
2533 | module_param(mode_option, charp, 0); | 2541 | module_param(mode_option, charp, 0); |
2534 | MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); | 2542 | MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); |
2543 | #if defined(CONFIG_PM) && defined(CONFIG_X86) | ||
2544 | module_param(force_sleep, bool, 0); | ||
2545 | MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware"); | ||
2546 | module_param(ignore_devlist, bool, 0); | ||
2547 | MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops"); | ||
2548 | #endif | ||
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index c7091761cef4..f31e606a2ded 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c | |||
@@ -27,6 +27,99 @@ | |||
27 | 27 | ||
28 | #include "ati_ids.h" | 28 | #include "ati_ids.h" |
29 | 29 | ||
30 | static void radeon_reinitialize_M10(struct radeonfb_info *rinfo); | ||
31 | |||
32 | /* | ||
33 | * Workarounds for bugs in PC laptops: | ||
34 | * - enable D2 sleep in some IBM Thinkpads | ||
35 | * - special case for Samsung P35 | ||
36 | * | ||
37 | * Whitelist by subsystem vendor/device because | ||
38 | * its the subsystem vendor's fault! | ||
39 | */ | ||
40 | |||
41 | #if defined(CONFIG_PM) && defined(CONFIG_X86) | ||
42 | struct radeon_device_id { | ||
43 | const char *ident; /* (arbitrary) Name */ | ||
44 | const unsigned short subsystem_vendor; /* Subsystem Vendor ID */ | ||
45 | const unsigned short subsystem_device; /* Subsystem Device ID */ | ||
46 | const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */ | ||
47 | const reinit_function_ptr new_reinit_func; /* changed reinit_func */ | ||
48 | }; | ||
49 | |||
50 | #define BUGFIX(model, sv, sd, pm, fn) { \ | ||
51 | .ident = model, \ | ||
52 | .subsystem_vendor = sv, \ | ||
53 | .subsystem_device = sd, \ | ||
54 | .pm_mode_modifier = pm, \ | ||
55 | .new_reinit_func = fn \ | ||
56 | } | ||
57 | |||
58 | static struct radeon_device_id radeon_workaround_list[] = { | ||
59 | BUGFIX("IBM Thinkpad R32", | ||
60 | PCI_VENDOR_ID_IBM, 0x1905, | ||
61 | radeon_pm_d2, NULL), | ||
62 | BUGFIX("IBM Thinkpad R40", | ||
63 | PCI_VENDOR_ID_IBM, 0x0526, | ||
64 | radeon_pm_d2, NULL), | ||
65 | BUGFIX("IBM Thinkpad R40", | ||
66 | PCI_VENDOR_ID_IBM, 0x0527, | ||
67 | radeon_pm_d2, NULL), | ||
68 | BUGFIX("IBM Thinkpad R50/R51/T40/T41", | ||
69 | PCI_VENDOR_ID_IBM, 0x0531, | ||
70 | radeon_pm_d2, NULL), | ||
71 | BUGFIX("IBM Thinkpad R51/T40/T41/T42", | ||
72 | PCI_VENDOR_ID_IBM, 0x0530, | ||
73 | radeon_pm_d2, NULL), | ||
74 | BUGFIX("IBM Thinkpad T30", | ||
75 | PCI_VENDOR_ID_IBM, 0x0517, | ||
76 | radeon_pm_d2, NULL), | ||
77 | BUGFIX("IBM Thinkpad T40p", | ||
78 | PCI_VENDOR_ID_IBM, 0x054d, | ||
79 | radeon_pm_d2, NULL), | ||
80 | BUGFIX("IBM Thinkpad T42", | ||
81 | PCI_VENDOR_ID_IBM, 0x0550, | ||
82 | radeon_pm_d2, NULL), | ||
83 | BUGFIX("IBM Thinkpad X31/X32", | ||
84 | PCI_VENDOR_ID_IBM, 0x052f, | ||
85 | radeon_pm_d2, NULL), | ||
86 | BUGFIX("Samsung P35", | ||
87 | PCI_VENDOR_ID_SAMSUNG, 0xc00c, | ||
88 | radeon_pm_off, radeon_reinitialize_M10), | ||
89 | { .ident = NULL } | ||
90 | }; | ||
91 | |||
92 | static int radeon_apply_workarounds(struct radeonfb_info *rinfo) | ||
93 | { | ||
94 | struct radeon_device_id *id; | ||
95 | |||
96 | for (id = radeon_workaround_list; id->ident != NULL; id++ ) | ||
97 | if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) && | ||
98 | (id->subsystem_device == rinfo->pdev->subsystem_device )) { | ||
99 | |||
100 | /* we found a device that requires workaround */ | ||
101 | printk(KERN_DEBUG "radeonfb: %s detected" | ||
102 | ", enabling workaround\n", id->ident); | ||
103 | |||
104 | rinfo->pm_mode |= id->pm_mode_modifier; | ||
105 | |||
106 | if (id->new_reinit_func != NULL) | ||
107 | rinfo->reinit_func = id->new_reinit_func; | ||
108 | |||
109 | return 1; | ||
110 | } | ||
111 | return 0; /* not found */ | ||
112 | } | ||
113 | |||
114 | #else /* defined(CONFIG_PM) && defined(CONFIG_X86) */ | ||
115 | static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo) | ||
116 | { | ||
117 | return 0; | ||
118 | } | ||
119 | #endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */ | ||
120 | |||
121 | |||
122 | |||
30 | static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) | 123 | static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) |
31 | { | 124 | { |
32 | u32 tmp; | 125 | u32 tmp; |
@@ -852,18 +945,26 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) | |||
852 | /* because both INPLL and OUTPLL take the same lock, that's why. */ | 945 | /* because both INPLL and OUTPLL take the same lock, that's why. */ |
853 | tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; | 946 | tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; |
854 | OUTPLL( pllMCLK_MISC, tmp); | 947 | OUTPLL( pllMCLK_MISC, tmp); |
855 | |||
856 | /* AGP PLL control */ | ||
857 | if (rinfo->family <= CHIP_FAMILY_RV280) { | ||
858 | OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); | ||
859 | 948 | ||
860 | OUTREG(BUS_CNTL1, | 949 | /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset |
861 | (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) | 950 | * and radeon chip dependent. Thus we only enable it on Mac for |
862 | | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX | 951 | * now (until we get more info on how to compute the correct |
863 | } else { | 952 | * value for various X86 bridges). |
864 | OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); | 953 | */ |
865 | OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); | 954 | #ifdef CONFIG_PPC_PMAC |
955 | if (machine_is(powermac)) { | ||
956 | /* AGP PLL control */ | ||
957 | if (rinfo->family <= CHIP_FAMILY_RV280) { | ||
958 | OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); | ||
959 | OUTREG(BUS_CNTL1, | ||
960 | (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) | ||
961 | | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX | ||
962 | } else { | ||
963 | OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); | ||
964 | OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); | ||
965 | } | ||
866 | } | 966 | } |
967 | #endif | ||
867 | 968 | ||
868 | OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) | 969 | OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) |
869 | & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN)); | 970 | & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN)); |
@@ -2713,7 +2814,7 @@ static void radeonfb_early_resume(void *data) | |||
2713 | 2814 | ||
2714 | #endif /* CONFIG_PM */ | 2815 | #endif /* CONFIG_PM */ |
2715 | 2816 | ||
2716 | void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) | 2817 | void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep) |
2717 | { | 2818 | { |
2718 | /* Find PM registers in config space if any*/ | 2819 | /* Find PM registers in config space if any*/ |
2719 | rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); | 2820 | rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); |
@@ -2729,22 +2830,13 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) | |||
2729 | } | 2830 | } |
2730 | 2831 | ||
2731 | #if defined(CONFIG_PM) | 2832 | #if defined(CONFIG_PM) |
2833 | #if defined(CONFIG_PPC_PMAC) | ||
2732 | /* Check if we can power manage on suspend/resume. We can do | 2834 | /* Check if we can power manage on suspend/resume. We can do |
2733 | * D2 on M6, M7 and M9, and we can resume from D3 cold a few other | 2835 | * D2 on M6, M7 and M9, and we can resume from D3 cold a few other |
2734 | * "Mac" cards, but that's all. We need more infos about what the | 2836 | * "Mac" cards, but that's all. We need more infos about what the |
2735 | * BIOS does tho. Right now, all this PM stuff is pmac-only for that | 2837 | * BIOS does tho. Right now, all this PM stuff is pmac-only for that |
2736 | * reason. --BenH | 2838 | * reason. --BenH |
2737 | */ | 2839 | */ |
2738 | /* Special case for Samsung P35 laptops | ||
2739 | */ | ||
2740 | if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) && | ||
2741 | (rinfo->pdev->device == PCI_CHIP_RV350_NP) && | ||
2742 | (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) && | ||
2743 | (rinfo->pdev->subsystem_device == 0xc00c)) { | ||
2744 | rinfo->reinit_func = radeon_reinitialize_M10; | ||
2745 | rinfo->pm_mode |= radeon_pm_off; | ||
2746 | } | ||
2747 | #if defined(CONFIG_PPC_PMAC) | ||
2748 | if (machine_is(powermac) && rinfo->of_node) { | 2840 | if (machine_is(powermac) && rinfo->of_node) { |
2749 | if (rinfo->is_mobility && rinfo->pm_reg && | 2841 | if (rinfo->is_mobility && rinfo->pm_reg && |
2750 | rinfo->family <= CHIP_FAMILY_RV250) | 2842 | rinfo->family <= CHIP_FAMILY_RV250) |
@@ -2790,6 +2882,18 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) | |||
2790 | } | 2882 | } |
2791 | #endif /* defined(CONFIG_PPC_PMAC) */ | 2883 | #endif /* defined(CONFIG_PPC_PMAC) */ |
2792 | #endif /* defined(CONFIG_PM) */ | 2884 | #endif /* defined(CONFIG_PM) */ |
2885 | |||
2886 | if (ignore_devlist) | ||
2887 | printk(KERN_DEBUG | ||
2888 | "radeonfb: skipping test for device workarounds\n"); | ||
2889 | else | ||
2890 | radeon_apply_workarounds(rinfo); | ||
2891 | |||
2892 | if (force_sleep) { | ||
2893 | printk(KERN_DEBUG | ||
2894 | "radeonfb: forcefully enabling D2 sleep mode\n"); | ||
2895 | rinfo->pm_mode |= radeon_pm_d2; | ||
2896 | } | ||
2793 | } | 2897 | } |
2794 | 2898 | ||
2795 | void radeonfb_pm_exit(struct radeonfb_info *rinfo) | 2899 | void radeonfb_pm_exit(struct radeonfb_info *rinfo) |
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 38657b2d10eb..d5ff224a6258 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h | |||
@@ -273,6 +273,8 @@ enum radeon_pm_mode { | |||
273 | radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ | 273 | radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ |
274 | }; | 274 | }; |
275 | 275 | ||
276 | typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo); | ||
277 | |||
276 | struct radeonfb_info { | 278 | struct radeonfb_info { |
277 | struct fb_info *info; | 279 | struct fb_info *info; |
278 | 280 | ||
@@ -338,7 +340,7 @@ struct radeonfb_info { | |||
338 | int dynclk; | 340 | int dynclk; |
339 | int no_schedule; | 341 | int no_schedule; |
340 | enum radeon_pm_mode pm_mode; | 342 | enum radeon_pm_mode pm_mode; |
341 | void (*reinit_func)(struct radeonfb_info *rinfo); | 343 | reinit_function_ptr reinit_func; |
342 | 344 | ||
343 | /* Lock on register access */ | 345 | /* Lock on register access */ |
344 | spinlock_t reg_lock; | 346 | spinlock_t reg_lock; |
@@ -600,7 +602,7 @@ extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 | |||
600 | /* PM Functions */ | 602 | /* PM Functions */ |
601 | extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state); | 603 | extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state); |
602 | extern int radeonfb_pci_resume(struct pci_dev *pdev); | 604 | extern int radeonfb_pci_resume(struct pci_dev *pdev); |
603 | extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk); | 605 | extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep); |
604 | extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); | 606 | extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); |
605 | 607 | ||
606 | /* Monitor probe functions */ | 608 | /* Monitor probe functions */ |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index a92a91fef16f..f25d5d648333 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -156,7 +156,7 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) | |||
156 | 156 | ||
157 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 157 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
158 | info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */ | 158 | info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */ |
159 | } | 159 | } |
160 | } else { | 160 | } else { |
161 | /* mono */ | 161 | /* mono */ |
162 | info->fix.visual = FB_VISUAL_MONO10; | 162 | info->fix.visual = FB_VISUAL_MONO10; |
@@ -164,20 +164,16 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | info->screen_size = info->fix.line_length * info->var.yres_virtual; | 166 | info->screen_size = info->fix.line_length * info->var.yres_virtual; |
167 | info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \ | ||
168 | >> LCD_CONTROL_SM_BIT) * 90; | ||
167 | 169 | ||
168 | /* Determine BPP mode and format */ | 170 | /* Determine BPP mode and format */ |
169 | fbdev->regs->lcd_control = fbdev->panel->control_base | | 171 | fbdev->regs->lcd_control = fbdev->panel->control_base; |
170 | ((info->var.rotate/90) << LCD_CONTROL_SM_BIT); | ||
171 | |||
172 | fbdev->regs->lcd_intenable = 0; | ||
173 | fbdev->regs->lcd_intstatus = 0; | ||
174 | |||
175 | fbdev->regs->lcd_horztiming = fbdev->panel->horztiming; | 172 | fbdev->regs->lcd_horztiming = fbdev->panel->horztiming; |
176 | |||
177 | fbdev->regs->lcd_verttiming = fbdev->panel->verttiming; | 173 | fbdev->regs->lcd_verttiming = fbdev->panel->verttiming; |
178 | |||
179 | fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base; | 174 | fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base; |
180 | 175 | fbdev->regs->lcd_intenable = 0; | |
176 | fbdev->regs->lcd_intstatus = 0; | ||
181 | fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys); | 177 | fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys); |
182 | 178 | ||
183 | if (panel_is_dual(fbdev->panel)) { | 179 | if (panel_is_dual(fbdev->panel)) { |
@@ -206,6 +202,8 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) | |||
206 | 202 | ||
207 | /* Resume controller */ | 203 | /* Resume controller */ |
208 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; | 204 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; |
205 | mdelay(10); | ||
206 | au1100fb_fb_blank(VESA_NO_BLANKING, info); | ||
209 | 207 | ||
210 | return 0; | 208 | return 0; |
211 | } | 209 | } |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 022f9d3473f5..02f15297a021 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT | |||
10 | 10 | ||
11 | config BACKLIGHT_CLASS_DEVICE | 11 | config BACKLIGHT_CLASS_DEVICE |
12 | tristate "Lowlevel Backlight controls" | 12 | tristate "Lowlevel Backlight controls" |
13 | depends on BACKLIGHT_LCD_SUPPORT && FB | 13 | depends on BACKLIGHT_LCD_SUPPORT |
14 | default m | 14 | default m |
15 | help | 15 | help |
16 | This framework adds support for low-level control of the LCD | 16 | This framework adds support for low-level control of the LCD |
@@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE | |||
26 | 26 | ||
27 | config LCD_CLASS_DEVICE | 27 | config LCD_CLASS_DEVICE |
28 | tristate "Lowlevel LCD controls" | 28 | tristate "Lowlevel LCD controls" |
29 | depends on BACKLIGHT_LCD_SUPPORT && FB | 29 | depends on BACKLIGHT_LCD_SUPPORT |
30 | default m | 30 | default m |
31 | help | 31 | help |
32 | This framework adds support for low-level control of LCD. | 32 | This framework adds support for low-level control of LCD. |
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 52ed12b12acc..eb4d03fa5391 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c | |||
@@ -197,7 +197,7 @@ static int __init mdacon_setup(char *str) | |||
197 | __setup("mdacon=", mdacon_setup); | 197 | __setup("mdacon=", mdacon_setup); |
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | static int __init mda_detect(void) | 200 | static int mda_detect(void) |
201 | { | 201 | { |
202 | int count=0; | 202 | int count=0; |
203 | u16 *p, p_save; | 203 | u16 *p, p_save; |
@@ -282,7 +282,7 @@ static int __init mda_detect(void) | |||
282 | return 1; | 282 | return 1; |
283 | } | 283 | } |
284 | 284 | ||
285 | static void __init mda_initialize(void) | 285 | static void mda_initialize(void) |
286 | { | 286 | { |
287 | write_mda_b(97, 0x00); /* horizontal total */ | 287 | write_mda_b(97, 0x00); /* horizontal total */ |
288 | write_mda_b(80, 0x01); /* horizontal displayed */ | 288 | write_mda_b(80, 0x01); /* horizontal displayed */ |
diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c new file mode 100644 index 000000000000..8c020389e4fa --- /dev/null +++ b/drivers/video/fb_notify.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/fb_notify.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Antonino Daplas <adaplas@pol.net> | ||
5 | * | ||
6 | * 2001 - Documented with DocBook | ||
7 | * - Brad Douglas <brad@neruo.com> | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive | ||
11 | * for more details. | ||
12 | */ | ||
13 | #include <linux/fb.h> | ||
14 | #include <linux/notifier.h> | ||
15 | |||
16 | static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); | ||
17 | |||
18 | /** | ||
19 | * fb_register_client - register a client notifier | ||
20 | * @nb: notifier block to callback on events | ||
21 | */ | ||
22 | int fb_register_client(struct notifier_block *nb) | ||
23 | { | ||
24 | return blocking_notifier_chain_register(&fb_notifier_list, nb); | ||
25 | } | ||
26 | EXPORT_SYMBOL(fb_register_client); | ||
27 | |||
28 | /** | ||
29 | * fb_unregister_client - unregister a client notifier | ||
30 | * @nb: notifier block to callback on events | ||
31 | */ | ||
32 | int fb_unregister_client(struct notifier_block *nb) | ||
33 | { | ||
34 | return blocking_notifier_chain_unregister(&fb_notifier_list, nb); | ||
35 | } | ||
36 | EXPORT_SYMBOL(fb_unregister_client); | ||
37 | |||
38 | /** | ||
39 | * fb_notifier_call_chain - notify clients of fb_events | ||
40 | * | ||
41 | */ | ||
42 | int fb_notifier_call_chain(unsigned long val, void *v) | ||
43 | { | ||
44 | return blocking_notifier_call_chain(&fb_notifier_list, val, v); | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(fb_notifier_call_chain); | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 4fc9df426c1a..17961e3ecaa0 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -52,7 +52,6 @@ | |||
52 | 52 | ||
53 | #define FBPIXMAPSIZE (1024 * 8) | 53 | #define FBPIXMAPSIZE (1024 * 8) |
54 | 54 | ||
55 | static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); | ||
56 | struct fb_info *registered_fb[FB_MAX]; | 55 | struct fb_info *registered_fb[FB_MAX]; |
57 | int num_registered_fb; | 56 | int num_registered_fb; |
58 | 57 | ||
@@ -791,8 +790,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
791 | 790 | ||
792 | event.info = info; | 791 | event.info = info; |
793 | event.data = &mode1; | 792 | event.data = &mode1; |
794 | ret = blocking_notifier_call_chain(&fb_notifier_list, | 793 | ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); |
795 | FB_EVENT_MODE_DELETE, &event); | ||
796 | } | 794 | } |
797 | 795 | ||
798 | if (!ret) | 796 | if (!ret) |
@@ -837,8 +835,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
837 | 835 | ||
838 | info->flags &= ~FBINFO_MISC_USEREVENT; | 836 | info->flags &= ~FBINFO_MISC_USEREVENT; |
839 | event.info = info; | 837 | event.info = info; |
840 | blocking_notifier_call_chain(&fb_notifier_list, | 838 | fb_notifier_call_chain(evnt, &event); |
841 | evnt, &event); | ||
842 | } | 839 | } |
843 | } | 840 | } |
844 | } | 841 | } |
@@ -861,8 +858,7 @@ fb_blank(struct fb_info *info, int blank) | |||
861 | 858 | ||
862 | event.info = info; | 859 | event.info = info; |
863 | event.data = ␣ | 860 | event.data = ␣ |
864 | blocking_notifier_call_chain(&fb_notifier_list, | 861 | fb_notifier_call_chain(FB_EVENT_BLANK, &event); |
865 | FB_EVENT_BLANK, &event); | ||
866 | } | 862 | } |
867 | 863 | ||
868 | return ret; | 864 | return ret; |
@@ -933,8 +929,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
933 | con2fb.framebuffer = -1; | 929 | con2fb.framebuffer = -1; |
934 | event.info = info; | 930 | event.info = info; |
935 | event.data = &con2fb; | 931 | event.data = &con2fb; |
936 | blocking_notifier_call_chain(&fb_notifier_list, | 932 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); |
937 | FB_EVENT_GET_CONSOLE_MAP, &event); | ||
938 | return copy_to_user(argp, &con2fb, | 933 | return copy_to_user(argp, &con2fb, |
939 | sizeof(con2fb)) ? -EFAULT : 0; | 934 | sizeof(con2fb)) ? -EFAULT : 0; |
940 | case FBIOPUT_CON2FBMAP: | 935 | case FBIOPUT_CON2FBMAP: |
@@ -952,9 +947,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
952 | return -EINVAL; | 947 | return -EINVAL; |
953 | event.info = info; | 948 | event.info = info; |
954 | event.data = &con2fb; | 949 | event.data = &con2fb; |
955 | return blocking_notifier_call_chain(&fb_notifier_list, | 950 | return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, |
956 | FB_EVENT_SET_CONSOLE_MAP, | 951 | &event); |
957 | &event); | ||
958 | case FBIOBLANK: | 952 | case FBIOBLANK: |
959 | acquire_console_sem(); | 953 | acquire_console_sem(); |
960 | info->flags |= FBINFO_MISC_USEREVENT; | 954 | info->flags |= FBINFO_MISC_USEREVENT; |
@@ -1330,8 +1324,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1330 | registered_fb[i] = fb_info; | 1324 | registered_fb[i] = fb_info; |
1331 | 1325 | ||
1332 | event.info = fb_info; | 1326 | event.info = fb_info; |
1333 | blocking_notifier_call_chain(&fb_notifier_list, | 1327 | fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); |
1334 | FB_EVENT_FB_REGISTERED, &event); | ||
1335 | return 0; | 1328 | return 0; |
1336 | } | 1329 | } |
1337 | 1330 | ||
@@ -1365,30 +1358,11 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1365 | fb_cleanup_class_device(fb_info); | 1358 | fb_cleanup_class_device(fb_info); |
1366 | class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); | 1359 | class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); |
1367 | event.info = fb_info; | 1360 | event.info = fb_info; |
1368 | blocking_notifier_call_chain(&fb_notifier_list, | 1361 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); |
1369 | FB_EVENT_FB_UNREGISTERED, &event); | ||
1370 | return 0; | 1362 | return 0; |
1371 | } | 1363 | } |
1372 | 1364 | ||
1373 | /** | 1365 | /** |
1374 | * fb_register_client - register a client notifier | ||
1375 | * @nb: notifier block to callback on events | ||
1376 | */ | ||
1377 | int fb_register_client(struct notifier_block *nb) | ||
1378 | { | ||
1379 | return blocking_notifier_chain_register(&fb_notifier_list, nb); | ||
1380 | } | ||
1381 | |||
1382 | /** | ||
1383 | * fb_unregister_client - unregister a client notifier | ||
1384 | * @nb: notifier block to callback on events | ||
1385 | */ | ||
1386 | int fb_unregister_client(struct notifier_block *nb) | ||
1387 | { | ||
1388 | return blocking_notifier_chain_unregister(&fb_notifier_list, nb); | ||
1389 | } | ||
1390 | |||
1391 | /** | ||
1392 | * fb_set_suspend - low level driver signals suspend | 1366 | * fb_set_suspend - low level driver signals suspend |
1393 | * @info: framebuffer affected | 1367 | * @info: framebuffer affected |
1394 | * @state: 0 = resuming, !=0 = suspending | 1368 | * @state: 0 = resuming, !=0 = suspending |
@@ -1403,13 +1377,11 @@ void fb_set_suspend(struct fb_info *info, int state) | |||
1403 | 1377 | ||
1404 | event.info = info; | 1378 | event.info = info; |
1405 | if (state) { | 1379 | if (state) { |
1406 | blocking_notifier_call_chain(&fb_notifier_list, | 1380 | fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); |
1407 | FB_EVENT_SUSPEND, &event); | ||
1408 | info->state = FBINFO_STATE_SUSPENDED; | 1381 | info->state = FBINFO_STATE_SUSPENDED; |
1409 | } else { | 1382 | } else { |
1410 | info->state = FBINFO_STATE_RUNNING; | 1383 | info->state = FBINFO_STATE_RUNNING; |
1411 | blocking_notifier_call_chain(&fb_notifier_list, | 1384 | fb_notifier_call_chain(FB_EVENT_RESUME, &event); |
1412 | FB_EVENT_RESUME, &event); | ||
1413 | } | 1385 | } |
1414 | } | 1386 | } |
1415 | 1387 | ||
@@ -1480,9 +1452,7 @@ int fb_new_modelist(struct fb_info *info) | |||
1480 | 1452 | ||
1481 | if (!list_empty(&info->modelist)) { | 1453 | if (!list_empty(&info->modelist)) { |
1482 | event.info = info; | 1454 | event.info = info; |
1483 | err = blocking_notifier_call_chain(&fb_notifier_list, | 1455 | err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); |
1484 | FB_EVENT_NEW_MODELIST, | ||
1485 | &event); | ||
1486 | } | 1456 | } |
1487 | 1457 | ||
1488 | return err; | 1458 | return err; |
@@ -1594,8 +1564,6 @@ EXPORT_SYMBOL(fb_blank); | |||
1594 | EXPORT_SYMBOL(fb_pan_display); | 1564 | EXPORT_SYMBOL(fb_pan_display); |
1595 | EXPORT_SYMBOL(fb_get_buffer_offset); | 1565 | EXPORT_SYMBOL(fb_get_buffer_offset); |
1596 | EXPORT_SYMBOL(fb_set_suspend); | 1566 | EXPORT_SYMBOL(fb_set_suspend); |
1597 | EXPORT_SYMBOL(fb_register_client); | ||
1598 | EXPORT_SYMBOL(fb_unregister_client); | ||
1599 | EXPORT_SYMBOL(fb_get_options); | 1567 | EXPORT_SYMBOL(fb_get_options); |
1600 | 1568 | ||
1601 | MODULE_LICENSE("GPL"); | 1569 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 9f2066f0745a..d4f850117874 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -34,10 +34,6 @@ | |||
34 | #include "nv_proto.h" | 34 | #include "nv_proto.h" |
35 | #include "nv_dma.h" | 35 | #include "nv_dma.h" |
36 | 36 | ||
37 | #ifndef CONFIG_PCI /* sanity check */ | ||
38 | #error This driver requires PCI support. | ||
39 | #endif | ||
40 | |||
41 | #undef CONFIG_FB_NVIDIA_DEBUG | 37 | #undef CONFIG_FB_NVIDIA_DEBUG |
42 | #ifdef CONFIG_FB_NVIDIA_DEBUG | 38 | #ifdef CONFIG_FB_NVIDIA_DEBUG |
43 | #define NVTRACE printk | 39 | #define NVTRACE printk |
@@ -1303,20 +1299,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, | |||
1303 | 1299 | ||
1304 | nvidia_save_vga(par, &par->SavedReg); | 1300 | nvidia_save_vga(par, &par->SavedReg); |
1305 | 1301 | ||
1302 | pci_set_drvdata(pd, info); | ||
1303 | nvidia_bl_init(par); | ||
1306 | if (register_framebuffer(info) < 0) { | 1304 | if (register_framebuffer(info) < 0) { |
1307 | printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); | 1305 | printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); |
1308 | goto err_out_iounmap_fb; | 1306 | goto err_out_iounmap_fb; |
1309 | } | 1307 | } |
1310 | 1308 | ||
1311 | pci_set_drvdata(pd, info); | ||
1312 | 1309 | ||
1313 | printk(KERN_INFO PFX | 1310 | printk(KERN_INFO PFX |
1314 | "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", | 1311 | "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", |
1315 | info->fix.id, | 1312 | info->fix.id, |
1316 | par->FbMapSize / (1024 * 1024), info->fix.smem_start); | 1313 | par->FbMapSize / (1024 * 1024), info->fix.smem_start); |
1317 | 1314 | ||
1318 | nvidia_bl_init(par); | ||
1319 | |||
1320 | NVTRACE_LEAVE(); | 1315 | NVTRACE_LEAVE(); |
1321 | return 0; | 1316 | return 0; |
1322 | 1317 | ||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c index ce5f3031b99b..0013311e0564 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c | |||
@@ -62,8 +62,6 @@ struct offb_par default_par; | |||
62 | * Interface used by the world | 62 | * Interface used by the world |
63 | */ | 63 | */ |
64 | 64 | ||
65 | int offb_init(void); | ||
66 | |||
67 | static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | 65 | static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, |
68 | u_int transp, struct fb_info *info); | 66 | u_int transp, struct fb_info *info); |
69 | static int offb_blank(int blank, struct fb_info *info); | 67 | static int offb_blank(int blank, struct fb_info *info); |
@@ -72,11 +70,6 @@ static int offb_blank(int blank, struct fb_info *info); | |||
72 | extern boot_infos_t *boot_infos; | 70 | extern boot_infos_t *boot_infos; |
73 | #endif | 71 | #endif |
74 | 72 | ||
75 | static void offb_init_nodriver(struct device_node *); | ||
76 | static void offb_init_fb(const char *name, const char *full_name, | ||
77 | int width, int height, int depth, int pitch, | ||
78 | unsigned long address, struct device_node *dp); | ||
79 | |||
80 | static struct fb_ops offb_ops = { | 73 | static struct fb_ops offb_ops = { |
81 | .owner = THIS_MODULE, | 74 | .owner = THIS_MODULE, |
82 | .fb_setcolreg = offb_setcolreg, | 75 | .fb_setcolreg = offb_setcolreg, |
@@ -229,123 +222,17 @@ static int offb_blank(int blank, struct fb_info *info) | |||
229 | return 0; | 222 | return 0; |
230 | } | 223 | } |
231 | 224 | ||
232 | /* | ||
233 | * Initialisation | ||
234 | */ | ||
235 | 225 | ||
236 | int __init offb_init(void) | 226 | static void __iomem *offb_map_reg(struct device_node *np, int index, |
227 | unsigned long offset, unsigned long size) | ||
237 | { | 228 | { |
238 | struct device_node *dp = NULL, *boot_disp = NULL; | 229 | struct resource r; |
239 | |||
240 | if (fb_get_options("offb", NULL)) | ||
241 | return -ENODEV; | ||
242 | 230 | ||
243 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { | 231 | if (of_address_to_resource(np, index, &r)) |
244 | if (get_property(dp, "linux,opened", NULL) && | 232 | return 0; |
245 | get_property(dp, "linux,boot-display", NULL)) { | 233 | if ((r.start + offset + size) > r.end) |
246 | boot_disp = dp; | 234 | return 0; |
247 | offb_init_nodriver(dp); | 235 | return ioremap(r.start + offset, size); |
248 | } | ||
249 | } | ||
250 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { | ||
251 | if (get_property(dp, "linux,opened", NULL) && | ||
252 | dp != boot_disp) | ||
253 | offb_init_nodriver(dp); | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | |||
260 | static void __init offb_init_nodriver(struct device_node *dp) | ||
261 | { | ||
262 | unsigned int len; | ||
263 | int i, width = 640, height = 480, depth = 8, pitch = 640; | ||
264 | unsigned int flags, rsize, addr_prop = 0; | ||
265 | unsigned long max_size = 0; | ||
266 | u64 rstart, address = OF_BAD_ADDR; | ||
267 | u32 *pp, *addrp, *up; | ||
268 | u64 asize; | ||
269 | |||
270 | pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); | ||
271 | if (pp == NULL) | ||
272 | pp = (u32 *)get_property(dp, "depth", &len); | ||
273 | if (pp && len == sizeof(u32)) | ||
274 | depth = *pp; | ||
275 | |||
276 | pp = (u32 *)get_property(dp, "linux,bootx-width", &len); | ||
277 | if (pp == NULL) | ||
278 | pp = (u32 *)get_property(dp, "width", &len); | ||
279 | if (pp && len == sizeof(u32)) | ||
280 | width = *pp; | ||
281 | |||
282 | pp = (u32 *)get_property(dp, "linux,bootx-height", &len); | ||
283 | if (pp == NULL) | ||
284 | pp = (u32 *)get_property(dp, "height", &len); | ||
285 | if (pp && len == sizeof(u32)) | ||
286 | height = *pp; | ||
287 | |||
288 | pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); | ||
289 | if (pp == NULL) | ||
290 | pp = (u32 *)get_property(dp, "linebytes", &len); | ||
291 | if (pp && len == sizeof(u32)) | ||
292 | pitch = *pp; | ||
293 | else | ||
294 | pitch = width * ((depth + 7) / 8); | ||
295 | |||
296 | rsize = (unsigned long)pitch * (unsigned long)height; | ||
297 | |||
298 | /* Ok, now we try to figure out the address of the framebuffer. | ||
299 | * | ||
300 | * Unfortunately, Open Firmware doesn't provide a standard way to do | ||
301 | * so. All we can do is a dodgy heuristic that happens to work in | ||
302 | * practice. On most machines, the "address" property contains what | ||
303 | * we need, though not on Matrox cards found in IBM machines. What I've | ||
304 | * found that appears to give good results is to go through the PCI | ||
305 | * ranges and pick one that is both big enough and if possible encloses | ||
306 | * the "address" property. If none match, we pick the biggest | ||
307 | */ | ||
308 | up = (u32 *)get_property(dp, "linux,bootx-addr", &len); | ||
309 | if (up == NULL) | ||
310 | up = (u32 *)get_property(dp, "address", &len); | ||
311 | if (up && len == sizeof(u32)) | ||
312 | addr_prop = *up; | ||
313 | |||
314 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) | ||
315 | != NULL; i++) { | ||
316 | int match_addrp = 0; | ||
317 | |||
318 | if (!(flags & IORESOURCE_MEM)) | ||
319 | continue; | ||
320 | if (asize < rsize) | ||
321 | continue; | ||
322 | rstart = of_translate_address(dp, addrp); | ||
323 | if (rstart == OF_BAD_ADDR) | ||
324 | continue; | ||
325 | if (addr_prop && (rstart <= addr_prop) && | ||
326 | ((rstart + asize) >= (addr_prop + rsize))) | ||
327 | match_addrp = 1; | ||
328 | if (match_addrp) { | ||
329 | address = addr_prop; | ||
330 | break; | ||
331 | } | ||
332 | if (rsize > max_size) { | ||
333 | max_size = rsize; | ||
334 | address = OF_BAD_ADDR; | ||
335 | } | ||
336 | |||
337 | if (address == OF_BAD_ADDR) | ||
338 | address = rstart; | ||
339 | } | ||
340 | if (address == OF_BAD_ADDR && addr_prop) | ||
341 | address = (u64)addr_prop; | ||
342 | if (address != OF_BAD_ADDR) { | ||
343 | /* kludge for valkyrie */ | ||
344 | if (strcmp(dp->name, "valkyrie") == 0) | ||
345 | address += 0x1000; | ||
346 | offb_init_fb(dp->name, dp->full_name, width, height, depth, | ||
347 | pitch, address, dp); | ||
348 | } | ||
349 | } | 236 | } |
350 | 237 | ||
351 | static void __init offb_init_fb(const char *name, const char *full_name, | 238 | static void __init offb_init_fb(const char *name, const char *full_name, |
@@ -402,45 +289,39 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
402 | 289 | ||
403 | par->cmap_type = cmap_unknown; | 290 | par->cmap_type = cmap_unknown; |
404 | if (depth == 8) { | 291 | if (depth == 8) { |
405 | |||
406 | /* Palette hacks disabled for now */ | 292 | /* Palette hacks disabled for now */ |
407 | #if 0 | ||
408 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { | 293 | if (dp && !strncmp(name, "ATY,Rage128", 11)) { |
409 | unsigned long regbase = dp->addrs[2].address; | 294 | par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); |
410 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 295 | if (par->cmap_adr) |
411 | par->cmap_type = cmap_r128; | 296 | par->cmap_type = cmap_r128; |
412 | } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) | 297 | } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) |
413 | || !strncmp(name, "ATY,RageM3p12A", 14))) { | 298 | || !strncmp(name, "ATY,RageM3p12A", 14))) { |
414 | unsigned long regbase = | 299 | par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); |
415 | dp->parent->addrs[2].address; | 300 | if (par->cmap_adr) |
416 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 301 | par->cmap_type = cmap_M3A; |
417 | par->cmap_type = cmap_M3A; | ||
418 | } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { | 302 | } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { |
419 | unsigned long regbase = | 303 | par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); |
420 | dp->parent->addrs[2].address; | 304 | if (par->cmap_adr) |
421 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 305 | par->cmap_type = cmap_M3B; |
422 | par->cmap_type = cmap_M3B; | ||
423 | } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { | 306 | } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { |
424 | unsigned long regbase = dp->addrs[1].address; | 307 | par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff); |
425 | par->cmap_adr = ioremap(regbase, 0x1FFF); | 308 | if (par->cmap_adr) |
426 | par->cmap_type = cmap_radeon; | 309 | par->cmap_type = cmap_radeon; |
427 | } else if (!strncmp(name, "ATY,", 4)) { | 310 | } else if (!strncmp(name, "ATY,", 4)) { |
428 | unsigned long base = address & 0xff000000UL; | 311 | unsigned long base = address & 0xff000000UL; |
429 | par->cmap_adr = | 312 | par->cmap_adr = |
430 | ioremap(base + 0x7ff000, 0x1000) + 0xcc0; | 313 | ioremap(base + 0x7ff000, 0x1000) + 0xcc0; |
431 | par->cmap_data = par->cmap_adr + 1; | 314 | par->cmap_data = par->cmap_adr + 1; |
432 | par->cmap_type = cmap_m64; | 315 | par->cmap_type = cmap_m64; |
433 | } else if (device_is_compatible(dp, "pci1014,b7")) { | 316 | } else if (dp && device_is_compatible(dp, "pci1014,b7")) { |
434 | unsigned long regbase = dp->addrs[0].address; | 317 | par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); |
435 | par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); | 318 | if (par->cmap_adr) |
436 | par->cmap_type = cmap_gxt2000; | 319 | par->cmap_type = cmap_gxt2000; |
437 | } | 320 | } |
438 | #endif | 321 | fix->visual = (par->cmap_type != cmap_unknown) ? |
439 | fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR | 322 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; |
440 | : FB_VISUAL_STATIC_PSEUDOCOLOR; | ||
441 | } else | 323 | } else |
442 | fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR | 324 | fix->visual = FB_VISUAL_TRUECOLOR; |
443 | : */ FB_VISUAL_TRUECOLOR; | ||
444 | 325 | ||
445 | var->xoffset = var->yoffset = 0; | 326 | var->xoffset = var->yoffset = 0; |
446 | switch (depth) { | 327 | switch (depth) { |
@@ -520,5 +401,139 @@ static void __init offb_init_fb(const char *name, const char *full_name, | |||
520 | info->node, full_name); | 401 | info->node, full_name); |
521 | } | 402 | } |
522 | 403 | ||
404 | |||
405 | static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) | ||
406 | { | ||
407 | unsigned int len; | ||
408 | int i, width = 640, height = 480, depth = 8, pitch = 640; | ||
409 | unsigned int flags, rsize, addr_prop = 0; | ||
410 | unsigned long max_size = 0; | ||
411 | u64 rstart, address = OF_BAD_ADDR; | ||
412 | u32 *pp, *addrp, *up; | ||
413 | u64 asize; | ||
414 | |||
415 | pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); | ||
416 | if (pp == NULL) | ||
417 | pp = (u32 *)get_property(dp, "depth", &len); | ||
418 | if (pp && len == sizeof(u32)) | ||
419 | depth = *pp; | ||
420 | |||
421 | pp = (u32 *)get_property(dp, "linux,bootx-width", &len); | ||
422 | if (pp == NULL) | ||
423 | pp = (u32 *)get_property(dp, "width", &len); | ||
424 | if (pp && len == sizeof(u32)) | ||
425 | width = *pp; | ||
426 | |||
427 | pp = (u32 *)get_property(dp, "linux,bootx-height", &len); | ||
428 | if (pp == NULL) | ||
429 | pp = (u32 *)get_property(dp, "height", &len); | ||
430 | if (pp && len == sizeof(u32)) | ||
431 | height = *pp; | ||
432 | |||
433 | pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); | ||
434 | if (pp == NULL) | ||
435 | pp = (u32 *)get_property(dp, "linebytes", &len); | ||
436 | if (pp && len == sizeof(u32)) | ||
437 | pitch = *pp; | ||
438 | else | ||
439 | pitch = width * ((depth + 7) / 8); | ||
440 | |||
441 | rsize = (unsigned long)pitch * (unsigned long)height; | ||
442 | |||
443 | /* Ok, now we try to figure out the address of the framebuffer. | ||
444 | * | ||
445 | * Unfortunately, Open Firmware doesn't provide a standard way to do | ||
446 | * so. All we can do is a dodgy heuristic that happens to work in | ||
447 | * practice. On most machines, the "address" property contains what | ||
448 | * we need, though not on Matrox cards found in IBM machines. What I've | ||
449 | * found that appears to give good results is to go through the PCI | ||
450 | * ranges and pick one that is both big enough and if possible encloses | ||
451 | * the "address" property. If none match, we pick the biggest | ||
452 | */ | ||
453 | up = (u32 *)get_property(dp, "linux,bootx-addr", &len); | ||
454 | if (up == NULL) | ||
455 | up = (u32 *)get_property(dp, "address", &len); | ||
456 | if (up && len == sizeof(u32)) | ||
457 | addr_prop = *up; | ||
458 | |||
459 | /* Hack for when BootX is passing us */ | ||
460 | if (no_real_node) | ||
461 | goto skip_addr; | ||
462 | |||
463 | for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) | ||
464 | != NULL; i++) { | ||
465 | int match_addrp = 0; | ||
466 | |||
467 | if (!(flags & IORESOURCE_MEM)) | ||
468 | continue; | ||
469 | if (asize < rsize) | ||
470 | continue; | ||
471 | rstart = of_translate_address(dp, addrp); | ||
472 | if (rstart == OF_BAD_ADDR) | ||
473 | continue; | ||
474 | if (addr_prop && (rstart <= addr_prop) && | ||
475 | ((rstart + asize) >= (addr_prop + rsize))) | ||
476 | match_addrp = 1; | ||
477 | if (match_addrp) { | ||
478 | address = addr_prop; | ||
479 | break; | ||
480 | } | ||
481 | if (rsize > max_size) { | ||
482 | max_size = rsize; | ||
483 | address = OF_BAD_ADDR; | ||
484 | } | ||
485 | |||
486 | if (address == OF_BAD_ADDR) | ||
487 | address = rstart; | ||
488 | } | ||
489 | skip_addr: | ||
490 | if (address == OF_BAD_ADDR && addr_prop) | ||
491 | address = (u64)addr_prop; | ||
492 | if (address != OF_BAD_ADDR) { | ||
493 | /* kludge for valkyrie */ | ||
494 | if (strcmp(dp->name, "valkyrie") == 0) | ||
495 | address += 0x1000; | ||
496 | offb_init_fb(no_real_node ? "bootx" : dp->name, | ||
497 | no_real_node ? "display" : dp->full_name, | ||
498 | width, height, depth, pitch, address, | ||
499 | no_real_node ? dp : NULL); | ||
500 | } | ||
501 | } | ||
502 | |||
503 | static int __init offb_init(void) | ||
504 | { | ||
505 | struct device_node *dp = NULL, *boot_disp = NULL; | ||
506 | |||
507 | if (fb_get_options("offb", NULL)) | ||
508 | return -ENODEV; | ||
509 | |||
510 | /* Check if we have a MacOS display without a node spec */ | ||
511 | if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) { | ||
512 | /* The old code tried to work out which node was the MacOS | ||
513 | * display based on the address. I'm dropping that since the | ||
514 | * lack of a node spec only happens with old BootX versions | ||
515 | * (users can update) and with this code, they'll still get | ||
516 | * a display (just not the palette hacks). | ||
517 | */ | ||
518 | offb_init_nodriver(of_chosen, 1); | ||
519 | } | ||
520 | |||
521 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { | ||
522 | if (get_property(dp, "linux,opened", NULL) && | ||
523 | get_property(dp, "linux,boot-display", NULL)) { | ||
524 | boot_disp = dp; | ||
525 | offb_init_nodriver(dp, 0); | ||
526 | } | ||
527 | } | ||
528 | for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { | ||
529 | if (get_property(dp, "linux,opened", NULL) && | ||
530 | dp != boot_disp) | ||
531 | offb_init_nodriver(dp, 0); | ||
532 | } | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | |||
523 | module_init(offb_init); | 538 | module_init(offb_init); |
524 | MODULE_LICENSE("GPL"); | 539 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 33dddbae5420..76fc9d355eb7 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -2132,6 +2132,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd, | |||
2132 | 2132 | ||
2133 | fb_destroy_modedb(info->monspecs.modedb); | 2133 | fb_destroy_modedb(info->monspecs.modedb); |
2134 | info->monspecs.modedb = NULL; | 2134 | info->monspecs.modedb = NULL; |
2135 | |||
2136 | pci_set_drvdata(pd, info); | ||
2137 | riva_bl_init(info->par); | ||
2135 | ret = register_framebuffer(info); | 2138 | ret = register_framebuffer(info); |
2136 | if (ret < 0) { | 2139 | if (ret < 0) { |
2137 | printk(KERN_ERR PFX | 2140 | printk(KERN_ERR PFX |
@@ -2139,8 +2142,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, | |||
2139 | goto err_iounmap_screen_base; | 2142 | goto err_iounmap_screen_base; |
2140 | } | 2143 | } |
2141 | 2144 | ||
2142 | pci_set_drvdata(pd, info); | ||
2143 | |||
2144 | printk(KERN_INFO PFX | 2145 | printk(KERN_INFO PFX |
2145 | "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", | 2146 | "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", |
2146 | info->fix.id, | 2147 | info->fix.id, |
@@ -2148,8 +2149,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, | |||
2148 | info->fix.smem_len / (1024 * 1024), | 2149 | info->fix.smem_len / (1024 * 1024), |
2149 | info->fix.smem_start); | 2150 | info->fix.smem_start); |
2150 | 2151 | ||
2151 | riva_bl_init(info->par); | ||
2152 | |||
2153 | NVTRACE_LEAVE(); | 2152 | NVTRACE_LEAVE(); |
2154 | return 0; | 2153 | return 0; |
2155 | 2154 | ||