aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-11-30 18:56:59 -0500
committerSteve French <sfrench@us.ibm.com>2005-11-30 18:56:59 -0500
commitd2149b542382bfc206cb28485108f6470c979566 (patch)
tree484fad0d7493a9cfe33202db3687d348c0140f33
parent25741b3e43151bc207dd2b850b0bb157c442682b (diff)
parent346f7dbb17cb7d84317b4410df2e8f7bf2e57f44 (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
-rw-r--r--Documentation/usb/error-codes.txt5
-rw-r--r--drivers/char/drm/drm_context.c5
-rw-r--r--drivers/hwmon/w83792d.c25
-rw-r--r--drivers/usb/atm/cxacru.c3
-rw-r--r--drivers/usb/core/hcd-pci.c3
-rw-r--r--drivers/usb/core/hcd.c15
-rw-r--r--drivers/usb/core/hcd.h7
-rw-r--r--drivers/usb/host/ehci-pci.c46
-rw-r--r--drivers/usb/host/ehci-q.c24
-rw-r--r--drivers/usb/host/ehci-sched.c18
-rw-r--r--drivers/usb/host/ohci-hcd.c6
-rw-r--r--drivers/usb/host/ohci-hub.c24
-rw-r--r--drivers/usb/host/ohci-pci.c27
-rw-r--r--drivers/usb/host/uhci-hcd.c6
-rw-r--r--include/linux/mm.h1
-rw-r--r--mm/memory.c36
16 files changed, 207 insertions, 44 deletions
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index 1e36f1661cd0..867f4c38f356 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -46,8 +46,9 @@ USB-specific:
46 46
47-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable 47-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable
48 in the current interface altsetting. 48 in the current interface altsetting.
49 (b) ISO packet is biger than endpoint maxpacket 49 (b) ISO packet is larger than the endpoint maxpacket.
50 (c) requested data transfer size is invalid (negative) 50 (c) requested data transfer length is invalid: negative
51 or too large for the host controller.
51 52
52-ENOSPC This request would overcommit the usb bandwidth reserved 53-ENOSPC This request would overcommit the usb bandwidth reserved
53 for periodic transfers (interrupt, isochronous). 54 for periodic transfers (interrupt, isochronous).
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index bdd168d88f49..bd958d69a2ac 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -432,7 +432,10 @@ int drm_addctx(struct inode *inode, struct file *filp,
432 432
433 if (ctx.handle != DRM_KERNEL_CONTEXT) { 433 if (ctx.handle != DRM_KERNEL_CONTEXT) {
434 if (dev->driver->context_ctor) 434 if (dev->driver->context_ctor)
435 dev->driver->context_ctor(dev, ctx.handle); 435 if (!dev->driver->context_ctor(dev, ctx.handle)) {
436 DRM_DEBUG( "Running out of ctxs or memory.\n");
437 return -ENOMEM;
438 }
436 } 439 }
437 440
438 ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST); 441 ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 4be59dbb78c4..1ba072630361 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -193,6 +193,7 @@ static const u8 W83792D_REG_LEVELS[3][4] = {
193 0xE2 } /* (bit3-0) SmartFanII: Fan3 Level 3 */ 193 0xE2 } /* (bit3-0) SmartFanII: Fan3 Level 3 */
194}; 194};
195 195
196#define W83792D_REG_GPIO_EN 0x1A
196#define W83792D_REG_CONFIG 0x40 197#define W83792D_REG_CONFIG 0x40
197#define W83792D_REG_VID_FANDIV 0x47 198#define W83792D_REG_VID_FANDIV 0x47
198#define W83792D_REG_CHIPID 0x49 199#define W83792D_REG_CHIPID 0x49
@@ -257,7 +258,7 @@ DIV_TO_REG(long val)
257{ 258{
258 int i; 259 int i;
259 val = SENSORS_LIMIT(val, 1, 128) >> 1; 260 val = SENSORS_LIMIT(val, 1, 128) >> 1;
260 for (i = 0; i < 6; i++) { 261 for (i = 0; i < 7; i++) {
261 if (val == 0) 262 if (val == 0)
262 break; 263 break;
263 val >>= 1; 264 val >>= 1;
@@ -1282,8 +1283,8 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
1282 w83792d_init_client(new_client); 1283 w83792d_init_client(new_client);
1283 1284
1284 /* A few vars need to be filled upon startup */ 1285 /* A few vars need to be filled upon startup */
1285 for (i = 1; i <= 7; i++) { 1286 for (i = 0; i < 7; i++) {
1286 data->fan_min[i - 1] = w83792d_read_value(new_client, 1287 data->fan_min[i] = w83792d_read_value(new_client,
1287 W83792D_REG_FAN_MIN[i]); 1288 W83792D_REG_FAN_MIN[i]);
1288 } 1289 }
1289 1290
@@ -1306,10 +1307,20 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
1306 device_create_file_fan(new_client, 1); 1307 device_create_file_fan(new_client, 1);
1307 device_create_file_fan(new_client, 2); 1308 device_create_file_fan(new_client, 2);
1308 device_create_file_fan(new_client, 3); 1309 device_create_file_fan(new_client, 3);
1309 device_create_file_fan(new_client, 4); 1310
1310 device_create_file_fan(new_client, 5); 1311 /* Read GPIO enable register to check if pins for fan 4,5 are used as
1311 device_create_file_fan(new_client, 6); 1312 GPIO */
1312 device_create_file_fan(new_client, 7); 1313 val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN);
1314 if (!(val1 & 0x40))
1315 device_create_file_fan(new_client, 4);
1316 if (!(val1 & 0x20))
1317 device_create_file_fan(new_client, 5);
1318
1319 val1 = w83792d_read_value(new_client, W83792D_REG_PIN);
1320 if (val1 & 0x40)
1321 device_create_file_fan(new_client, 6);
1322 if (val1 & 0x04)
1323 device_create_file_fan(new_client, 7);
1313 1324
1314 device_create_file_temp1(new_client); /* Temp1 */ 1325 device_create_file_temp1(new_client); /* Temp1 */
1315 device_create_file_temp_add(new_client, 2); /* Temp2 */ 1326 device_create_file_temp_add(new_client, 2); /* Temp2 */
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 79861ee12a29..9d59dc62e6d2 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -787,6 +787,9 @@ static const struct usb_device_id cxacru_usb_ids[] = {
787 { /* V = Conexant P = ADSL modem (Hasbani project) */ 787 { /* V = Conexant P = ADSL modem (Hasbani project) */
788 USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00 788 USB_DEVICE(0x0572, 0xcb00), .driver_info = (unsigned long) &cxacru_cb00
789 }, 789 },
790 { /* V = Conexant P = ADSL modem (Well PTI-800 */
791 USB_DEVICE(0x0572, 0xcb02), .driver_info = (unsigned long) &cxacru_cb00
792 },
790 { /* V = Conexant P = ADSL modem */ 793 { /* V = Conexant P = ADSL modem */
791 USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00 794 USB_DEVICE(0x0572, 0xcb01), .driver_info = (unsigned long) &cxacru_cb00
792 }, 795 },
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 5131d88e8c5b..29b5b2a6e183 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -219,6 +219,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
219 goto done; 219 goto done;
220 } 220 }
221 } 221 }
222 synchronize_irq(dev->irq);
222 223
223 /* FIXME until the generic PM interfaces change a lot more, this 224 /* FIXME until the generic PM interfaces change a lot more, this
224 * can't use PCI D1 and D2 states. For example, the confusion 225 * can't use PCI D1 and D2 states. For example, the confusion
@@ -392,7 +393,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
392 393
393 dev->dev.power.power_state = PMSG_ON; 394 dev->dev.power.power_state = PMSG_ON;
394 395
395 hcd->saw_irq = 0; 396 clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
396 397
397 if (hcd->driver->resume) { 398 if (hcd->driver->resume) {
398 retval = hcd->driver->resume(hcd); 399 retval = hcd->driver->resume(hcd);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5e5f65a475ab..da24c31ee00d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1315,11 +1315,12 @@ static int hcd_unlink_urb (struct urb *urb, int status)
1315 * finish unlinking the initial failed usb_set_address() 1315 * finish unlinking the initial failed usb_set_address()
1316 * or device descriptor fetch. 1316 * or device descriptor fetch.
1317 */ 1317 */
1318 if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) { 1318 if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags)
1319 && hcd->self.root_hub != urb->dev) {
1319 dev_warn (hcd->self.controller, "Unlink after no-IRQ? " 1320 dev_warn (hcd->self.controller, "Unlink after no-IRQ? "
1320 "Controller is probably using the wrong IRQ." 1321 "Controller is probably using the wrong IRQ."
1321 "\n"); 1322 "\n");
1322 hcd->saw_irq = 1; 1323 set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
1323 } 1324 }
1324 1325
1325 urb->status = status; 1326 urb->status = status;
@@ -1649,13 +1650,15 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
1649 struct usb_hcd *hcd = __hcd; 1650 struct usb_hcd *hcd = __hcd;
1650 int start = hcd->state; 1651 int start = hcd->state;
1651 1652
1652 if (start == HC_STATE_HALT) 1653 if (unlikely(start == HC_STATE_HALT ||
1654 !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
1653 return IRQ_NONE; 1655 return IRQ_NONE;
1654 if (hcd->driver->irq (hcd, r) == IRQ_NONE) 1656 if (hcd->driver->irq (hcd, r) == IRQ_NONE)
1655 return IRQ_NONE; 1657 return IRQ_NONE;
1656 1658
1657 hcd->saw_irq = 1; 1659 set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
1658 if (hcd->state == HC_STATE_HALT) 1660
1661 if (unlikely(hcd->state == HC_STATE_HALT))
1659 usb_hc_died (hcd); 1662 usb_hc_died (hcd);
1660 return IRQ_HANDLED; 1663 return IRQ_HANDLED;
1661} 1664}
@@ -1768,6 +1771,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
1768 1771
1769 dev_info(hcd->self.controller, "%s\n", hcd->product_desc); 1772 dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
1770 1773
1774 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
1775
1771 /* till now HC has been in an indeterminate state ... */ 1776 /* till now HC has been in an indeterminate state ... */
1772 if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) { 1777 if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
1773 dev_err(hcd->self.controller, "can't reset\n"); 1778 dev_err(hcd->self.controller, "can't reset\n");
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 24a62a2ff86d..c8a1b350e2cf 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -72,7 +72,12 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
72 * hardware info/state 72 * hardware info/state
73 */ 73 */
74 const struct hc_driver *driver; /* hw-specific hooks */ 74 const struct hc_driver *driver; /* hw-specific hooks */
75 unsigned saw_irq : 1; 75
76 /* Flags that need to be manipulated atomically */
77 unsigned long flags;
78#define HCD_FLAG_HW_ACCESSIBLE 0x00000001
79#define HCD_FLAG_SAW_IRQ 0x00000002
80
76 unsigned can_wakeup:1; /* hw supports wakeup? */ 81 unsigned can_wakeup:1; /* hw supports wakeup? */
77 unsigned remote_wakeup:1;/* sw should use wakeup? */ 82 unsigned remote_wakeup:1;/* sw should use wakeup? */
78 unsigned rh_registered:1;/* is root hub registered? */ 83 unsigned rh_registered:1;/* is root hub registered? */
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 441c26064b44..13f73a836e45 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -121,8 +121,8 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
121 return 0; 121 return 0;
122} 122}
123 123
124/* called by khubd or root hub (re)init threads; leaves HC in halt state */ 124/* called during probe() after chip reset completes */
125static int ehci_pci_reset(struct usb_hcd *hcd) 125static int ehci_pci_setup(struct usb_hcd *hcd)
126{ 126{
127 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 127 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
128 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 128 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
@@ -141,6 +141,11 @@ static int ehci_pci_reset(struct usb_hcd *hcd)
141 if (retval) 141 if (retval)
142 return retval; 142 return retval;
143 143
144 /* data structure init */
145 retval = ehci_init(hcd);
146 if (retval)
147 return retval;
148
144 /* NOTE: only the parts below this line are PCI-specific */ 149 /* NOTE: only the parts below this line are PCI-specific */
145 150
146 switch (pdev->vendor) { 151 switch (pdev->vendor) {
@@ -154,7 +159,8 @@ static int ehci_pci_reset(struct usb_hcd *hcd)
154 /* AMD8111 EHCI doesn't work, according to AMD errata */ 159 /* AMD8111 EHCI doesn't work, according to AMD errata */
155 if (pdev->device == 0x7463) { 160 if (pdev->device == 0x7463) {
156 ehci_info(ehci, "ignoring AMD8111 (errata)\n"); 161 ehci_info(ehci, "ignoring AMD8111 (errata)\n");
157 return -EIO; 162 retval = -EIO;
163 goto done;
158 } 164 }
159 break; 165 break;
160 case PCI_VENDOR_ID_NVIDIA: 166 case PCI_VENDOR_ID_NVIDIA:
@@ -207,9 +213,8 @@ static int ehci_pci_reset(struct usb_hcd *hcd)
207 /* REVISIT: per-port wake capability (PCI 0x62) currently unused */ 213 /* REVISIT: per-port wake capability (PCI 0x62) currently unused */
208 214
209 retval = ehci_pci_reinit(ehci, pdev); 215 retval = ehci_pci_reinit(ehci, pdev);
210 216done:
211 /* finish init */ 217 return retval;
212 return ehci_init(hcd);
213} 218}
214 219
215/*-------------------------------------------------------------------------*/ 220/*-------------------------------------------------------------------------*/
@@ -228,14 +233,36 @@ static int ehci_pci_reset(struct usb_hcd *hcd)
228static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) 233static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
229{ 234{
230 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 235 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
236 unsigned long flags;
237 int rc = 0;
231 238
232 if (time_before(jiffies, ehci->next_statechange)) 239 if (time_before(jiffies, ehci->next_statechange))
233 msleep(10); 240 msleep(10);
234 241
242 /* Root hub was already suspended. Disable irq emission and
243 * mark HW unaccessible, bail out if RH has been resumed. Use
244 * the spinlock to properly synchronize with possible pending
245 * RH suspend or resume activity.
246 *
247 * This is still racy as hcd->state is manipulated outside of
248 * any locks =P But that will be a different fix.
249 */
250 spin_lock_irqsave (&ehci->lock, flags);
251 if (hcd->state != HC_STATE_SUSPENDED) {
252 rc = -EINVAL;
253 goto bail;
254 }
255 writel (0, &ehci->regs->intr_enable);
256 (void)readl(&ehci->regs->intr_enable);
257
258 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
259 bail:
260 spin_unlock_irqrestore (&ehci->lock, flags);
261
235 // could save FLADJ in case of Vaux power loss 262 // could save FLADJ in case of Vaux power loss
236 // ... we'd only use it to handle clock skew 263 // ... we'd only use it to handle clock skew
237 264
238 return 0; 265 return rc;
239} 266}
240 267
241static int ehci_pci_resume(struct usb_hcd *hcd) 268static int ehci_pci_resume(struct usb_hcd *hcd)
@@ -251,6 +278,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd)
251 if (time_before(jiffies, ehci->next_statechange)) 278 if (time_before(jiffies, ehci->next_statechange))
252 msleep(100); 279 msleep(100);
253 280
281 /* Mark hardware accessible again as we are out of D3 state by now */
282 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
283
254 /* If CF is clear, we lost PCI Vaux power and need to restart. */ 284 /* If CF is clear, we lost PCI Vaux power and need to restart. */
255 if (readl(&ehci->regs->configured_flag) != FLAG_CF) 285 if (readl(&ehci->regs->configured_flag) != FLAG_CF)
256 goto restart; 286 goto restart;
@@ -319,7 +349,7 @@ static const struct hc_driver ehci_pci_hc_driver = {
319 /* 349 /*
320 * basic lifecycle operations 350 * basic lifecycle operations
321 */ 351 */
322 .reset = ehci_pci_reset, 352 .reset = ehci_pci_setup,
323 .start = ehci_run, 353 .start = ehci_run,
324#ifdef CONFIG_PM 354#ifdef CONFIG_PM
325 .suspend = ehci_pci_suspend, 355 .suspend = ehci_pci_suspend,
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 5bb872c3496d..bf03ec0d8ee2 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -912,6 +912,7 @@ submit_async (
912 int epnum; 912 int epnum;
913 unsigned long flags; 913 unsigned long flags;
914 struct ehci_qh *qh = NULL; 914 struct ehci_qh *qh = NULL;
915 int rc = 0;
915 916
916 qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); 917 qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
917 epnum = ep->desc.bEndpointAddress; 918 epnum = ep->desc.bEndpointAddress;
@@ -926,21 +927,28 @@ submit_async (
926#endif 927#endif
927 928
928 spin_lock_irqsave (&ehci->lock, flags); 929 spin_lock_irqsave (&ehci->lock, flags);
930 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
931 &ehci_to_hcd(ehci)->flags))) {
932 rc = -ESHUTDOWN;
933 goto done;
934 }
935
929 qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); 936 qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
937 if (unlikely(qh == NULL)) {
938 rc = -ENOMEM;
939 goto done;
940 }
930 941
931 /* Control/bulk operations through TTs don't need scheduling, 942 /* Control/bulk operations through TTs don't need scheduling,
932 * the HC and TT handle it when the TT has a buffer ready. 943 * the HC and TT handle it when the TT has a buffer ready.
933 */ 944 */
934 if (likely (qh != NULL)) { 945 if (likely (qh->qh_state == QH_STATE_IDLE))
935 if (likely (qh->qh_state == QH_STATE_IDLE)) 946 qh_link_async (ehci, qh_get (qh));
936 qh_link_async (ehci, qh_get (qh)); 947 done:
937 }
938 spin_unlock_irqrestore (&ehci->lock, flags); 948 spin_unlock_irqrestore (&ehci->lock, flags);
939 if (unlikely (qh == NULL)) { 949 if (unlikely (qh == NULL))
940 qtd_list_free (ehci, urb, qtd_list); 950 qtd_list_free (ehci, urb, qtd_list);
941 return -ENOMEM; 951 return rc;
942 }
943 return 0;
944} 952}
945 953
946/*-------------------------------------------------------------------------*/ 954/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index f0c8aa1ccd5d..57e77374d228 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -602,6 +602,12 @@ static int intr_submit (
602 602
603 spin_lock_irqsave (&ehci->lock, flags); 603 spin_lock_irqsave (&ehci->lock, flags);
604 604
605 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
606 &ehci_to_hcd(ehci)->flags))) {
607 status = -ESHUTDOWN;
608 goto done;
609 }
610
605 /* get qh and force any scheduling errors */ 611 /* get qh and force any scheduling errors */
606 INIT_LIST_HEAD (&empty); 612 INIT_LIST_HEAD (&empty);
607 qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv); 613 qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
@@ -1456,7 +1462,11 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
1456 1462
1457 /* schedule ... need to lock */ 1463 /* schedule ... need to lock */
1458 spin_lock_irqsave (&ehci->lock, flags); 1464 spin_lock_irqsave (&ehci->lock, flags);
1459 status = iso_stream_schedule (ehci, urb, stream); 1465 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
1466 &ehci_to_hcd(ehci)->flags)))
1467 status = -ESHUTDOWN;
1468 else
1469 status = iso_stream_schedule (ehci, urb, stream);
1460 if (likely (status == 0)) 1470 if (likely (status == 0))
1461 itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); 1471 itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
1462 spin_unlock_irqrestore (&ehci->lock, flags); 1472 spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1815,7 +1825,11 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
1815 1825
1816 /* schedule ... need to lock */ 1826 /* schedule ... need to lock */
1817 spin_lock_irqsave (&ehci->lock, flags); 1827 spin_lock_irqsave (&ehci->lock, flags);
1818 status = iso_stream_schedule (ehci, urb, stream); 1828 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
1829 &ehci_to_hcd(ehci)->flags)))
1830 status = -ESHUTDOWN;
1831 else
1832 status = iso_stream_schedule (ehci, urb, stream);
1819 if (status == 0) 1833 if (status == 0)
1820 sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); 1834 sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
1821 spin_unlock_irqrestore (&ehci->lock, flags); 1835 spin_unlock_irqrestore (&ehci->lock, flags);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5c0c6c8a7a82..bf1d9abc07ac 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -115,7 +115,7 @@
115 115
116/*-------------------------------------------------------------------------*/ 116/*-------------------------------------------------------------------------*/
117 117
118// #define OHCI_VERBOSE_DEBUG /* not always helpful */ 118#undef OHCI_VERBOSE_DEBUG /* not always helpful */
119 119
120/* For initializing controller (mask in an HCFS mode too) */ 120/* For initializing controller (mask in an HCFS mode too) */
121#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR 121#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
@@ -253,6 +253,10 @@ static int ohci_urb_enqueue (
253 spin_lock_irqsave (&ohci->lock, flags); 253 spin_lock_irqsave (&ohci->lock, flags);
254 254
255 /* don't submit to a dead HC */ 255 /* don't submit to a dead HC */
256 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
257 retval = -ENODEV;
258 goto fail;
259 }
256 if (!HC_IS_RUNNING(hcd->state)) { 260 if (!HC_IS_RUNNING(hcd->state)) {
257 retval = -ENODEV; 261 retval = -ENODEV;
258 goto fail; 262 goto fail;
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index e01e77bc324b..72e3b12a1926 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -53,6 +53,11 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
53 53
54 spin_lock_irqsave (&ohci->lock, flags); 54 spin_lock_irqsave (&ohci->lock, flags);
55 55
56 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
57 spin_unlock_irqrestore (&ohci->lock, flags);
58 return -ESHUTDOWN;
59 }
60
56 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); 61 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
57 switch (ohci->hc_control & OHCI_CTRL_HCFS) { 62 switch (ohci->hc_control & OHCI_CTRL_HCFS) {
58 case OHCI_USB_RESUME: 63 case OHCI_USB_RESUME:
@@ -140,11 +145,19 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
140 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 145 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
141 u32 temp, enables; 146 u32 temp, enables;
142 int status = -EINPROGRESS; 147 int status = -EINPROGRESS;
148 unsigned long flags;
143 149
144 if (time_before (jiffies, ohci->next_statechange)) 150 if (time_before (jiffies, ohci->next_statechange))
145 msleep(5); 151 msleep(5);
146 152
147 spin_lock_irq (&ohci->lock); 153 spin_lock_irqsave (&ohci->lock, flags);
154
155 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
156 spin_unlock_irqrestore (&ohci->lock, flags);
157 return -ESHUTDOWN;
158 }
159
160
148 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); 161 ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
149 162
150 if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { 163 if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
@@ -179,7 +192,7 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
179 ohci_dbg (ohci, "lost power\n"); 192 ohci_dbg (ohci, "lost power\n");
180 status = -EBUSY; 193 status = -EBUSY;
181 } 194 }
182 spin_unlock_irq (&ohci->lock); 195 spin_unlock_irqrestore (&ohci->lock, flags);
183 if (status == -EBUSY) { 196 if (status == -EBUSY) {
184 (void) ohci_init (ohci); 197 (void) ohci_init (ohci);
185 return ohci_restart (ohci); 198 return ohci_restart (ohci);
@@ -297,8 +310,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
297 /* handle autosuspended root: finish resuming before 310 /* handle autosuspended root: finish resuming before
298 * letting khubd or root hub timer see state changes. 311 * letting khubd or root hub timer see state changes.
299 */ 312 */
300 if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER 313 if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
301 || !HC_IS_RUNNING(hcd->state)) { 314 || !HC_IS_RUNNING(hcd->state))) {
302 can_suspend = 0; 315 can_suspend = 0;
303 goto done; 316 goto done;
304 } 317 }
@@ -508,6 +521,9 @@ static int ohci_hub_control (
508 u32 temp; 521 u32 temp;
509 int retval = 0; 522 int retval = 0;
510 523
524 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
525 return -ESHUTDOWN;
526
511 switch (typeReq) { 527 switch (typeReq) {
512 case ClearHubFeature: 528 case ClearHubFeature:
513 switch (wValue) { 529 switch (wValue) {
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 5f22e6590cd1..1b09dde068e1 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -105,13 +105,36 @@ ohci_pci_start (struct usb_hcd *hcd)
105 105
106static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) 106static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
107{ 107{
108 /* root hub was already suspended */ 108 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
109 return 0; 109 unsigned long flags;
110 int rc = 0;
111
112 /* Root hub was already suspended. Disable irq emission and
113 * mark HW unaccessible, bail out if RH has been resumed. Use
114 * the spinlock to properly synchronize with possible pending
115 * RH suspend or resume activity.
116 *
117 * This is still racy as hcd->state is manipulated outside of
118 * any locks =P But that will be a different fix.
119 */
120 spin_lock_irqsave (&ohci->lock, flags);
121 if (hcd->state != HC_STATE_SUSPENDED) {
122 rc = -EINVAL;
123 goto bail;
124 }
125 ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
126 (void)ohci_readl(ohci, &ohci->regs->intrdisable);
127 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
128 bail:
129 spin_unlock_irqrestore (&ohci->lock, flags);
130
131 return rc;
110} 132}
111 133
112 134
113static int ohci_pci_resume (struct usb_hcd *hcd) 135static int ohci_pci_resume (struct usb_hcd *hcd)
114{ 136{
137 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
115 usb_hcd_resume_root_hub(hcd); 138 usb_hcd_resume_root_hub(hcd);
116 return 0; 139 return 0;
117} 140}
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index d33ce3982a5f..ed550132db0b 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -717,6 +717,7 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
717 * at the source, so we must turn off PIRQ. 717 * at the source, so we must turn off PIRQ.
718 */ 718 */
719 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); 719 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
720 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
720 uhci->hc_inaccessible = 1; 721 uhci->hc_inaccessible = 1;
721 hcd->poll_rh = 0; 722 hcd->poll_rh = 0;
722 723
@@ -733,6 +734,11 @@ static int uhci_resume(struct usb_hcd *hcd)
733 734
734 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); 735 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
735 736
737 /* We aren't in D3 state anymore, we do that even if dead as I
738 * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0
739 */
740 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
741
736 if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ 742 if (uhci->rh_state == UHCI_RH_RESET) /* Dead */
737 return 0; 743 return 0;
738 spin_lock_irq(&uhci->lock); 744 spin_lock_irq(&uhci->lock);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0e73f1539d08..29f02d8513f6 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -956,6 +956,7 @@ struct page *vmalloc_to_page(void *addr);
956unsigned long vmalloc_to_pfn(void *addr); 956unsigned long vmalloc_to_pfn(void *addr);
957int remap_pfn_range(struct vm_area_struct *, unsigned long addr, 957int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
958 unsigned long pfn, unsigned long size, pgprot_t); 958 unsigned long pfn, unsigned long size, pgprot_t);
959int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *);
959 960
960struct page *follow_page(struct vm_area_struct *, unsigned long address, 961struct page *follow_page(struct vm_area_struct *, unsigned long address,
961 unsigned int foll_flags); 962 unsigned int foll_flags);
diff --git a/mm/memory.c b/mm/memory.c
index 8d10b5540c73..4b4fc3a7ea48 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1172,7 +1172,7 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa
1172 spinlock_t *ptl; 1172 spinlock_t *ptl;
1173 1173
1174 retval = -EINVAL; 1174 retval = -EINVAL;
1175 if (PageAnon(page) || !PageReserved(page)) 1175 if (PageAnon(page))
1176 goto out; 1176 goto out;
1177 retval = -ENOMEM; 1177 retval = -ENOMEM;
1178 flush_dcache_page(page); 1178 flush_dcache_page(page);
@@ -1197,6 +1197,35 @@ out:
1197} 1197}
1198 1198
1199/* 1199/*
1200 * This allows drivers to insert individual pages they've allocated
1201 * into a user vma.
1202 *
1203 * The page has to be a nice clean _individual_ kernel allocation.
1204 * If you allocate a compound page, you need to have marked it as
1205 * such (__GFP_COMP), or manually just split the page up yourself
1206 * (which is mainly an issue of doing "set_page_count(page, 1)" for
1207 * each sub-page, and then freeing them one by one when you free
1208 * them rather than freeing it as a compound page).
1209 *
1210 * NOTE! Traditionally this was done with "remap_pfn_range()" which
1211 * took an arbitrary page protection parameter. This doesn't allow
1212 * that. Your vma protection will have to be set up correctly, which
1213 * means that if you want a shared writable mapping, you'd better
1214 * ask for a shared writable mapping!
1215 *
1216 * The page does not need to be reserved.
1217 */
1218int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page)
1219{
1220 if (addr < vma->vm_start || addr >= vma->vm_end)
1221 return -EFAULT;
1222 if (!page_count(page))
1223 return -EINVAL;
1224 return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot);
1225}
1226EXPORT_SYMBOL_GPL(vm_insert_page);
1227
1228/*
1200 * Somebody does a pfn remapping that doesn't actually work as a vma. 1229 * Somebody does a pfn remapping that doesn't actually work as a vma.
1201 * 1230 *
1202 * Do it as individual pages instead, and warn about it. It's bad form, 1231 * Do it as individual pages instead, and warn about it. It's bad form,
@@ -1225,8 +1254,11 @@ static int incomplete_pfn_remap(struct vm_area_struct *vma,
1225 if (!pfn_valid(pfn)) 1254 if (!pfn_valid(pfn))
1226 return -EINVAL; 1255 return -EINVAL;
1227 1256
1228 retval = 0;
1229 page = pfn_to_page(pfn); 1257 page = pfn_to_page(pfn);
1258 if (!PageReserved(page))
1259 return -EINVAL;
1260
1261 retval = 0;
1230 while (start < end) { 1262 while (start < end) {
1231 retval = insert_page(vma->vm_mm, start, page, prot); 1263 retval = insert_page(vma->vm_mm, start, page, prot);
1232 if (retval < 0) 1264 if (retval < 0)