ia64/linux-2.6.18-xen.hg

view drivers/bluetooth/dtl1_cs.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 *
3 * A driver for Nokia Connectivity Card DTL-1 devices
4 *
5 * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation;
11 *
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
16 *
17 * The initial developer of the original code is David A. Hinds
18 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20 *
21 */
23 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
29 #include <linux/sched.h>
30 #include <linux/delay.h>
31 #include <linux/errno.h>
32 #include <linux/ptrace.h>
33 #include <linux/ioport.h>
34 #include <linux/spinlock.h>
35 #include <linux/moduleparam.h>
37 #include <linux/skbuff.h>
38 #include <linux/string.h>
39 #include <linux/serial.h>
40 #include <linux/serial_reg.h>
41 #include <linux/bitops.h>
42 #include <asm/system.h>
43 #include <asm/io.h>
45 #include <pcmcia/cs_types.h>
46 #include <pcmcia/cs.h>
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/ciscode.h>
49 #include <pcmcia/ds.h>
50 #include <pcmcia/cisreg.h>
52 #include <net/bluetooth/bluetooth.h>
53 #include <net/bluetooth/hci_core.h>
57 /* ======================== Module parameters ======================== */
60 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
61 MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
62 MODULE_LICENSE("GPL");
66 /* ======================== Local structures ======================== */
69 typedef struct dtl1_info_t {
70 struct pcmcia_device *p_dev;
71 dev_node_t node;
73 struct hci_dev *hdev;
75 spinlock_t lock; /* For serializing operations */
77 unsigned long flowmask; /* HCI flow mask */
78 int ri_latch;
80 struct sk_buff_head txq;
81 unsigned long tx_state;
83 unsigned long rx_state;
84 unsigned long rx_count;
85 struct sk_buff *rx_skb;
86 } dtl1_info_t;
89 static int dtl1_config(struct pcmcia_device *link);
90 static void dtl1_release(struct pcmcia_device *link);
92 static void dtl1_detach(struct pcmcia_device *p_dev);
95 /* Transmit states */
96 #define XMIT_SENDING 1
97 #define XMIT_WAKEUP 2
98 #define XMIT_WAITING 8
100 /* Receiver States */
101 #define RECV_WAIT_NSH 0
102 #define RECV_WAIT_DATA 1
105 typedef struct {
106 u8 type;
107 u8 zero;
108 u16 len;
109 } __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
111 #define NSHL 4 /* Nokia Specific Header Length */
115 /* ======================== Interrupt handling ======================== */
118 static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
119 {
120 int actual = 0;
122 /* Tx FIFO should be empty */
123 if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
124 return 0;
126 /* Fill FIFO with current frame */
127 while ((fifo_size-- > 0) && (actual < len)) {
128 /* Transmit next byte */
129 outb(buf[actual], iobase + UART_TX);
130 actual++;
131 }
133 return actual;
134 }
137 static void dtl1_write_wakeup(dtl1_info_t *info)
138 {
139 if (!info) {
140 BT_ERR("Unknown device");
141 return;
142 }
144 if (test_bit(XMIT_WAITING, &(info->tx_state))) {
145 set_bit(XMIT_WAKEUP, &(info->tx_state));
146 return;
147 }
149 if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
150 set_bit(XMIT_WAKEUP, &(info->tx_state));
151 return;
152 }
154 do {
155 register unsigned int iobase = info->p_dev->io.BasePort1;
156 register struct sk_buff *skb;
157 register int len;
159 clear_bit(XMIT_WAKEUP, &(info->tx_state));
161 if (!pcmcia_dev_present(info->p_dev))
162 return;
164 if (!(skb = skb_dequeue(&(info->txq))))
165 break;
167 /* Send frame */
168 len = dtl1_write(iobase, 32, skb->data, skb->len);
170 if (len == skb->len) {
171 set_bit(XMIT_WAITING, &(info->tx_state));
172 kfree_skb(skb);
173 } else {
174 skb_pull(skb, len);
175 skb_queue_head(&(info->txq), skb);
176 }
178 info->hdev->stat.byte_tx += len;
180 } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
182 clear_bit(XMIT_SENDING, &(info->tx_state));
183 }
186 static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
187 {
188 u8 flowmask = *(u8 *)skb->data;
189 int i;
191 printk(KERN_INFO "Bluetooth: Nokia control data =");
192 for (i = 0; i < skb->len; i++) {
193 printk(" %02x", skb->data[i]);
194 }
195 printk("\n");
197 /* transition to active state */
198 if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
199 clear_bit(XMIT_WAITING, &(info->tx_state));
200 dtl1_write_wakeup(info);
201 }
203 info->flowmask = flowmask;
205 kfree_skb(skb);
206 }
209 static void dtl1_receive(dtl1_info_t *info)
210 {
211 unsigned int iobase;
212 nsh_t *nsh;
213 int boguscount = 0;
215 if (!info) {
216 BT_ERR("Unknown device");
217 return;
218 }
220 iobase = info->p_dev->io.BasePort1;
222 do {
223 info->hdev->stat.byte_rx++;
225 /* Allocate packet */
226 if (info->rx_skb == NULL)
227 if (!(info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
228 BT_ERR("Can't allocate mem for new packet");
229 info->rx_state = RECV_WAIT_NSH;
230 info->rx_count = NSHL;
231 return;
232 }
234 *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
235 nsh = (nsh_t *)info->rx_skb->data;
237 info->rx_count--;
239 if (info->rx_count == 0) {
241 switch (info->rx_state) {
242 case RECV_WAIT_NSH:
243 info->rx_state = RECV_WAIT_DATA;
244 info->rx_count = nsh->len + (nsh->len & 0x0001);
245 break;
246 case RECV_WAIT_DATA:
247 bt_cb(info->rx_skb)->pkt_type = nsh->type;
249 /* remove PAD byte if it exists */
250 if (nsh->len & 0x0001) {
251 info->rx_skb->tail--;
252 info->rx_skb->len--;
253 }
255 /* remove NSH */
256 skb_pull(info->rx_skb, NSHL);
258 switch (bt_cb(info->rx_skb)->pkt_type) {
259 case 0x80:
260 /* control data for the Nokia Card */
261 dtl1_control(info, info->rx_skb);
262 break;
263 case 0x82:
264 case 0x83:
265 case 0x84:
266 /* send frame to the HCI layer */
267 info->rx_skb->dev = (void *) info->hdev;
268 bt_cb(info->rx_skb)->pkt_type &= 0x0f;
269 hci_recv_frame(info->rx_skb);
270 break;
271 default:
272 /* unknown packet */
273 BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
274 kfree_skb(info->rx_skb);
275 break;
276 }
278 info->rx_state = RECV_WAIT_NSH;
279 info->rx_count = NSHL;
280 info->rx_skb = NULL;
281 break;
282 }
284 }
286 /* Make sure we don't stay here too long */
287 if (boguscount++ > 32)
288 break;
290 } while (inb(iobase + UART_LSR) & UART_LSR_DR);
291 }
294 static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
295 {
296 dtl1_info_t *info = dev_inst;
297 unsigned int iobase;
298 unsigned char msr;
299 int boguscount = 0;
300 int iir, lsr;
302 if (!info || !info->hdev) {
303 BT_ERR("Call of irq %d for unknown device", irq);
304 return IRQ_NONE;
305 }
307 iobase = info->p_dev->io.BasePort1;
309 spin_lock(&(info->lock));
311 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
312 while (iir) {
314 /* Clear interrupt */
315 lsr = inb(iobase + UART_LSR);
317 switch (iir) {
318 case UART_IIR_RLSI:
319 BT_ERR("RLSI");
320 break;
321 case UART_IIR_RDI:
322 /* Receive interrupt */
323 dtl1_receive(info);
324 break;
325 case UART_IIR_THRI:
326 if (lsr & UART_LSR_THRE) {
327 /* Transmitter ready for data */
328 dtl1_write_wakeup(info);
329 }
330 break;
331 default:
332 BT_ERR("Unhandled IIR=%#x", iir);
333 break;
334 }
336 /* Make sure we don't stay here too long */
337 if (boguscount++ > 100)
338 break;
340 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
342 }
344 msr = inb(iobase + UART_MSR);
346 if (info->ri_latch ^ (msr & UART_MSR_RI)) {
347 info->ri_latch = msr & UART_MSR_RI;
348 clear_bit(XMIT_WAITING, &(info->tx_state));
349 dtl1_write_wakeup(info);
350 }
352 spin_unlock(&(info->lock));
354 return IRQ_HANDLED;
355 }
359 /* ======================== HCI interface ======================== */
362 static int dtl1_hci_open(struct hci_dev *hdev)
363 {
364 set_bit(HCI_RUNNING, &(hdev->flags));
366 return 0;
367 }
370 static int dtl1_hci_flush(struct hci_dev *hdev)
371 {
372 dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
374 /* Drop TX queue */
375 skb_queue_purge(&(info->txq));
377 return 0;
378 }
381 static int dtl1_hci_close(struct hci_dev *hdev)
382 {
383 if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
384 return 0;
386 dtl1_hci_flush(hdev);
388 return 0;
389 }
392 static int dtl1_hci_send_frame(struct sk_buff *skb)
393 {
394 dtl1_info_t *info;
395 struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
396 struct sk_buff *s;
397 nsh_t nsh;
399 if (!hdev) {
400 BT_ERR("Frame for unknown HCI device (hdev=NULL)");
401 return -ENODEV;
402 }
404 info = (dtl1_info_t *)(hdev->driver_data);
406 switch (bt_cb(skb)->pkt_type) {
407 case HCI_COMMAND_PKT:
408 hdev->stat.cmd_tx++;
409 nsh.type = 0x81;
410 break;
411 case HCI_ACLDATA_PKT:
412 hdev->stat.acl_tx++;
413 nsh.type = 0x82;
414 break;
415 case HCI_SCODATA_PKT:
416 hdev->stat.sco_tx++;
417 nsh.type = 0x83;
418 break;
419 };
421 nsh.zero = 0;
422 nsh.len = skb->len;
424 s = bt_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
425 if (!s)
426 return -ENOMEM;
428 skb_reserve(s, NSHL);
429 memcpy(skb_put(s, skb->len), skb->data, skb->len);
430 if (skb->len & 0x0001)
431 *skb_put(s, 1) = 0; /* PAD */
433 /* Prepend skb with Nokia frame header and queue */
434 memcpy(skb_push(s, NSHL), &nsh, NSHL);
435 skb_queue_tail(&(info->txq), s);
437 dtl1_write_wakeup(info);
439 kfree_skb(skb);
441 return 0;
442 }
445 static void dtl1_hci_destruct(struct hci_dev *hdev)
446 {
447 }
450 static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
451 {
452 return -ENOIOCTLCMD;
453 }
457 /* ======================== Card services HCI interaction ======================== */
460 static int dtl1_open(dtl1_info_t *info)
461 {
462 unsigned long flags;
463 unsigned int iobase = info->p_dev->io.BasePort1;
464 struct hci_dev *hdev;
466 spin_lock_init(&(info->lock));
468 skb_queue_head_init(&(info->txq));
470 info->rx_state = RECV_WAIT_NSH;
471 info->rx_count = NSHL;
472 info->rx_skb = NULL;
474 set_bit(XMIT_WAITING, &(info->tx_state));
476 /* Initialize HCI device */
477 hdev = hci_alloc_dev();
478 if (!hdev) {
479 BT_ERR("Can't allocate HCI device");
480 return -ENOMEM;
481 }
483 info->hdev = hdev;
485 hdev->type = HCI_PCCARD;
486 hdev->driver_data = info;
487 SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
489 hdev->open = dtl1_hci_open;
490 hdev->close = dtl1_hci_close;
491 hdev->flush = dtl1_hci_flush;
492 hdev->send = dtl1_hci_send_frame;
493 hdev->destruct = dtl1_hci_destruct;
494 hdev->ioctl = dtl1_hci_ioctl;
496 hdev->owner = THIS_MODULE;
498 spin_lock_irqsave(&(info->lock), flags);
500 /* Reset UART */
501 outb(0, iobase + UART_MCR);
503 /* Turn off interrupts */
504 outb(0, iobase + UART_IER);
506 /* Initialize UART */
507 outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
508 outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
510 info->ri_latch = inb(info->p_dev->io.BasePort1 + UART_MSR) & UART_MSR_RI;
512 /* Turn on interrupts */
513 outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
515 spin_unlock_irqrestore(&(info->lock), flags);
517 /* Timeout before it is safe to send the first HCI packet */
518 msleep(2000);
520 /* Register HCI device */
521 if (hci_register_dev(hdev) < 0) {
522 BT_ERR("Can't register HCI device");
523 info->hdev = NULL;
524 hci_free_dev(hdev);
525 return -ENODEV;
526 }
528 return 0;
529 }
532 static int dtl1_close(dtl1_info_t *info)
533 {
534 unsigned long flags;
535 unsigned int iobase = info->p_dev->io.BasePort1;
536 struct hci_dev *hdev = info->hdev;
538 if (!hdev)
539 return -ENODEV;
541 dtl1_hci_close(hdev);
543 spin_lock_irqsave(&(info->lock), flags);
545 /* Reset UART */
546 outb(0, iobase + UART_MCR);
548 /* Turn off interrupts */
549 outb(0, iobase + UART_IER);
551 spin_unlock_irqrestore(&(info->lock), flags);
553 if (hci_unregister_dev(hdev) < 0)
554 BT_ERR("Can't unregister HCI device %s", hdev->name);
556 hci_free_dev(hdev);
558 return 0;
559 }
561 static int dtl1_probe(struct pcmcia_device *link)
562 {
563 dtl1_info_t *info;
565 /* Create new info device */
566 info = kzalloc(sizeof(*info), GFP_KERNEL);
567 if (!info)
568 return -ENOMEM;
570 info->p_dev = link;
571 link->priv = info;
573 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
574 link->io.NumPorts1 = 8;
575 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
576 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
578 link->irq.Handler = dtl1_interrupt;
579 link->irq.Instance = info;
581 link->conf.Attributes = CONF_ENABLE_IRQ;
582 link->conf.IntType = INT_MEMORY_AND_IO;
584 return dtl1_config(link);
585 }
588 static void dtl1_detach(struct pcmcia_device *link)
589 {
590 dtl1_info_t *info = link->priv;
592 dtl1_release(link);
594 kfree(info);
595 }
597 static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
598 {
599 int i;
601 i = pcmcia_get_tuple_data(handle, tuple);
602 if (i != CS_SUCCESS)
603 return i;
605 return pcmcia_parse_tuple(handle, tuple, parse);
606 }
608 static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
609 {
610 if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS)
611 return CS_NO_MORE_ITEMS;
612 return get_tuple(handle, tuple, parse);
613 }
615 static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
616 {
617 if (pcmcia_get_next_tuple(handle, tuple) != CS_SUCCESS)
618 return CS_NO_MORE_ITEMS;
619 return get_tuple(handle, tuple, parse);
620 }
622 static int dtl1_config(struct pcmcia_device *link)
623 {
624 dtl1_info_t *info = link->priv;
625 tuple_t tuple;
626 u_short buf[256];
627 cisparse_t parse;
628 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
629 int i, last_ret, last_fn;
631 tuple.TupleData = (cisdata_t *)buf;
632 tuple.TupleOffset = 0;
633 tuple.TupleDataMax = 255;
634 tuple.Attributes = 0;
636 /* Get configuration register information */
637 tuple.DesiredTuple = CISTPL_CONFIG;
638 last_ret = first_tuple(link, &tuple, &parse);
639 if (last_ret != CS_SUCCESS) {
640 last_fn = ParseTuple;
641 goto cs_failed;
642 }
643 link->conf.ConfigBase = parse.config.base;
644 link->conf.Present = parse.config.rmask[0];
646 tuple.TupleData = (cisdata_t *)buf;
647 tuple.TupleOffset = 0;
648 tuple.TupleDataMax = 255;
649 tuple.Attributes = 0;
650 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
652 /* Look for a generic full-sized window */
653 link->io.NumPorts1 = 8;
654 i = first_tuple(link, &tuple, &parse);
655 while (i != CS_NO_MORE_ITEMS) {
656 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
657 link->conf.ConfigIndex = cf->index;
658 link->io.BasePort1 = cf->io.win[0].base;
659 link->io.NumPorts1 = cf->io.win[0].len; /*yo */
660 link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
661 i = pcmcia_request_io(link, &link->io);
662 if (i == CS_SUCCESS)
663 break;
664 }
665 i = next_tuple(link, &tuple, &parse);
666 }
668 if (i != CS_SUCCESS) {
669 cs_error(link, RequestIO, i);
670 goto failed;
671 }
673 i = pcmcia_request_irq(link, &link->irq);
674 if (i != CS_SUCCESS) {
675 cs_error(link, RequestIRQ, i);
676 link->irq.AssignedIRQ = 0;
677 }
679 i = pcmcia_request_configuration(link, &link->conf);
680 if (i != CS_SUCCESS) {
681 cs_error(link, RequestConfiguration, i);
682 goto failed;
683 }
685 if (dtl1_open(info) != 0)
686 goto failed;
688 strcpy(info->node.dev_name, info->hdev->name);
689 link->dev_node = &info->node;
691 return 0;
693 cs_failed:
694 cs_error(link, last_fn, last_ret);
696 failed:
697 dtl1_release(link);
698 return -ENODEV;
699 }
702 static void dtl1_release(struct pcmcia_device *link)
703 {
704 dtl1_info_t *info = link->priv;
706 dtl1_close(info);
708 pcmcia_disable_device(link);
709 }
712 static struct pcmcia_device_id dtl1_ids[] = {
713 PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
714 PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
715 PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
716 PCMCIA_DEVICE_NULL
717 };
718 MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
720 static struct pcmcia_driver dtl1_driver = {
721 .owner = THIS_MODULE,
722 .drv = {
723 .name = "dtl1_cs",
724 },
725 .probe = dtl1_probe,
726 .remove = dtl1_detach,
727 .id_table = dtl1_ids,
728 };
730 static int __init init_dtl1_cs(void)
731 {
732 return pcmcia_register_driver(&dtl1_driver);
733 }
736 static void __exit exit_dtl1_cs(void)
737 {
738 pcmcia_unregister_driver(&dtl1_driver);
739 }
741 module_init(init_dtl1_cs);
742 module_exit(exit_dtl1_cs);