ia64/linux-2.6.18-xen.hg

view drivers/net/smc-mca.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 /* smc-mca.c: A SMC Ultra ethernet driver for linux. */
2 /*
3 Most of this driver, except for ultramca_probe is nearly
4 verbatim from smc-ultra.c by Donald Becker. The rest is
5 written and copyright 1996 by David Weis, weisd3458@uni.edu
7 This is a driver for the SMC Ultra and SMC EtherEZ ethercards.
9 This driver uses the cards in the 8390-compatible, shared memory mode.
10 Most of the run-time complexity is handled by the generic code in
11 8390.c.
13 This driver enables the shared memory only when doing the actual data
14 transfers to avoid a bug in early version of the card that corrupted
15 data transferred by a AHA1542.
17 This driver does not support the programmed-I/O data transfer mode of
18 the EtherEZ. That support (if available) is smc-ez.c. Nor does it
19 use the non-8390-compatible "Altego" mode. (No support currently planned.)
21 Changelog:
23 Paul Gortmaker : multiple card support for module users.
24 David Weis : Micro Channel-ized it.
25 Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A
26 Christopher Turcksin : Changed MCA-probe so that multiple adapters are
27 found correctly (Jul 16, 1997)
28 Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997)
29 Tom Sightler : Fixed minor detection bug caused by above merge
30 Tom Sightler : Added support for three more Western Digital
31 MCA-adapters
32 Tom Sightler : Added support for 2.2.x mca_find_unused_adapter
33 Hartmut Schmidt : - Modified parameter detection to handle each
34 card differently depending on a switch-list
35 - 'card_ver' removed from the adapter list
36 - Some minor bug fixes
37 */
39 #include <linux/mca.h>
40 #include <linux/module.h>
41 #include <linux/kernel.h>
42 #include <linux/errno.h>
43 #include <linux/string.h>
44 #include <linux/init.h>
45 #include <linux/netdevice.h>
46 #include <linux/etherdevice.h>
48 #include <asm/io.h>
49 #include <asm/system.h>
51 #include "8390.h"
53 #define DRV_NAME "smc-mca"
55 static int ultramca_open(struct net_device *dev);
56 static void ultramca_reset_8390(struct net_device *dev);
57 static void ultramca_get_8390_hdr(struct net_device *dev,
58 struct e8390_pkt_hdr *hdr,
59 int ring_page);
60 static void ultramca_block_input(struct net_device *dev, int count,
61 struct sk_buff *skb,
62 int ring_offset);
63 static void ultramca_block_output(struct net_device *dev, int count,
64 const unsigned char *buf,
65 const int start_page);
66 static int ultramca_close_card(struct net_device *dev);
68 #define START_PG 0x00 /* First page of TX buffer */
70 #define ULTRA_CMDREG 0 /* Offset to ASIC command register. */
71 #define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */
72 #define ULTRA_MEMENB 0x40 /* Enable the shared memory. */
73 #define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */
74 #define ULTRA_IO_EXTENT 32
75 #define EN0_ERWCNT 0x08 /* Early receive warning count. */
77 #define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0
78 #define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1
79 #define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2
80 #define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3
81 #define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4
82 #define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5
83 #define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6
84 #define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7
86 struct smc_mca_adapters_t {
87 unsigned int id;
88 char *name;
89 };
91 #define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */
93 static int ultra_io[MAX_ULTRAMCA_CARDS];
94 static int ultra_irq[MAX_ULTRAMCA_CARDS];
95 MODULE_LICENSE("GPL");
97 module_param_array(ultra_io, int, NULL, 0);
98 module_param_array(ultra_irq, int, NULL, 0);
99 MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
100 MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
102 static const struct {
103 unsigned int base_addr;
104 } addr_table[] = {
105 { 0x0800 },
106 { 0x1800 },
107 { 0x2800 },
108 { 0x3800 },
109 { 0x4800 },
110 { 0x5800 },
111 { 0x6800 },
112 { 0x7800 },
113 { 0x8800 },
114 { 0x9800 },
115 { 0xa800 },
116 { 0xb800 },
117 { 0xc800 },
118 { 0xd800 },
119 { 0xe800 },
120 { 0xf800 }
121 };
123 #define MEM_MASK 64
125 static const struct {
126 unsigned char mem_index;
127 unsigned long mem_start;
128 unsigned char num_pages;
129 } mem_table[] = {
130 { 16, 0x0c0000, 40 },
131 { 18, 0x0c4000, 40 },
132 { 20, 0x0c8000, 40 },
133 { 22, 0x0cc000, 40 },
134 { 24, 0x0d0000, 40 },
135 { 26, 0x0d4000, 40 },
136 { 28, 0x0d8000, 40 },
137 { 30, 0x0dc000, 40 },
138 {144, 0xfc0000, 40 },
139 {148, 0xfc8000, 40 },
140 {154, 0xfd0000, 40 },
141 {156, 0xfd8000, 40 },
142 { 0, 0x0c0000, 20 },
143 { 1, 0x0c2000, 20 },
144 { 2, 0x0c4000, 20 },
145 { 3, 0x0c6000, 20 }
146 };
148 #define IRQ_MASK 243
149 static const struct {
150 unsigned char new_irq;
151 unsigned char old_irq;
152 } irq_table[] = {
153 { 3, 3 },
154 { 4, 4 },
155 { 10, 10 },
156 { 14, 15 }
157 };
159 static short smc_mca_adapter_ids[] __initdata = {
160 0x61c8,
161 0x61c9,
162 0x6fc0,
163 0x6fc1,
164 0x6fc2,
165 0xefd4,
166 0xefd5,
167 0xefe5,
168 0x0000
169 };
171 static char *smc_mca_adapter_names[] __initdata = {
172 "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
173 "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
174 "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
175 "WD Starcard PLUS/A (WD8003ST/A)",
176 "WD Ethercard PLUS 10T/A (WD8003W/A)",
177 "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)",
178 "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)",
179 "IBM PS/2 Adapter/A for Ethernet",
180 NULL
181 };
183 static int ultra_found = 0;
185 static int __init ultramca_probe(struct device *gen_dev)
186 {
187 unsigned short ioaddr;
188 struct net_device *dev;
189 unsigned char reg4, num_pages;
190 struct mca_device *mca_dev = to_mca_device(gen_dev);
191 char slot = mca_dev->slot;
192 unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
193 int i, rc;
194 int adapter = mca_dev->index;
195 int tbase = 0;
196 int tirq = 0;
197 int base_addr = ultra_io[ultra_found];
198 int irq = ultra_irq[ultra_found];
200 if (base_addr || irq) {
201 printk(KERN_INFO "Probing for SMC MCA adapter");
202 if (base_addr) {
203 printk(KERN_INFO " at I/O address 0x%04x%c",
204 base_addr, irq ? ' ' : '\n');
205 }
206 if (irq) {
207 printk(KERN_INFO "using irq %d\n", irq);
208 }
209 }
211 tirq = 0;
212 tbase = 0;
214 /* If we're trying to match a specificied irq or io address,
215 * we'll reject the adapter found unless it's the one we're
216 * looking for */
218 pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */
219 pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */
220 pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */
221 pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */
223 /* Test the following conditions:
224 * - If an irq parameter is supplied, compare it
225 * with the irq of the adapter we found
226 * - If a base_addr paramater is given, compare it
227 * with the base_addr of the adapter we found
228 * - Check that the irq and the base_addr of the
229 * adapter we found is not already in use by
230 * this driver
231 */
233 switch (mca_dev->index) {
234 case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
235 case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
236 case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
237 case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
238 {
239 tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr;
240 tirq = irq_table[(pos5 & 0xc) >> 2].new_irq;
241 break;
242 }
243 case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
244 case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
245 case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
246 case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
247 {
248 tbase = ((pos2 & 0x0fe) * 0x10);
249 tirq = irq_table[(pos5 & 3)].old_irq;
250 break;
251 }
252 }
254 if(!tirq || !tbase
255 || (irq && irq != tirq)
256 || (base_addr && tbase != base_addr))
257 /* FIXME: we're trying to force the ordering of the
258 * devices here, there should be a way of getting this
259 * to happen */
260 return -ENXIO;
262 /* Adapter found. */
263 dev = alloc_ei_netdev();
264 if(!dev)
265 return -ENODEV;
267 SET_MODULE_OWNER(dev);
268 SET_NETDEV_DEV(dev, gen_dev);
269 mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]);
270 mca_device_set_claim(mca_dev, 1);
272 printk(KERN_INFO "smc_mca: %s found in slot %d\n",
273 smc_mca_adapter_names[adapter], slot + 1);
275 ultra_found++;
277 dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
278 dev->irq = mca_device_transform_irq(mca_dev, tirq);
279 dev->mem_start = 0;
280 num_pages = 40;
282 switch (adapter) { /* card-# in const array above [hs] */
283 case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
284 case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
285 {
286 for (i = 0; i < 16; i++) { /* taking 16 counts
287 * up to 15 [hs] */
288 if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) {
289 dev->mem_start = (unsigned long)
290 mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start);
291 num_pages = mem_table[i].num_pages;
292 }
293 }
294 break;
295 }
296 case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
297 case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
298 case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
299 case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
300 {
301 dev->mem_start = (unsigned long)
302 mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000));
303 num_pages = 0x40;
304 break;
305 }
306 case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
307 case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
308 {
309 /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates
310 * the index of the 0x2000 step.
311 * beware different number of pages [hs]
312 */
313 dev->mem_start = (unsigned long)
314 mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf))));
315 num_pages = 0x20 + (2 * (pos3 & 0x10));
316 break;
317 }
318 }
320 /* sanity check, shouldn't happen */
321 if (dev->mem_start == 0) {
322 rc = -ENODEV;
323 goto err_unclaim;
324 }
326 if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) {
327 rc = -ENODEV;
328 goto err_unclaim;
329 }
331 reg4 = inb(ioaddr + 4) & 0x7f;
332 outb(reg4, ioaddr + 4);
334 printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x,", slot + 1, ioaddr);
336 for (i = 0; i < 6; i++)
337 printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
339 /* Switch from the station address to the alternate register set
340 * and read the useful registers there.
341 */
343 outb(0x80 | reg4, ioaddr + 4);
345 /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot.
346 */
348 outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
350 /* Switch back to the station address register set so that
351 * the MS-DOS driver can find the card after a warm boot.
352 */
354 outb(reg4, ioaddr + 4);
356 gen_dev->driver_data = dev;
358 /* The 8390 isn't at the base address, so fake the offset
359 */
361 dev->base_addr = ioaddr + ULTRA_NIC_OFFSET;
363 ei_status.name = "SMC Ultra MCA";
364 ei_status.word16 = 1;
365 ei_status.tx_start_page = START_PG;
366 ei_status.rx_start_page = START_PG + TX_PAGES;
367 ei_status.stop_page = num_pages;
369 ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256);
370 if (!ei_status.mem) {
371 rc = -ENOMEM;
372 goto err_release_region;
373 }
375 dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256;
377 printk(", IRQ %d memory %#lx-%#lx.\n",
378 dev->irq, dev->mem_start, dev->mem_end - 1);
380 ei_status.reset_8390 = &ultramca_reset_8390;
381 ei_status.block_input = &ultramca_block_input;
382 ei_status.block_output = &ultramca_block_output;
383 ei_status.get_8390_hdr = &ultramca_get_8390_hdr;
385 ei_status.priv = slot;
387 dev->open = &ultramca_open;
388 dev->stop = &ultramca_close_card;
389 #ifdef CONFIG_NET_POLL_CONTROLLER
390 dev->poll_controller = ei_poll;
391 #endif
393 NS8390_init(dev, 0);
395 rc = register_netdev(dev);
396 if (rc)
397 goto err_unmap;
399 return 0;
401 err_unmap:
402 iounmap(ei_status.mem);
403 err_release_region:
404 release_region(ioaddr, ULTRA_IO_EXTENT);
405 err_unclaim:
406 mca_device_set_claim(mca_dev, 0);
407 free_netdev(dev);
408 return rc;
409 }
411 static int ultramca_open(struct net_device *dev)
412 {
413 int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
414 int retval;
416 if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
417 return retval;
419 outb(ULTRA_MEMENB, ioaddr); /* Enable memory */
420 outb(0x80, ioaddr + 5); /* ??? */
421 outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
422 outb(0x04, ioaddr + 5); /* ??? */
424 /* Set the early receive warning level in window 0 high enough not
425 * to receive ERW interrupts.
426 */
428 /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr);
429 * outb(0xff, dev->base_addr + EN0_ERWCNT);
430 */
432 ei_open(dev);
433 return 0;
434 }
436 static void ultramca_reset_8390(struct net_device *dev)
437 {
438 int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
440 outb(ULTRA_RESET, ioaddr);
441 if (ei_debug > 1)
442 printk("resetting Ultra, t=%ld...", jiffies);
443 ei_status.txing = 0;
445 outb(0x80, ioaddr + 5); /* ??? */
446 outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
448 if (ei_debug > 1)
449 printk("reset done\n");
450 return;
451 }
453 /* Grab the 8390 specific header. Similar to the block_input routine, but
454 * we don't need to be concerned with ring wrap as the header will be at
455 * the start of a page, so we optimize accordingly.
456 */
458 static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
459 {
460 void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8);
462 #ifdef notdef
463 /* Officially this is what we are doing, but the readl() is faster */
464 memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
465 #else
466 ((unsigned int*)hdr)[0] = readl(hdr_start);
467 #endif
468 }
470 /* Block input and output are easy on shared memory ethercards, the only
471 * complication is when the ring buffer wraps.
472 */
474 static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
475 {
476 void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256;
478 if (ring_offset + count > ei_status.stop_page * 256) {
479 /* We must wrap the input move. */
480 int semi_count = ei_status.stop_page * 256 - ring_offset;
481 memcpy_fromio(skb->data, xfer_start, semi_count);
482 count -= semi_count;
483 memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
484 } else {
485 /* Packet is in one chunk -- we can copy + cksum. */
486 eth_io_copy_and_sum(skb, xfer_start, count, 0);
487 }
489 }
491 static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf,
492 int start_page)
493 {
494 void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8);
496 memcpy_toio(shmem, buf, count);
497 }
499 static int ultramca_close_card(struct net_device *dev)
500 {
501 int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
503 netif_stop_queue(dev);
505 if (ei_debug > 1)
506 printk("%s: Shutting down ethercard.\n", dev->name);
508 outb(0x00, ioaddr + 6); /* Disable interrupts. */
509 free_irq(dev->irq, dev);
511 NS8390_init(dev, 0);
512 /* We should someday disable shared memory and change to 8-bit mode
513 * "just in case"...
514 */
516 return 0;
517 }
519 static int ultramca_remove(struct device *gen_dev)
520 {
521 struct mca_device *mca_dev = to_mca_device(gen_dev);
522 struct net_device *dev = (struct net_device *)gen_dev->driver_data;
524 if (dev) {
525 /* NB: ultra_close_card() does free_irq */
526 int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
528 unregister_netdev(dev);
529 mca_device_set_claim(mca_dev, 0);
530 release_region(ioaddr, ULTRA_IO_EXTENT);
531 iounmap(ei_status.mem);
532 free_netdev(dev);
533 }
534 return 0;
535 }
538 static struct mca_driver ultra_driver = {
539 .id_table = smc_mca_adapter_ids,
540 .driver = {
541 .name = "smc-mca",
542 .bus = &mca_bus_type,
543 .probe = ultramca_probe,
544 .remove = ultramca_remove,
545 }
546 };
548 static int __init ultramca_init_module(void)
549 {
550 if(!MCA_bus)
551 return -ENXIO;
553 mca_register_driver(&ultra_driver);
555 return ultra_found ? 0 : -ENXIO;
556 }
558 static void __exit ultramca_cleanup_module(void)
559 {
560 mca_unregister_driver(&ultra_driver);
561 }
562 module_init(ultramca_init_module);
563 module_exit(ultramca_cleanup_module);