diff options
49 files changed, 750 insertions, 482 deletions
diff --git a/.gitignore b/.gitignore index b1f5b9df2ae1..e1d5c17c12c2 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -12,6 +12,9 @@ | |||
12 | *.ko | 12 | *.ko |
13 | *.so | 13 | *.so |
14 | *.mod.c | 14 | *.mod.c |
15 | *.i | ||
16 | *.lst | ||
17 | *.symtypes | ||
15 | 18 | ||
16 | # | 19 | # |
17 | # Top-level generic files | 20 | # Top-level generic files |
@@ -889,7 +889,7 @@ depend dep: | |||
889 | 889 | ||
890 | # --------------------------------------------------------------------------- | 890 | # --------------------------------------------------------------------------- |
891 | # Kernel headers | 891 | # Kernel headers |
892 | INSTALL_HDR_PATH=$(MODLIB)/abi | 892 | INSTALL_HDR_PATH=$(objtree)/usr |
893 | export INSTALL_HDR_PATH | 893 | export INSTALL_HDR_PATH |
894 | 894 | ||
895 | PHONY += headers_install | 895 | PHONY += headers_install |
@@ -986,7 +986,7 @@ CLEAN_FILES += vmlinux System.map \ | |||
986 | .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map | 986 | .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map |
987 | 987 | ||
988 | # Directories & files removed with 'make mrproper' | 988 | # Directories & files removed with 'make mrproper' |
989 | MRPROPER_DIRS += include/config include2 | 989 | MRPROPER_DIRS += include/config include2 usr/include |
990 | MRPROPER_FILES += .config .config.old include/asm .version .old_version \ | 990 | MRPROPER_FILES += .config .config.old include/asm .version .old_version \ |
991 | include/linux/autoconf.h include/linux/version.h \ | 991 | include/linux/autoconf.h include/linux/version.h \ |
992 | include/linux/utsrelease.h \ | 992 | include/linux/utsrelease.h \ |
@@ -1077,7 +1077,7 @@ help: | |||
1077 | @echo ' kernelrelease - Output the release version string' | 1077 | @echo ' kernelrelease - Output the release version string' |
1078 | @echo ' kernelversion - Output the version stored in Makefile' | 1078 | @echo ' kernelversion - Output the version stored in Makefile' |
1079 | @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH' | 1079 | @echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH' |
1080 | @echo ' (default: /lib/modules/$$VERSION/abi)' | 1080 | @echo ' (default: $(INSTALL_HDR_PATH))' |
1081 | @echo '' | 1081 | @echo '' |
1082 | @echo 'Static analysers' | 1082 | @echo 'Static analysers' |
1083 | @echo ' checkstack - Generate a list of stack hogs' | 1083 | @echo ' checkstack - Generate a list of stack hogs' |
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index c8c1df8ff2b4..5f8dc8a21bd7 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c | |||
@@ -337,6 +337,8 @@ static int __init ppro_init(char ** cpu_type) | |||
337 | 337 | ||
338 | if (cpu_model == 14) | 338 | if (cpu_model == 14) |
339 | *cpu_type = "i386/core"; | 339 | *cpu_type = "i386/core"; |
340 | else if (cpu_model == 15) | ||
341 | *cpu_type = "i386/core_2"; | ||
340 | else if (cpu_model > 0xd) | 342 | else if (cpu_model > 0xd) |
341 | return 0; | 343 | return 0; |
342 | else if (cpu_model == 9) { | 344 | else if (cpu_model == 9) { |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index ca2f538e549e..613d67f1c7f0 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -668,6 +668,7 @@ int khvcd(void *unused) | |||
668 | do { | 668 | do { |
669 | poll_mask = 0; | 669 | poll_mask = 0; |
670 | hvc_kicked = 0; | 670 | hvc_kicked = 0; |
671 | try_to_freeze(); | ||
671 | wmb(); | 672 | wmb(); |
672 | if (cpus_empty(cpus_in_xmon)) { | 673 | if (cpus_empty(cpus_in_xmon)) { |
673 | spin_lock(&hvc_structs_lock); | 674 | spin_lock(&hvc_structs_lock); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index f57eba0bf253..abca98beac14 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -402,10 +402,10 @@ static void handle_flags(struct smi_info *smi_info) | |||
402 | smi_info->curr_msg->data, | 402 | smi_info->curr_msg->data, |
403 | smi_info->curr_msg->data_size); | 403 | smi_info->curr_msg->data_size); |
404 | smi_info->si_state = SI_GETTING_EVENTS; | 404 | smi_info->si_state = SI_GETTING_EVENTS; |
405 | } else if (smi_info->msg_flags & OEM_DATA_AVAIL) { | 405 | } else if (smi_info->msg_flags & OEM_DATA_AVAIL && |
406 | if (smi_info->oem_data_avail_handler) | 406 | smi_info->oem_data_avail_handler) { |
407 | if (smi_info->oem_data_avail_handler(smi_info)) | 407 | if (smi_info->oem_data_avail_handler(smi_info)) |
408 | goto retry; | 408 | goto retry; |
409 | } else { | 409 | } else { |
410 | smi_info->si_state = SI_NORMAL; | 410 | smi_info->si_state = SI_NORMAL; |
411 | } | 411 | } |
@@ -2481,6 +2481,7 @@ static __devinit int init_ipmi_si(void) | |||
2481 | #ifdef CONFIG_PCI | 2481 | #ifdef CONFIG_PCI |
2482 | pci_unregister_driver(&ipmi_pci_driver); | 2482 | pci_unregister_driver(&ipmi_pci_driver); |
2483 | #endif | 2483 | #endif |
2484 | driver_unregister(&ipmi_driver); | ||
2484 | printk("ipmi_si: Unable to find any System Interface(s)\n"); | 2485 | printk("ipmi_si: Unable to find any System Interface(s)\n"); |
2485 | return -ENODEV; | 2486 | return -ENODEV; |
2486 | } else { | 2487 | } else { |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d6f99d5720fc..5d625a81193f 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("Generic RDMA CM Agent"); | |||
49 | MODULE_LICENSE("Dual BSD/GPL"); | 49 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | 50 | ||
51 | #define CMA_CM_RESPONSE_TIMEOUT 20 | 51 | #define CMA_CM_RESPONSE_TIMEOUT 20 |
52 | #define CMA_MAX_CM_RETRIES 3 | 52 | #define CMA_MAX_CM_RETRIES 15 |
53 | 53 | ||
54 | static void cma_add_one(struct ib_device *device); | 54 | static void cma_add_one(struct ib_device *device); |
55 | static void cma_remove_one(struct ib_device *device); | 55 | static void cma_remove_one(struct ib_device *device); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index b5e6a7be603d..ec356ce7cdcd 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -326,6 +326,7 @@ ipoib_mcast_sendonly_join_complete(int status, | |||
326 | 326 | ||
327 | /* Clear the busy flag so we try again */ | 327 | /* Clear the busy flag so we try again */ |
328 | clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); | 328 | clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); |
329 | mcast->query = NULL; | ||
329 | } | 330 | } |
330 | 331 | ||
331 | complete(&mcast->done); | 332 | complete(&mcast->done); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 8257d5a2c8f8..fd8344cdc0db 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -799,13 +799,6 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
799 | spin_unlock_irqrestore(target->scsi_host->host_lock, flags); | 799 | spin_unlock_irqrestore(target->scsi_host->host_lock, flags); |
800 | } | 800 | } |
801 | 801 | ||
802 | static void srp_reconnect_work(void *target_ptr) | ||
803 | { | ||
804 | struct srp_target_port *target = target_ptr; | ||
805 | |||
806 | srp_reconnect_target(target); | ||
807 | } | ||
808 | |||
809 | static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) | 802 | static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) |
810 | { | 803 | { |
811 | struct srp_iu *iu; | 804 | struct srp_iu *iu; |
@@ -858,7 +851,6 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr) | |||
858 | { | 851 | { |
859 | struct srp_target_port *target = target_ptr; | 852 | struct srp_target_port *target = target_ptr; |
860 | struct ib_wc wc; | 853 | struct ib_wc wc; |
861 | unsigned long flags; | ||
862 | 854 | ||
863 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); | 855 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); |
864 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 856 | while (ib_poll_cq(cq, 1, &wc) > 0) { |
@@ -866,10 +858,6 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr) | |||
866 | printk(KERN_ERR PFX "failed %s status %d\n", | 858 | printk(KERN_ERR PFX "failed %s status %d\n", |
867 | wc.wr_id & SRP_OP_RECV ? "receive" : "send", | 859 | wc.wr_id & SRP_OP_RECV ? "receive" : "send", |
868 | wc.status); | 860 | wc.status); |
869 | spin_lock_irqsave(target->scsi_host->host_lock, flags); | ||
870 | if (target->state == SRP_TARGET_LIVE) | ||
871 | schedule_work(&target->work); | ||
872 | spin_unlock_irqrestore(target->scsi_host->host_lock, flags); | ||
873 | break; | 861 | break; |
874 | } | 862 | } |
875 | 863 | ||
@@ -1705,8 +1693,6 @@ static ssize_t srp_create_target(struct class_device *class_dev, | |||
1705 | target->scsi_host = target_host; | 1693 | target->scsi_host = target_host; |
1706 | target->srp_host = host; | 1694 | target->srp_host = host; |
1707 | 1695 | ||
1708 | INIT_WORK(&target->work, srp_reconnect_work, target); | ||
1709 | |||
1710 | INIT_LIST_HEAD(&target->free_reqs); | 1696 | INIT_LIST_HEAD(&target->free_reqs); |
1711 | INIT_LIST_HEAD(&target->req_queue); | 1697 | INIT_LIST_HEAD(&target->req_queue); |
1712 | for (i = 0; i < SRP_SQ_SIZE; ++i) { | 1698 | for (i = 0; i < SRP_SQ_SIZE; ++i) { |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index c8cbc00243fe..0a54d003ef34 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1204,7 +1204,7 @@ static int nand_write_oob_syndrome(struct mtd_info *mtd, | |||
1204 | pos = steps * (eccsize + chunk); | 1204 | pos = steps * (eccsize + chunk); |
1205 | steps = 0; | 1205 | steps = 0; |
1206 | } else | 1206 | } else |
1207 | pos = eccsize + chunk; | 1207 | pos = eccsize; |
1208 | 1208 | ||
1209 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); | 1209 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); |
1210 | for (i = 0; i < steps; i++) { | 1210 | for (i = 0; i < steps; i++) { |
@@ -1567,7 +1567,7 @@ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, | |||
1567 | bytes = min_t(size_t, len, free->length); | 1567 | bytes = min_t(size_t, len, free->length); |
1568 | boffs = free->offset; | 1568 | boffs = free->offset; |
1569 | } | 1569 | } |
1570 | memcpy(chip->oob_poi + woffs, oob, bytes); | 1570 | memcpy(chip->oob_poi + boffs, oob, bytes); |
1571 | oob += bytes; | 1571 | oob += bytes; |
1572 | } | 1572 | } |
1573 | return oob; | 1573 | return oob; |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 726f43d55937..98ef9f85482f 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -1433,8 +1433,8 @@ e1000_configure_tx(struct e1000_adapter *adapter) | |||
1433 | E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL)); | 1433 | E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL)); |
1434 | E1000_WRITE_REG(hw, TDT, 0); | 1434 | E1000_WRITE_REG(hw, TDT, 0); |
1435 | E1000_WRITE_REG(hw, TDH, 0); | 1435 | E1000_WRITE_REG(hw, TDH, 0); |
1436 | adapter->tx_ring[0].tdh = E1000_TDH; | 1436 | adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH); |
1437 | adapter->tx_ring[0].tdt = E1000_TDT; | 1437 | adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT); |
1438 | break; | 1438 | break; |
1439 | } | 1439 | } |
1440 | 1440 | ||
@@ -1840,8 +1840,8 @@ e1000_configure_rx(struct e1000_adapter *adapter) | |||
1840 | E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); | 1840 | E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL)); |
1841 | E1000_WRITE_REG(hw, RDT, 0); | 1841 | E1000_WRITE_REG(hw, RDT, 0); |
1842 | E1000_WRITE_REG(hw, RDH, 0); | 1842 | E1000_WRITE_REG(hw, RDH, 0); |
1843 | adapter->rx_ring[0].rdh = E1000_RDH; | 1843 | adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH); |
1844 | adapter->rx_ring[0].rdt = E1000_RDT; | 1844 | adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT); |
1845 | break; | 1845 | break; |
1846 | } | 1846 | } |
1847 | 1847 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 760c61b98867..eeab1df5bef3 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -385,6 +385,8 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) | |||
385 | struct pkt_info pkt_info; | 385 | struct pkt_info pkt_info; |
386 | 386 | ||
387 | while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) { | 387 | while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) { |
388 | dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE, | ||
389 | DMA_FROM_DEVICE); | ||
388 | mp->rx_desc_count--; | 390 | mp->rx_desc_count--; |
389 | received_packets++; | 391 | received_packets++; |
390 | 392 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index da9d06bdb818..aa792821854e 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -1430,9 +1430,43 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size) | |||
1430 | break; | 1430 | break; |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | switch (rate) { | ||
1434 | case ZD_OFDM_RATE_6M: | ||
1435 | case ZD_OFDM_RATE_9M: | ||
1436 | i += 3; | ||
1437 | break; | ||
1438 | case ZD_OFDM_RATE_12M: | ||
1439 | case ZD_OFDM_RATE_18M: | ||
1440 | i += 5; | ||
1441 | break; | ||
1442 | case ZD_OFDM_RATE_24M: | ||
1443 | case ZD_OFDM_RATE_36M: | ||
1444 | i += 9; | ||
1445 | break; | ||
1446 | case ZD_OFDM_RATE_48M: | ||
1447 | case ZD_OFDM_RATE_54M: | ||
1448 | i += 15; | ||
1449 | break; | ||
1450 | default: | ||
1451 | return -EINVAL; | ||
1452 | } | ||
1453 | |||
1433 | return i; | 1454 | return i; |
1434 | } | 1455 | } |
1435 | 1456 | ||
1457 | static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size) | ||
1458 | { | ||
1459 | int r; | ||
1460 | |||
1461 | r = ofdm_qual_db(status_quality, rate, size); | ||
1462 | ZD_ASSERT(r >= 0); | ||
1463 | if (r < 0) | ||
1464 | r = 0; | ||
1465 | |||
1466 | r = (r * 100)/29; | ||
1467 | return r <= 100 ? r : 100; | ||
1468 | } | ||
1469 | |||
1436 | static unsigned int log10times100(unsigned int x) | 1470 | static unsigned int log10times100(unsigned int x) |
1437 | { | 1471 | { |
1438 | static const u8 log10[] = { | 1472 | static const u8 log10[] = { |
@@ -1476,31 +1510,28 @@ static int cck_snr_db(u8 status_quality) | |||
1476 | return r; | 1510 | return r; |
1477 | } | 1511 | } |
1478 | 1512 | ||
1479 | static int rx_qual_db(const void *rx_frame, unsigned int size, | 1513 | static int cck_qual_percent(u8 status_quality) |
1480 | const struct rx_status *status) | ||
1481 | { | 1514 | { |
1482 | return (status->frame_status&ZD_RX_OFDM) ? | 1515 | int r; |
1483 | ofdm_qual_db(status->signal_quality_ofdm, | 1516 | |
1484 | zd_ofdm_plcp_header_rate(rx_frame), | 1517 | r = cck_snr_db(status_quality); |
1485 | size) : | 1518 | r = (100*r)/17; |
1486 | cck_snr_db(status->signal_quality_cck); | 1519 | return r <= 100 ? r : 100; |
1487 | } | 1520 | } |
1488 | 1521 | ||
1489 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | 1522 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, |
1490 | const struct rx_status *status) | 1523 | const struct rx_status *status) |
1491 | { | 1524 | { |
1492 | int r = rx_qual_db(rx_frame, size, status); | 1525 | return (status->frame_status&ZD_RX_OFDM) ? |
1493 | if (r < 0) | 1526 | ofdm_qual_percent(status->signal_quality_ofdm, |
1494 | r = 0; | 1527 | zd_ofdm_plcp_header_rate(rx_frame), |
1495 | r = (r * 100) / 14; | 1528 | size) : |
1496 | if (r > 100) | 1529 | cck_qual_percent(status->signal_quality_cck); |
1497 | r = 100; | ||
1498 | return r; | ||
1499 | } | 1530 | } |
1500 | 1531 | ||
1501 | u8 zd_rx_strength_percent(u8 rssi) | 1532 | u8 zd_rx_strength_percent(u8 rssi) |
1502 | { | 1533 | { |
1503 | int r = (rssi*100) / 30; | 1534 | int r = (rssi*100) / 41; |
1504 | if (r > 100) | 1535 | if (r > 100) |
1505 | r = 100; | 1536 | r = 100; |
1506 | return (u8) r; | 1537 | return (u8) r; |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index d6f3e02a0b54..a9bd80a08613 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -816,13 +816,25 @@ static int filter_rx(struct ieee80211_device *ieee, | |||
816 | return -EINVAL; | 816 | return -EINVAL; |
817 | } | 817 | } |
818 | 818 | ||
819 | static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi) | 819 | static void update_qual_rssi(struct zd_mac *mac, |
820 | const u8 *buffer, unsigned int length, | ||
821 | u8 qual_percent, u8 rssi_percent) | ||
820 | { | 822 | { |
821 | unsigned long flags; | 823 | unsigned long flags; |
824 | struct ieee80211_hdr_3addr *hdr; | ||
825 | int i; | ||
826 | |||
827 | hdr = (struct ieee80211_hdr_3addr *)buffer; | ||
828 | if (length < offsetof(struct ieee80211_hdr_3addr, addr3)) | ||
829 | return; | ||
830 | if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0) | ||
831 | return; | ||
822 | 832 | ||
823 | spin_lock_irqsave(&mac->lock, flags); | 833 | spin_lock_irqsave(&mac->lock, flags); |
824 | mac->qual_average = (7 * mac->qual_average + qual_percent) / 8; | 834 | i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE; |
825 | mac->rssi_average = (7 * mac->rssi_average + rssi) / 8; | 835 | mac->qual_buffer[i] = qual_percent; |
836 | mac->rssi_buffer[i] = rssi_percent; | ||
837 | mac->stats_count++; | ||
826 | spin_unlock_irqrestore(&mac->lock, flags); | 838 | spin_unlock_irqrestore(&mac->lock, flags); |
827 | } | 839 | } |
828 | 840 | ||
@@ -853,7 +865,6 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, | |||
853 | if (stats->rate) | 865 | if (stats->rate) |
854 | stats->mask |= IEEE80211_STATMASK_RATE; | 866 | stats->mask |= IEEE80211_STATMASK_RATE; |
855 | 867 | ||
856 | update_qual_rssi(mac, stats->signal, stats->rssi); | ||
857 | return 0; | 868 | return 0; |
858 | } | 869 | } |
859 | 870 | ||
@@ -877,6 +888,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) | |||
877 | sizeof(struct rx_status); | 888 | sizeof(struct rx_status); |
878 | buffer += ZD_PLCP_HEADER_SIZE; | 889 | buffer += ZD_PLCP_HEADER_SIZE; |
879 | 890 | ||
891 | update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); | ||
892 | |||
880 | r = filter_rx(ieee, buffer, length, &stats); | 893 | r = filter_rx(ieee, buffer, length, &stats); |
881 | if (r <= 0) | 894 | if (r <= 0) |
882 | return r; | 895 | return r; |
@@ -981,17 +994,31 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) | |||
981 | { | 994 | { |
982 | struct zd_mac *mac = zd_netdev_mac(ndev); | 995 | struct zd_mac *mac = zd_netdev_mac(ndev); |
983 | struct iw_statistics *iw_stats = &mac->iw_stats; | 996 | struct iw_statistics *iw_stats = &mac->iw_stats; |
997 | unsigned int i, count, qual_total, rssi_total; | ||
984 | 998 | ||
985 | memset(iw_stats, 0, sizeof(struct iw_statistics)); | 999 | memset(iw_stats, 0, sizeof(struct iw_statistics)); |
986 | /* We are not setting the status, because ieee->state is not updated | 1000 | /* We are not setting the status, because ieee->state is not updated |
987 | * at all and this driver doesn't track authentication state. | 1001 | * at all and this driver doesn't track authentication state. |
988 | */ | 1002 | */ |
989 | spin_lock_irq(&mac->lock); | 1003 | spin_lock_irq(&mac->lock); |
990 | iw_stats->qual.qual = mac->qual_average; | 1004 | count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ? |
991 | iw_stats->qual.level = mac->rssi_average; | 1005 | mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE; |
992 | iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED| | 1006 | qual_total = rssi_total = 0; |
993 | IW_QUAL_NOISE_INVALID; | 1007 | for (i = 0; i < count; i++) { |
1008 | qual_total += mac->qual_buffer[i]; | ||
1009 | rssi_total += mac->rssi_buffer[i]; | ||
1010 | } | ||
994 | spin_unlock_irq(&mac->lock); | 1011 | spin_unlock_irq(&mac->lock); |
1012 | iw_stats->qual.updated = IW_QUAL_NOISE_INVALID; | ||
1013 | if (count > 0) { | ||
1014 | iw_stats->qual.qual = qual_total / count; | ||
1015 | iw_stats->qual.level = rssi_total / count; | ||
1016 | iw_stats->qual.updated |= | ||
1017 | IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED; | ||
1018 | } else { | ||
1019 | iw_stats->qual.updated |= | ||
1020 | IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID; | ||
1021 | } | ||
995 | /* TODO: update counter */ | 1022 | /* TODO: update counter */ |
996 | return iw_stats; | 1023 | return iw_stats; |
997 | } | 1024 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 71e382c589ee..b3ba49b84634 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* zd_mac.c | 1 | /* zd_mac.h |
2 | * | 2 | * |
3 | * This program is free software; you can redistribute it and/or modify | 3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by | 4 | * it under the terms of the GNU General Public License as published by |
@@ -87,9 +87,9 @@ struct rx_length_info { | |||
87 | #define RX_LENGTH_INFO_TAG 0x697e | 87 | #define RX_LENGTH_INFO_TAG 0x697e |
88 | 88 | ||
89 | struct rx_status { | 89 | struct rx_status { |
90 | u8 signal_quality_cck; | ||
90 | /* rssi */ | 91 | /* rssi */ |
91 | u8 signal_strength; | 92 | u8 signal_strength; |
92 | u8 signal_quality_cck; | ||
93 | u8 signal_quality_ofdm; | 93 | u8 signal_quality_ofdm; |
94 | u8 decryption_type; | 94 | u8 decryption_type; |
95 | u8 frame_status; | 95 | u8 frame_status; |
@@ -120,14 +120,17 @@ enum mac_flags { | |||
120 | MAC_FIXED_CHANNEL = 0x01, | 120 | MAC_FIXED_CHANNEL = 0x01, |
121 | }; | 121 | }; |
122 | 122 | ||
123 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | ||
124 | |||
123 | struct zd_mac { | 125 | struct zd_mac { |
124 | struct net_device *netdev; | 126 | struct net_device *netdev; |
125 | struct zd_chip chip; | 127 | struct zd_chip chip; |
126 | spinlock_t lock; | 128 | spinlock_t lock; |
127 | /* Unlocked reading possible */ | 129 | /* Unlocked reading possible */ |
128 | struct iw_statistics iw_stats; | 130 | struct iw_statistics iw_stats; |
129 | u8 qual_average; | 131 | unsigned int stats_count; |
130 | u8 rssi_average; | 132 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; |
133 | u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | ||
131 | u8 regdomain; | 134 | u8 regdomain; |
132 | u8 default_regdomain; | 135 | u8 default_regdomain; |
133 | u8 requested_channel; | 136 | u8 requested_channel; |
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 548854754921..1a93fa684e9f 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig | |||
@@ -92,15 +92,6 @@ config QETH_VLAN | |||
92 | If CONFIG_QETH is switched on, this option will include IEEE | 92 | If CONFIG_QETH is switched on, this option will include IEEE |
93 | 802.1q VLAN support in the qeth device driver. | 93 | 802.1q VLAN support in the qeth device driver. |
94 | 94 | ||
95 | config QETH_PERF_STATS | ||
96 | bool "Performance statistics in /proc" | ||
97 | depends on QETH | ||
98 | help | ||
99 | When switched on, this option will add a file in the proc-fs | ||
100 | (/proc/qeth_perf_stats) containing performance statistics. It | ||
101 | may slightly impact performance, so this is only recommended for | ||
102 | internal tuning of the device driver. | ||
103 | |||
104 | config CCWGROUP | 95 | config CCWGROUP |
105 | tristate | 96 | tristate |
106 | default (LCS || CTC || QETH) | 97 | default (LCS || CTC || QETH) |
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 6775a837d646..4777e36a922f 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile | |||
@@ -10,7 +10,6 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o | |||
10 | obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o | 10 | obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o |
11 | obj-$(CONFIG_LCS) += lcs.o cu3088.o | 11 | obj-$(CONFIG_LCS) += lcs.o cu3088.o |
12 | obj-$(CONFIG_CLAW) += claw.o cu3088.o | 12 | obj-$(CONFIG_CLAW) += claw.o cu3088.o |
13 | obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o | ||
14 | qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o | 13 | qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o |
15 | qeth-$(CONFIG_PROC_FS) += qeth_proc.o | 14 | qeth-$(CONFIG_PROC_FS) += qeth_proc.o |
16 | obj-$(CONFIG_QETH) += qeth.o | 15 | obj-$(CONFIG_QETH) += qeth.o |
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 8a4b58120146..3257c22dd79c 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c | |||
@@ -1714,6 +1714,9 @@ add_channel(struct ccw_device *cdev, enum channel_types type) | |||
1714 | kfree(ch); | 1714 | kfree(ch); |
1715 | return 0; | 1715 | return 0; |
1716 | } | 1716 | } |
1717 | |||
1718 | spin_lock_init(&ch->collect_lock); | ||
1719 | |||
1717 | fsm_settimer(ch->fsm, &ch->timer); | 1720 | fsm_settimer(ch->fsm, &ch->timer); |
1718 | skb_queue_head_init(&ch->io_queue); | 1721 | skb_queue_head_init(&ch->io_queue); |
1719 | skb_queue_head_init(&ch->collect_queue); | 1722 | skb_queue_head_init(&ch->collect_queue); |
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 0e863df4027a..821dde86e240 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c | |||
@@ -335,8 +335,8 @@ do { \ | |||
335 | 335 | ||
336 | #else | 336 | #else |
337 | 337 | ||
338 | #define iucv_debug(lvl, fmt, args...) | 338 | #define iucv_debug(lvl, fmt, args...) do { } while (0) |
339 | #define iucv_dumpit(title, buf, len) | 339 | #define iucv_dumpit(title, buf, len) do { } while (0) |
340 | 340 | ||
341 | #endif | 341 | #endif |
342 | 342 | ||
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 2eded55ae88d..16ac68c27a27 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -670,9 +670,8 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) | |||
670 | int index, rc; | 670 | int index, rc; |
671 | 671 | ||
672 | LCS_DBF_TEXT(5, trace, "rdybuff"); | 672 | LCS_DBF_TEXT(5, trace, "rdybuff"); |
673 | if (buffer->state != BUF_STATE_LOCKED && | 673 | BUG_ON(buffer->state != BUF_STATE_LOCKED && |
674 | buffer->state != BUF_STATE_PROCESSED) | 674 | buffer->state != BUF_STATE_PROCESSED); |
675 | BUG(); | ||
676 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); | 675 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); |
677 | buffer->state = BUF_STATE_READY; | 676 | buffer->state = BUF_STATE_READY; |
678 | index = buffer - channel->iob; | 677 | index = buffer - channel->iob; |
@@ -696,8 +695,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) | |||
696 | int index, prev, next; | 695 | int index, prev, next; |
697 | 696 | ||
698 | LCS_DBF_TEXT(5, trace, "prcsbuff"); | 697 | LCS_DBF_TEXT(5, trace, "prcsbuff"); |
699 | if (buffer->state != BUF_STATE_READY) | 698 | BUG_ON(buffer->state != BUF_STATE_READY); |
700 | BUG(); | ||
701 | buffer->state = BUF_STATE_PROCESSED; | 699 | buffer->state = BUF_STATE_PROCESSED; |
702 | index = buffer - channel->iob; | 700 | index = buffer - channel->iob; |
703 | prev = (index - 1) & (LCS_NUM_BUFFS - 1); | 701 | prev = (index - 1) & (LCS_NUM_BUFFS - 1); |
@@ -729,9 +727,8 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) | |||
729 | unsigned long flags; | 727 | unsigned long flags; |
730 | 728 | ||
731 | LCS_DBF_TEXT(5, trace, "relbuff"); | 729 | LCS_DBF_TEXT(5, trace, "relbuff"); |
732 | if (buffer->state != BUF_STATE_LOCKED && | 730 | BUG_ON(buffer->state != BUF_STATE_LOCKED && |
733 | buffer->state != BUF_STATE_PROCESSED) | 731 | buffer->state != BUF_STATE_PROCESSED); |
734 | BUG(); | ||
735 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); | 732 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); |
736 | buffer->state = BUF_STATE_EMPTY; | 733 | buffer->state = BUF_STATE_EMPTY; |
737 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); | 734 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 5d6e6cbfa360..d7d1cc0a5c8e 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -112,7 +112,12 @@ struct iucv_connection { | |||
112 | /** | 112 | /** |
113 | * Linked list of all connection structs. | 113 | * Linked list of all connection structs. |
114 | */ | 114 | */ |
115 | static struct iucv_connection *iucv_connections; | 115 | struct iucv_connection_struct { |
116 | struct iucv_connection *iucv_connections; | ||
117 | rwlock_t iucv_rwlock; | ||
118 | }; | ||
119 | |||
120 | static struct iucv_connection_struct iucv_conns; | ||
116 | 121 | ||
117 | /** | 122 | /** |
118 | * Representation of event-data for the | 123 | * Representation of event-data for the |
@@ -1368,8 +1373,10 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf, | |||
1368 | struct net_device *ndev = priv->conn->netdev; | 1373 | struct net_device *ndev = priv->conn->netdev; |
1369 | char *p; | 1374 | char *p; |
1370 | char *tmp; | 1375 | char *tmp; |
1371 | char username[10]; | 1376 | char username[9]; |
1372 | int i; | 1377 | int i; |
1378 | struct iucv_connection **clist = &iucv_conns.iucv_connections; | ||
1379 | unsigned long flags; | ||
1373 | 1380 | ||
1374 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 1381 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
1375 | if (count>9) { | 1382 | if (count>9) { |
@@ -1382,7 +1389,7 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf, | |||
1382 | tmp = strsep((char **) &buf, "\n"); | 1389 | tmp = strsep((char **) &buf, "\n"); |
1383 | for (i=0, p=tmp; i<8 && *p; i++, p++) { | 1390 | for (i=0, p=tmp; i<8 && *p; i++, p++) { |
1384 | if (isalnum(*p) || (*p == '$')) | 1391 | if (isalnum(*p) || (*p == '$')) |
1385 | username[i]= *p; | 1392 | username[i]= toupper(*p); |
1386 | else if (*p == '\n') { | 1393 | else if (*p == '\n') { |
1387 | /* trailing lf, grr */ | 1394 | /* trailing lf, grr */ |
1388 | break; | 1395 | break; |
@@ -1395,11 +1402,11 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf, | |||
1395 | return -EINVAL; | 1402 | return -EINVAL; |
1396 | } | 1403 | } |
1397 | } | 1404 | } |
1398 | while (i<9) | 1405 | while (i<8) |
1399 | username[i++] = ' '; | 1406 | username[i++] = ' '; |
1400 | username[9] = '\0'; | 1407 | username[8] = '\0'; |
1401 | 1408 | ||
1402 | if (memcmp(username, priv->conn->userid, 8)) { | 1409 | if (memcmp(username, priv->conn->userid, 9)) { |
1403 | /* username changed */ | 1410 | /* username changed */ |
1404 | if (ndev->flags & (IFF_UP | IFF_RUNNING)) { | 1411 | if (ndev->flags & (IFF_UP | IFF_RUNNING)) { |
1405 | PRINT_WARN( | 1412 | PRINT_WARN( |
@@ -1410,6 +1417,19 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf, | |||
1410 | return -EBUSY; | 1417 | return -EBUSY; |
1411 | } | 1418 | } |
1412 | } | 1419 | } |
1420 | read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); | ||
1421 | while (*clist) { | ||
1422 | if (!strncmp(username, (*clist)->userid, 9) || | ||
1423 | ((*clist)->netdev != ndev)) | ||
1424 | break; | ||
1425 | clist = &((*clist)->next); | ||
1426 | } | ||
1427 | read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
1428 | if (*clist) { | ||
1429 | PRINT_WARN("netiucv: Connection to %s already exists\n", | ||
1430 | username); | ||
1431 | return -EEXIST; | ||
1432 | } | ||
1413 | memcpy(priv->conn->userid, username, 9); | 1433 | memcpy(priv->conn->userid, username, 9); |
1414 | 1434 | ||
1415 | return count; | 1435 | return count; |
@@ -1781,13 +1801,15 @@ netiucv_unregister_device(struct device *dev) | |||
1781 | static struct iucv_connection * | 1801 | static struct iucv_connection * |
1782 | netiucv_new_connection(struct net_device *dev, char *username) | 1802 | netiucv_new_connection(struct net_device *dev, char *username) |
1783 | { | 1803 | { |
1784 | struct iucv_connection **clist = &iucv_connections; | 1804 | unsigned long flags; |
1805 | struct iucv_connection **clist = &iucv_conns.iucv_connections; | ||
1785 | struct iucv_connection *conn = | 1806 | struct iucv_connection *conn = |
1786 | kzalloc(sizeof(struct iucv_connection), GFP_KERNEL); | 1807 | kzalloc(sizeof(struct iucv_connection), GFP_KERNEL); |
1787 | 1808 | ||
1788 | if (conn) { | 1809 | if (conn) { |
1789 | skb_queue_head_init(&conn->collect_queue); | 1810 | skb_queue_head_init(&conn->collect_queue); |
1790 | skb_queue_head_init(&conn->commit_queue); | 1811 | skb_queue_head_init(&conn->commit_queue); |
1812 | spin_lock_init(&conn->collect_lock); | ||
1791 | conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; | 1813 | conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT; |
1792 | conn->netdev = dev; | 1814 | conn->netdev = dev; |
1793 | 1815 | ||
@@ -1822,8 +1844,10 @@ netiucv_new_connection(struct net_device *dev, char *username) | |||
1822 | fsm_newstate(conn->fsm, CONN_STATE_STOPPED); | 1844 | fsm_newstate(conn->fsm, CONN_STATE_STOPPED); |
1823 | } | 1845 | } |
1824 | 1846 | ||
1847 | write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); | ||
1825 | conn->next = *clist; | 1848 | conn->next = *clist; |
1826 | *clist = conn; | 1849 | *clist = conn; |
1850 | write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
1827 | } | 1851 | } |
1828 | return conn; | 1852 | return conn; |
1829 | } | 1853 | } |
@@ -1835,14 +1859,17 @@ netiucv_new_connection(struct net_device *dev, char *username) | |||
1835 | static void | 1859 | static void |
1836 | netiucv_remove_connection(struct iucv_connection *conn) | 1860 | netiucv_remove_connection(struct iucv_connection *conn) |
1837 | { | 1861 | { |
1838 | struct iucv_connection **clist = &iucv_connections; | 1862 | struct iucv_connection **clist = &iucv_conns.iucv_connections; |
1863 | unsigned long flags; | ||
1839 | 1864 | ||
1840 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 1865 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
1841 | if (conn == NULL) | 1866 | if (conn == NULL) |
1842 | return; | 1867 | return; |
1868 | write_lock_irqsave(&iucv_conns.iucv_rwlock, flags); | ||
1843 | while (*clist) { | 1869 | while (*clist) { |
1844 | if (*clist == conn) { | 1870 | if (*clist == conn) { |
1845 | *clist = conn->next; | 1871 | *clist = conn->next; |
1872 | write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
1846 | if (conn->handle) { | 1873 | if (conn->handle) { |
1847 | iucv_unregister_program(conn->handle); | 1874 | iucv_unregister_program(conn->handle); |
1848 | conn->handle = NULL; | 1875 | conn->handle = NULL; |
@@ -1855,6 +1882,7 @@ netiucv_remove_connection(struct iucv_connection *conn) | |||
1855 | } | 1882 | } |
1856 | clist = &((*clist)->next); | 1883 | clist = &((*clist)->next); |
1857 | } | 1884 | } |
1885 | write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
1858 | } | 1886 | } |
1859 | 1887 | ||
1860 | /** | 1888 | /** |
@@ -1947,9 +1975,11 @@ static ssize_t | |||
1947 | conn_write(struct device_driver *drv, const char *buf, size_t count) | 1975 | conn_write(struct device_driver *drv, const char *buf, size_t count) |
1948 | { | 1976 | { |
1949 | char *p; | 1977 | char *p; |
1950 | char username[10]; | 1978 | char username[9]; |
1951 | int i, ret; | 1979 | int i, ret; |
1952 | struct net_device *dev; | 1980 | struct net_device *dev; |
1981 | struct iucv_connection **clist = &iucv_conns.iucv_connections; | ||
1982 | unsigned long flags; | ||
1953 | 1983 | ||
1954 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 1984 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
1955 | if (count>9) { | 1985 | if (count>9) { |
@@ -1960,7 +1990,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) | |||
1960 | 1990 | ||
1961 | for (i=0, p=(char *)buf; i<8 && *p; i++, p++) { | 1991 | for (i=0, p=(char *)buf; i<8 && *p; i++, p++) { |
1962 | if (isalnum(*p) || (*p == '$')) | 1992 | if (isalnum(*p) || (*p == '$')) |
1963 | username[i]= *p; | 1993 | username[i]= toupper(*p); |
1964 | else if (*p == '\n') { | 1994 | else if (*p == '\n') { |
1965 | /* trailing lf, grr */ | 1995 | /* trailing lf, grr */ |
1966 | break; | 1996 | break; |
@@ -1971,9 +2001,22 @@ conn_write(struct device_driver *drv, const char *buf, size_t count) | |||
1971 | return -EINVAL; | 2001 | return -EINVAL; |
1972 | } | 2002 | } |
1973 | } | 2003 | } |
1974 | while (i<9) | 2004 | while (i<8) |
1975 | username[i++] = ' '; | 2005 | username[i++] = ' '; |
1976 | username[9] = '\0'; | 2006 | username[8] = '\0'; |
2007 | |||
2008 | read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); | ||
2009 | while (*clist) { | ||
2010 | if (!strncmp(username, (*clist)->userid, 9)) | ||
2011 | break; | ||
2012 | clist = &((*clist)->next); | ||
2013 | } | ||
2014 | read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
2015 | if (*clist) { | ||
2016 | PRINT_WARN("netiucv: Connection to %s already exists\n", | ||
2017 | username); | ||
2018 | return -EEXIST; | ||
2019 | } | ||
1977 | dev = netiucv_init_netdevice(username); | 2020 | dev = netiucv_init_netdevice(username); |
1978 | if (!dev) { | 2021 | if (!dev) { |
1979 | PRINT_WARN( | 2022 | PRINT_WARN( |
@@ -2015,7 +2058,8 @@ DRIVER_ATTR(connection, 0200, NULL, conn_write); | |||
2015 | static ssize_t | 2058 | static ssize_t |
2016 | remove_write (struct device_driver *drv, const char *buf, size_t count) | 2059 | remove_write (struct device_driver *drv, const char *buf, size_t count) |
2017 | { | 2060 | { |
2018 | struct iucv_connection **clist = &iucv_connections; | 2061 | struct iucv_connection **clist = &iucv_conns.iucv_connections; |
2062 | unsigned long flags; | ||
2019 | struct net_device *ndev; | 2063 | struct net_device *ndev; |
2020 | struct netiucv_priv *priv; | 2064 | struct netiucv_priv *priv; |
2021 | struct device *dev; | 2065 | struct device *dev; |
@@ -2026,7 +2070,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count) | |||
2026 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 2070 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
2027 | 2071 | ||
2028 | if (count >= IFNAMSIZ) | 2072 | if (count >= IFNAMSIZ) |
2029 | count = IFNAMSIZ-1; | 2073 | count = IFNAMSIZ - 1;; |
2030 | 2074 | ||
2031 | for (i=0, p=(char *)buf; i<count && *p; i++, p++) { | 2075 | for (i=0, p=(char *)buf; i<count && *p; i++, p++) { |
2032 | if ((*p == '\n') || (*p == ' ')) { | 2076 | if ((*p == '\n') || (*p == ' ')) { |
@@ -2038,6 +2082,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count) | |||
2038 | } | 2082 | } |
2039 | name[i] = '\0'; | 2083 | name[i] = '\0'; |
2040 | 2084 | ||
2085 | read_lock_irqsave(&iucv_conns.iucv_rwlock, flags); | ||
2041 | while (*clist) { | 2086 | while (*clist) { |
2042 | ndev = (*clist)->netdev; | 2087 | ndev = (*clist)->netdev; |
2043 | priv = (struct netiucv_priv*)ndev->priv; | 2088 | priv = (struct netiucv_priv*)ndev->priv; |
@@ -2047,6 +2092,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count) | |||
2047 | clist = &((*clist)->next); | 2092 | clist = &((*clist)->next); |
2048 | continue; | 2093 | continue; |
2049 | } | 2094 | } |
2095 | read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
2050 | if (ndev->flags & (IFF_UP | IFF_RUNNING)) { | 2096 | if (ndev->flags & (IFF_UP | IFF_RUNNING)) { |
2051 | PRINT_WARN( | 2097 | PRINT_WARN( |
2052 | "netiucv: net device %s active with peer %s\n", | 2098 | "netiucv: net device %s active with peer %s\n", |
@@ -2060,6 +2106,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count) | |||
2060 | netiucv_unregister_device(dev); | 2106 | netiucv_unregister_device(dev); |
2061 | return count; | 2107 | return count; |
2062 | } | 2108 | } |
2109 | read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags); | ||
2063 | PRINT_WARN("netiucv: net device %s unknown\n", name); | 2110 | PRINT_WARN("netiucv: net device %s unknown\n", name); |
2064 | IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); | 2111 | IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n"); |
2065 | return -EINVAL; | 2112 | return -EINVAL; |
@@ -2077,8 +2124,8 @@ static void __exit | |||
2077 | netiucv_exit(void) | 2124 | netiucv_exit(void) |
2078 | { | 2125 | { |
2079 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 2126 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
2080 | while (iucv_connections) { | 2127 | while (iucv_conns.iucv_connections) { |
2081 | struct net_device *ndev = iucv_connections->netdev; | 2128 | struct net_device *ndev = iucv_conns.iucv_connections->netdev; |
2082 | struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv; | 2129 | struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv; |
2083 | struct device *dev = priv->dev; | 2130 | struct device *dev = priv->dev; |
2084 | 2131 | ||
@@ -2120,6 +2167,7 @@ netiucv_init(void) | |||
2120 | if (!ret) { | 2167 | if (!ret) { |
2121 | ret = driver_create_file(&netiucv_driver, &driver_attr_remove); | 2168 | ret = driver_create_file(&netiucv_driver, &driver_attr_remove); |
2122 | netiucv_banner(); | 2169 | netiucv_banner(); |
2170 | rwlock_init(&iucv_conns.iucv_rwlock); | ||
2123 | } else { | 2171 | } else { |
2124 | PRINT_ERR("NETIUCV: failed to add driver attribute.\n"); | 2172 | PRINT_ERR("NETIUCV: failed to add driver attribute.\n"); |
2125 | IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret); | 2173 | IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret); |
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 619f4a0c7160..821383d8cbe7 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h | |||
@@ -176,7 +176,6 @@ extern struct ccwgroup_driver qeth_ccwgroup_driver; | |||
176 | /** | 176 | /** |
177 | * card stuff | 177 | * card stuff |
178 | */ | 178 | */ |
179 | #ifdef CONFIG_QETH_PERF_STATS | ||
180 | struct qeth_perf_stats { | 179 | struct qeth_perf_stats { |
181 | unsigned int bufs_rec; | 180 | unsigned int bufs_rec; |
182 | unsigned int bufs_sent; | 181 | unsigned int bufs_sent; |
@@ -211,8 +210,10 @@ struct qeth_perf_stats { | |||
211 | unsigned int large_send_cnt; | 210 | unsigned int large_send_cnt; |
212 | unsigned int sg_skbs_sent; | 211 | unsigned int sg_skbs_sent; |
213 | unsigned int sg_frags_sent; | 212 | unsigned int sg_frags_sent; |
213 | /* initial values when measuring starts */ | ||
214 | unsigned long initial_rx_packets; | ||
215 | unsigned long initial_tx_packets; | ||
214 | }; | 216 | }; |
215 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
216 | 217 | ||
217 | /* Routing stuff */ | 218 | /* Routing stuff */ |
218 | struct qeth_routing_info { | 219 | struct qeth_routing_info { |
@@ -462,6 +463,7 @@ enum qeth_qdio_info_states { | |||
462 | QETH_QDIO_UNINITIALIZED, | 463 | QETH_QDIO_UNINITIALIZED, |
463 | QETH_QDIO_ALLOCATED, | 464 | QETH_QDIO_ALLOCATED, |
464 | QETH_QDIO_ESTABLISHED, | 465 | QETH_QDIO_ESTABLISHED, |
466 | QETH_QDIO_CLEANING | ||
465 | }; | 467 | }; |
466 | 468 | ||
467 | struct qeth_buffer_pool_entry { | 469 | struct qeth_buffer_pool_entry { |
@@ -536,7 +538,7 @@ struct qeth_qdio_out_q { | |||
536 | } __attribute__ ((aligned(256))); | 538 | } __attribute__ ((aligned(256))); |
537 | 539 | ||
538 | struct qeth_qdio_info { | 540 | struct qeth_qdio_info { |
539 | volatile enum qeth_qdio_info_states state; | 541 | atomic_t state; |
540 | /* input */ | 542 | /* input */ |
541 | struct qeth_qdio_q *in_q; | 543 | struct qeth_qdio_q *in_q; |
542 | struct qeth_qdio_buffer_pool in_buf_pool; | 544 | struct qeth_qdio_buffer_pool in_buf_pool; |
@@ -767,6 +769,7 @@ struct qeth_card_options { | |||
767 | int fake_ll; | 769 | int fake_ll; |
768 | int layer2; | 770 | int layer2; |
769 | enum qeth_large_send_types large_send; | 771 | enum qeth_large_send_types large_send; |
772 | int performance_stats; | ||
770 | }; | 773 | }; |
771 | 774 | ||
772 | /* | 775 | /* |
@@ -819,9 +822,7 @@ struct qeth_card { | |||
819 | struct list_head cmd_waiter_list; | 822 | struct list_head cmd_waiter_list; |
820 | /* QDIO buffer handling */ | 823 | /* QDIO buffer handling */ |
821 | struct qeth_qdio_info qdio; | 824 | struct qeth_qdio_info qdio; |
822 | #ifdef CONFIG_QETH_PERF_STATS | ||
823 | struct qeth_perf_stats perf_stats; | 825 | struct qeth_perf_stats perf_stats; |
824 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
825 | int use_hard_stop; | 826 | int use_hard_stop; |
826 | int (*orig_hard_header)(struct sk_buff *,struct net_device *, | 827 | int (*orig_hard_header)(struct sk_buff *,struct net_device *, |
827 | unsigned short,void *,void *,unsigned); | 828 | unsigned short,void *,void *,unsigned); |
@@ -859,23 +860,18 @@ qeth_get_ipa_adp_type(enum qeth_link_types link_type) | |||
859 | } | 860 | } |
860 | } | 861 | } |
861 | 862 | ||
862 | static inline int | 863 | static inline struct sk_buff * |
863 | qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size) | 864 | qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size) |
864 | { | 865 | { |
865 | struct sk_buff *new_skb = NULL; | 866 | struct sk_buff *new_skb = skb; |
866 | 867 | ||
867 | if (skb_headroom(*skb) < size){ | 868 | if (skb_headroom(skb) >= size) |
868 | new_skb = skb_realloc_headroom(*skb, size); | 869 | return skb; |
869 | if (!new_skb) { | 870 | new_skb = skb_realloc_headroom(skb, size); |
870 | PRINT_ERR("qeth_prepare_skb: could " | 871 | if (!new_skb) |
871 | "not realloc headroom for qeth_hdr " | 872 | PRINT_ERR("Could not realloc headroom for qeth_hdr " |
872 | "on interface %s", QETH_CARD_IFNAME(card)); | 873 | "on interface %s", QETH_CARD_IFNAME(card)); |
873 | return -ENOMEM; | 874 | return new_skb; |
874 | } | ||
875 | kfree_skb(*skb); | ||
876 | *skb = new_skb; | ||
877 | } | ||
878 | return 0; | ||
879 | } | 875 | } |
880 | 876 | ||
881 | static inline struct sk_buff * | 877 | static inline struct sk_buff * |
@@ -885,16 +881,15 @@ qeth_pskb_unshare(struct sk_buff *skb, int pri) | |||
885 | if (!skb_cloned(skb)) | 881 | if (!skb_cloned(skb)) |
886 | return skb; | 882 | return skb; |
887 | nskb = skb_copy(skb, pri); | 883 | nskb = skb_copy(skb, pri); |
888 | kfree_skb(skb); /* free our shared copy */ | ||
889 | return nskb; | 884 | return nskb; |
890 | } | 885 | } |
891 | 886 | ||
892 | static inline void * | 887 | static inline void * |
893 | qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) | 888 | qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, int size) |
894 | { | 889 | { |
895 | void *hdr; | 890 | void *hdr; |
896 | 891 | ||
897 | hdr = (void *) skb_push(*skb, size); | 892 | hdr = (void *) skb_push(skb, size); |
898 | /* | 893 | /* |
899 | * sanity check, the Linux memory allocation scheme should | 894 | * sanity check, the Linux memory allocation scheme should |
900 | * never present us cases like this one (the qdio header size plus | 895 | * never present us cases like this one (the qdio header size plus |
@@ -903,8 +898,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) | |||
903 | if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != | 898 | if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != |
904 | (((unsigned long) hdr + size + | 899 | (((unsigned long) hdr + size + |
905 | QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { | 900 | QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { |
906 | PRINT_ERR("qeth_prepare_skb: misaligned " | 901 | PRINT_ERR("Misaligned packet on interface %s. Discarded.", |
907 | "packet on interface %s. Discarded.", | ||
908 | QETH_CARD_IFNAME(card)); | 902 | QETH_CARD_IFNAME(card)); |
909 | return NULL; | 903 | return NULL; |
910 | } | 904 | } |
@@ -1056,13 +1050,11 @@ qeth_get_arphdr_type(int cardtype, int linktype) | |||
1056 | } | 1050 | } |
1057 | } | 1051 | } |
1058 | 1052 | ||
1059 | #ifdef CONFIG_QETH_PERF_STATS | ||
1060 | static inline int | 1053 | static inline int |
1061 | qeth_get_micros(void) | 1054 | qeth_get_micros(void) |
1062 | { | 1055 | { |
1063 | return (int) (get_clock() >> 12); | 1056 | return (int) (get_clock() >> 12); |
1064 | } | 1057 | } |
1065 | #endif | ||
1066 | 1058 | ||
1067 | static inline int | 1059 | static inline int |
1068 | qeth_get_qdio_q_format(struct qeth_card *card) | 1060 | qeth_get_qdio_q_format(struct qeth_card *card) |
@@ -1096,10 +1088,11 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr) | |||
1096 | { | 1088 | { |
1097 | int count = 0, rc = 0; | 1089 | int count = 0, rc = 0; |
1098 | int in[4]; | 1090 | int in[4]; |
1091 | char c; | ||
1099 | 1092 | ||
1100 | rc = sscanf(buf, "%d.%d.%d.%d%n", | 1093 | rc = sscanf(buf, "%u.%u.%u.%u%c", |
1101 | &in[0], &in[1], &in[2], &in[3], &count); | 1094 | &in[0], &in[1], &in[2], &in[3], &c); |
1102 | if (rc != 4 || count<=0) | 1095 | if (rc != 4 && (rc != 5 || c != '\n')) |
1103 | return -EINVAL; | 1096 | return -EINVAL; |
1104 | for (count = 0; count < 4; count++) { | 1097 | for (count = 0; count < 4; count++) { |
1105 | if (in[count] > 255) | 1098 | if (in[count] > 255) |
@@ -1123,24 +1116,28 @@ qeth_ipaddr6_to_string(const __u8 *addr, char *buf) | |||
1123 | static inline int | 1116 | static inline int |
1124 | qeth_string_to_ipaddr6(const char *buf, __u8 *addr) | 1117 | qeth_string_to_ipaddr6(const char *buf, __u8 *addr) |
1125 | { | 1118 | { |
1126 | char *end, *start; | 1119 | const char *end, *end_tmp, *start; |
1127 | __u16 *in; | 1120 | __u16 *in; |
1128 | char num[5]; | 1121 | char num[5]; |
1129 | int num2, cnt, out, found, save_cnt; | 1122 | int num2, cnt, out, found, save_cnt; |
1130 | unsigned short in_tmp[8] = {0, }; | 1123 | unsigned short in_tmp[8] = {0, }; |
1131 | 1124 | ||
1132 | cnt = out = found = save_cnt = num2 = 0; | 1125 | cnt = out = found = save_cnt = num2 = 0; |
1133 | end = start = (char *) buf; | 1126 | end = start = buf; |
1134 | in = (__u16 *) addr; | 1127 | in = (__u16 *) addr; |
1135 | memset(in, 0, 16); | 1128 | memset(in, 0, 16); |
1136 | while (end) { | 1129 | while (*end) { |
1137 | end = strchr(end,':'); | 1130 | end = strchr(start,':'); |
1138 | if (end == NULL) { | 1131 | if (end == NULL) { |
1139 | end = (char *)buf + (strlen(buf)); | 1132 | end = buf + strlen(buf); |
1140 | out = 1; | 1133 | if ((end_tmp = strchr(start, '\n')) != NULL) |
1134 | end = end_tmp; | ||
1135 | out = 1; | ||
1141 | } | 1136 | } |
1142 | if ((end - start)) { | 1137 | if ((end - start)) { |
1143 | memset(num, 0, 5); | 1138 | memset(num, 0, 5); |
1139 | if ((end - start) > 4) | ||
1140 | return -EINVAL; | ||
1144 | memcpy(num, start, end - start); | 1141 | memcpy(num, start, end - start); |
1145 | if (!qeth_isxdigit(num)) | 1142 | if (!qeth_isxdigit(num)) |
1146 | return -EINVAL; | 1143 | return -EINVAL; |
@@ -1158,6 +1155,8 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr) | |||
1158 | } | 1155 | } |
1159 | start = ++end; | 1156 | start = ++end; |
1160 | } | 1157 | } |
1158 | if (cnt + save_cnt > 8) | ||
1159 | return -EINVAL; | ||
1161 | cnt = 7; | 1160 | cnt = 7; |
1162 | while (save_cnt) | 1161 | while (save_cnt) |
1163 | in[cnt--] = in_tmp[--save_cnt]; | 1162 | in[cnt--] = in_tmp[--save_cnt]; |
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 8491598f9149..a363721cf28d 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c | |||
@@ -179,9 +179,8 @@ out_check: | |||
179 | flush_cnt++; | 179 | flush_cnt++; |
180 | } | 180 | } |
181 | } else { | 181 | } else { |
182 | #ifdef CONFIG_QETH_PERF_STATS | 182 | if (queue->card->options.performance_stats) |
183 | queue->card->perf_stats.skbs_sent_pack++; | 183 | queue->card->perf_stats.skbs_sent_pack++; |
184 | #endif | ||
185 | QETH_DBF_TEXT(trace, 6, "fillbfpa"); | 184 | QETH_DBF_TEXT(trace, 6, "fillbfpa"); |
186 | if (buf->next_element_to_fill >= | 185 | if (buf->next_element_to_fill >= |
187 | QETH_MAX_BUFFER_ELEMENTS(queue->card)) { | 186 | QETH_MAX_BUFFER_ELEMENTS(queue->card)) { |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index e1327b8fce00..5613b4564fa2 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -1073,6 +1073,7 @@ qeth_set_intial_options(struct qeth_card *card) | |||
1073 | card->options.layer2 = 1; | 1073 | card->options.layer2 = 1; |
1074 | else | 1074 | else |
1075 | card->options.layer2 = 0; | 1075 | card->options.layer2 = 0; |
1076 | card->options.performance_stats = 1; | ||
1076 | } | 1077 | } |
1077 | 1078 | ||
1078 | /** | 1079 | /** |
@@ -1708,6 +1709,7 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1708 | "IP address reset.\n", | 1709 | "IP address reset.\n", |
1709 | QETH_CARD_IFNAME(card), | 1710 | QETH_CARD_IFNAME(card), |
1710 | card->info.chpid); | 1711 | card->info.chpid); |
1712 | netif_carrier_on(card->dev); | ||
1711 | qeth_schedule_recovery(card); | 1713 | qeth_schedule_recovery(card); |
1712 | return NULL; | 1714 | return NULL; |
1713 | case IPA_CMD_MODCCID: | 1715 | case IPA_CMD_MODCCID: |
@@ -2464,24 +2466,6 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, | |||
2464 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); | 2466 | qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); |
2465 | } | 2467 | } |
2466 | 2468 | ||
2467 | static inline void | ||
2468 | qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb, | ||
2469 | struct qeth_hdr *hdr) | ||
2470 | { | ||
2471 | #ifdef CONFIG_QETH_VLAN | ||
2472 | u16 *vlan_tag; | ||
2473 | |||
2474 | if (hdr->hdr.l3.ext_flags & | ||
2475 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { | ||
2476 | vlan_tag = (u16 *) skb_push(skb, VLAN_HLEN); | ||
2477 | *vlan_tag = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? | ||
2478 | hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); | ||
2479 | *(vlan_tag + 1) = skb->protocol; | ||
2480 | skb->protocol = __constant_htons(ETH_P_8021Q); | ||
2481 | } | ||
2482 | #endif /* CONFIG_QETH_VLAN */ | ||
2483 | } | ||
2484 | |||
2485 | static inline __u16 | 2469 | static inline __u16 |
2486 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | 2470 | qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, |
2487 | struct qeth_hdr *hdr) | 2471 | struct qeth_hdr *hdr) |
@@ -2510,15 +2494,16 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2510 | return vlan_id; | 2494 | return vlan_id; |
2511 | } | 2495 | } |
2512 | 2496 | ||
2513 | static inline void | 2497 | static inline __u16 |
2514 | qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | 2498 | qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, |
2515 | struct qeth_hdr *hdr) | 2499 | struct qeth_hdr *hdr) |
2516 | { | 2500 | { |
2501 | unsigned short vlan_id = 0; | ||
2517 | #ifdef CONFIG_QETH_IPV6 | 2502 | #ifdef CONFIG_QETH_IPV6 |
2518 | if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) { | 2503 | if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) { |
2519 | skb->pkt_type = PACKET_HOST; | 2504 | skb->pkt_type = PACKET_HOST; |
2520 | skb->protocol = qeth_type_trans(skb, card->dev); | 2505 | skb->protocol = qeth_type_trans(skb, card->dev); |
2521 | return; | 2506 | return 0; |
2522 | } | 2507 | } |
2523 | #endif /* CONFIG_QETH_IPV6 */ | 2508 | #endif /* CONFIG_QETH_IPV6 */ |
2524 | skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : | 2509 | skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : |
@@ -2540,7 +2525,13 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2540 | default: | 2525 | default: |
2541 | skb->pkt_type = PACKET_HOST; | 2526 | skb->pkt_type = PACKET_HOST; |
2542 | } | 2527 | } |
2543 | qeth_rebuild_skb_vlan(card, skb, hdr); | 2528 | |
2529 | if (hdr->hdr.l3.ext_flags & | ||
2530 | (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { | ||
2531 | vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? | ||
2532 | hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); | ||
2533 | } | ||
2534 | |||
2544 | if (card->options.fake_ll) | 2535 | if (card->options.fake_ll) |
2545 | qeth_rebuild_skb_fake_ll(card, skb, hdr); | 2536 | qeth_rebuild_skb_fake_ll(card, skb, hdr); |
2546 | else | 2537 | else |
@@ -2556,6 +2547,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, | |||
2556 | else | 2547 | else |
2557 | skb->ip_summed = SW_CHECKSUMMING; | 2548 | skb->ip_summed = SW_CHECKSUMMING; |
2558 | } | 2549 | } |
2550 | return vlan_id; | ||
2559 | } | 2551 | } |
2560 | 2552 | ||
2561 | static inline void | 2553 | static inline void |
@@ -2568,20 +2560,20 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2568 | int offset; | 2560 | int offset; |
2569 | int rxrc; | 2561 | int rxrc; |
2570 | __u16 vlan_tag = 0; | 2562 | __u16 vlan_tag = 0; |
2563 | __u16 *vlan_addr; | ||
2571 | 2564 | ||
2572 | /* get first element of current buffer */ | 2565 | /* get first element of current buffer */ |
2573 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; | 2566 | element = (struct qdio_buffer_element *)&buf->buffer->element[0]; |
2574 | offset = 0; | 2567 | offset = 0; |
2575 | #ifdef CONFIG_QETH_PERF_STATS | 2568 | if (card->options.performance_stats) |
2576 | card->perf_stats.bufs_rec++; | 2569 | card->perf_stats.bufs_rec++; |
2577 | #endif | ||
2578 | while((skb = qeth_get_next_skb(card, buf->buffer, &element, | 2570 | while((skb = qeth_get_next_skb(card, buf->buffer, &element, |
2579 | &offset, &hdr))) { | 2571 | &offset, &hdr))) { |
2580 | skb->dev = card->dev; | 2572 | skb->dev = card->dev; |
2581 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) | 2573 | if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) |
2582 | vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); | 2574 | vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr); |
2583 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) | 2575 | else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3) |
2584 | qeth_rebuild_skb(card, skb, hdr); | 2576 | vlan_tag = qeth_rebuild_skb(card, skb, hdr); |
2585 | else { /*in case of OSN*/ | 2577 | else { /*in case of OSN*/ |
2586 | skb_push(skb, sizeof(struct qeth_hdr)); | 2578 | skb_push(skb, sizeof(struct qeth_hdr)); |
2587 | memcpy(skb->data, hdr, sizeof(struct qeth_hdr)); | 2579 | memcpy(skb->data, hdr, sizeof(struct qeth_hdr)); |
@@ -2591,14 +2583,19 @@ qeth_process_inbound_buffer(struct qeth_card *card, | |||
2591 | dev_kfree_skb_any(skb); | 2583 | dev_kfree_skb_any(skb); |
2592 | continue; | 2584 | continue; |
2593 | } | 2585 | } |
2586 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
2587 | rxrc = card->osn_info.data_cb(skb); | ||
2588 | else | ||
2594 | #ifdef CONFIG_QETH_VLAN | 2589 | #ifdef CONFIG_QETH_VLAN |
2595 | if (vlan_tag) | 2590 | if (vlan_tag) |
2596 | vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag); | 2591 | if (card->vlangrp) |
2592 | vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag); | ||
2593 | else { | ||
2594 | dev_kfree_skb_any(skb); | ||
2595 | continue; | ||
2596 | } | ||
2597 | else | 2597 | else |
2598 | #endif | 2598 | #endif |
2599 | if (card->info.type == QETH_CARD_TYPE_OSN) | ||
2600 | rxrc = card->osn_info.data_cb(skb); | ||
2601 | else | ||
2602 | rxrc = netif_rx(skb); | 2599 | rxrc = netif_rx(skb); |
2603 | card->dev->last_rx = jiffies; | 2600 | card->dev->last_rx = jiffies; |
2604 | card->stats.rx_packets++; | 2601 | card->stats.rx_packets++; |
@@ -2626,7 +2623,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf) | |||
2626 | { | 2623 | { |
2627 | struct qeth_buffer_pool_entry *pool_entry; | 2624 | struct qeth_buffer_pool_entry *pool_entry; |
2628 | int i; | 2625 | int i; |
2629 | 2626 | ||
2630 | pool_entry = qeth_get_buffer_pool_entry(card); | 2627 | pool_entry = qeth_get_buffer_pool_entry(card); |
2631 | /* | 2628 | /* |
2632 | * since the buffer is accessed only from the input_tasklet | 2629 | * since the buffer is accessed only from the input_tasklet |
@@ -2700,17 +2697,18 @@ qeth_queue_input_buffer(struct qeth_card *card, int index) | |||
2700 | * 'index') un-requeued -> this buffer is the first buffer that | 2697 | * 'index') un-requeued -> this buffer is the first buffer that |
2701 | * will be requeued the next time | 2698 | * will be requeued the next time |
2702 | */ | 2699 | */ |
2703 | #ifdef CONFIG_QETH_PERF_STATS | 2700 | if (card->options.performance_stats) { |
2704 | card->perf_stats.inbound_do_qdio_cnt++; | 2701 | card->perf_stats.inbound_do_qdio_cnt++; |
2705 | card->perf_stats.inbound_do_qdio_start_time = qeth_get_micros(); | 2702 | card->perf_stats.inbound_do_qdio_start_time = |
2706 | #endif | 2703 | qeth_get_micros(); |
2704 | } | ||
2707 | rc = do_QDIO(CARD_DDEV(card), | 2705 | rc = do_QDIO(CARD_DDEV(card), |
2708 | QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, | 2706 | QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT, |
2709 | 0, queue->next_buf_to_init, count, NULL); | 2707 | 0, queue->next_buf_to_init, count, NULL); |
2710 | #ifdef CONFIG_QETH_PERF_STATS | 2708 | if (card->options.performance_stats) |
2711 | card->perf_stats.inbound_do_qdio_time += qeth_get_micros() - | 2709 | card->perf_stats.inbound_do_qdio_time += |
2712 | card->perf_stats.inbound_do_qdio_start_time; | 2710 | qeth_get_micros() - |
2713 | #endif | 2711 | card->perf_stats.inbound_do_qdio_start_time; |
2714 | if (rc){ | 2712 | if (rc){ |
2715 | PRINT_WARN("qeth_queue_input_buffer's do_QDIO " | 2713 | PRINT_WARN("qeth_queue_input_buffer's do_QDIO " |
2716 | "return %i (device %s).\n", | 2714 | "return %i (device %s).\n", |
@@ -2746,10 +2744,10 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2746 | QETH_DBF_TEXT(trace, 6, "qdinput"); | 2744 | QETH_DBF_TEXT(trace, 6, "qdinput"); |
2747 | card = (struct qeth_card *) card_ptr; | 2745 | card = (struct qeth_card *) card_ptr; |
2748 | net_dev = card->dev; | 2746 | net_dev = card->dev; |
2749 | #ifdef CONFIG_QETH_PERF_STATS | 2747 | if (card->options.performance_stats) { |
2750 | card->perf_stats.inbound_cnt++; | 2748 | card->perf_stats.inbound_cnt++; |
2751 | card->perf_stats.inbound_start_time = qeth_get_micros(); | 2749 | card->perf_stats.inbound_start_time = qeth_get_micros(); |
2752 | #endif | 2750 | } |
2753 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { | 2751 | if (status & QDIO_STATUS_LOOK_FOR_ERROR) { |
2754 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ | 2752 | if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){ |
2755 | QETH_DBF_TEXT(trace, 1,"qdinchk"); | 2753 | QETH_DBF_TEXT(trace, 1,"qdinchk"); |
@@ -2771,10 +2769,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2771 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); | 2769 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); |
2772 | qeth_queue_input_buffer(card, index); | 2770 | qeth_queue_input_buffer(card, index); |
2773 | } | 2771 | } |
2774 | #ifdef CONFIG_QETH_PERF_STATS | 2772 | if (card->options.performance_stats) |
2775 | card->perf_stats.inbound_time += qeth_get_micros() - | 2773 | card->perf_stats.inbound_time += qeth_get_micros() - |
2776 | card->perf_stats.inbound_start_time; | 2774 | card->perf_stats.inbound_start_time; |
2777 | #endif | ||
2778 | } | 2775 | } |
2779 | 2776 | ||
2780 | static inline int | 2777 | static inline int |
@@ -2864,10 +2861,11 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2864 | } | 2861 | } |
2865 | 2862 | ||
2866 | queue->card->dev->trans_start = jiffies; | 2863 | queue->card->dev->trans_start = jiffies; |
2867 | #ifdef CONFIG_QETH_PERF_STATS | 2864 | if (queue->card->options.performance_stats) { |
2868 | queue->card->perf_stats.outbound_do_qdio_cnt++; | 2865 | queue->card->perf_stats.outbound_do_qdio_cnt++; |
2869 | queue->card->perf_stats.outbound_do_qdio_start_time = qeth_get_micros(); | 2866 | queue->card->perf_stats.outbound_do_qdio_start_time = |
2870 | #endif | 2867 | qeth_get_micros(); |
2868 | } | ||
2871 | if (under_int) | 2869 | if (under_int) |
2872 | rc = do_QDIO(CARD_DDEV(queue->card), | 2870 | rc = do_QDIO(CARD_DDEV(queue->card), |
2873 | QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT, | 2871 | QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT, |
@@ -2875,10 +2873,10 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2875 | else | 2873 | else |
2876 | rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT, | 2874 | rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT, |
2877 | queue->queue_no, index, count, NULL); | 2875 | queue->queue_no, index, count, NULL); |
2878 | #ifdef CONFIG_QETH_PERF_STATS | 2876 | if (queue->card->options.performance_stats) |
2879 | queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - | 2877 | queue->card->perf_stats.outbound_do_qdio_time += |
2880 | queue->card->perf_stats.outbound_do_qdio_start_time; | 2878 | qeth_get_micros() - |
2881 | #endif | 2879 | queue->card->perf_stats.outbound_do_qdio_start_time; |
2882 | if (rc){ | 2880 | if (rc){ |
2883 | QETH_DBF_TEXT(trace, 2, "flushbuf"); | 2881 | QETH_DBF_TEXT(trace, 2, "flushbuf"); |
2884 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); | 2882 | QETH_DBF_TEXT_(trace, 2, " err%d", rc); |
@@ -2890,9 +2888,8 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2890 | return; | 2888 | return; |
2891 | } | 2889 | } |
2892 | atomic_add(count, &queue->used_buffers); | 2890 | atomic_add(count, &queue->used_buffers); |
2893 | #ifdef CONFIG_QETH_PERF_STATS | 2891 | if (queue->card->options.performance_stats) |
2894 | queue->card->perf_stats.bufs_sent += count; | 2892 | queue->card->perf_stats.bufs_sent += count; |
2895 | #endif | ||
2896 | } | 2893 | } |
2897 | 2894 | ||
2898 | /* | 2895 | /* |
@@ -2907,9 +2904,8 @@ qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue) | |||
2907 | >= QETH_HIGH_WATERMARK_PACK){ | 2904 | >= QETH_HIGH_WATERMARK_PACK){ |
2908 | /* switch non-PACKING -> PACKING */ | 2905 | /* switch non-PACKING -> PACKING */ |
2909 | QETH_DBF_TEXT(trace, 6, "np->pack"); | 2906 | QETH_DBF_TEXT(trace, 6, "np->pack"); |
2910 | #ifdef CONFIG_QETH_PERF_STATS | 2907 | if (queue->card->options.performance_stats) |
2911 | queue->card->perf_stats.sc_dp_p++; | 2908 | queue->card->perf_stats.sc_dp_p++; |
2912 | #endif | ||
2913 | queue->do_pack = 1; | 2909 | queue->do_pack = 1; |
2914 | } | 2910 | } |
2915 | } | 2911 | } |
@@ -2932,9 +2928,8 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue) | |||
2932 | <= QETH_LOW_WATERMARK_PACK) { | 2928 | <= QETH_LOW_WATERMARK_PACK) { |
2933 | /* switch PACKING -> non-PACKING */ | 2929 | /* switch PACKING -> non-PACKING */ |
2934 | QETH_DBF_TEXT(trace, 6, "pack->np"); | 2930 | QETH_DBF_TEXT(trace, 6, "pack->np"); |
2935 | #ifdef CONFIG_QETH_PERF_STATS | 2931 | if (queue->card->options.performance_stats) |
2936 | queue->card->perf_stats.sc_p_dp++; | 2932 | queue->card->perf_stats.sc_p_dp++; |
2937 | #endif | ||
2938 | queue->do_pack = 0; | 2933 | queue->do_pack = 0; |
2939 | /* flush packing buffers */ | 2934 | /* flush packing buffers */ |
2940 | buffer = &queue->bufs[queue->next_buf_to_fill]; | 2935 | buffer = &queue->bufs[queue->next_buf_to_fill]; |
@@ -2946,7 +2941,7 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue) | |||
2946 | queue->next_buf_to_fill = | 2941 | queue->next_buf_to_fill = |
2947 | (queue->next_buf_to_fill + 1) % | 2942 | (queue->next_buf_to_fill + 1) % |
2948 | QDIO_MAX_BUFFERS_PER_Q; | 2943 | QDIO_MAX_BUFFERS_PER_Q; |
2949 | } | 2944 | } |
2950 | } | 2945 | } |
2951 | } | 2946 | } |
2952 | return flush_count; | 2947 | return flush_count; |
@@ -3002,11 +2997,10 @@ qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) | |||
3002 | !atomic_read(&queue->set_pci_flags_count)) | 2997 | !atomic_read(&queue->set_pci_flags_count)) |
3003 | flush_cnt += | 2998 | flush_cnt += |
3004 | qeth_flush_buffers_on_no_pci(queue); | 2999 | qeth_flush_buffers_on_no_pci(queue); |
3005 | #ifdef CONFIG_QETH_PERF_STATS | 3000 | if (queue->card->options.performance_stats && |
3006 | if (q_was_packing) | 3001 | q_was_packing) |
3007 | queue->card->perf_stats.bufs_sent_pack += | 3002 | queue->card->perf_stats.bufs_sent_pack += |
3008 | flush_cnt; | 3003 | flush_cnt; |
3009 | #endif | ||
3010 | if (flush_cnt) | 3004 | if (flush_cnt) |
3011 | qeth_flush_buffers(queue, 1, index, flush_cnt); | 3005 | qeth_flush_buffers(queue, 1, index, flush_cnt); |
3012 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | 3006 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); |
@@ -3036,10 +3030,11 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
3036 | return; | 3030 | return; |
3037 | } | 3031 | } |
3038 | } | 3032 | } |
3039 | #ifdef CONFIG_QETH_PERF_STATS | 3033 | if (card->options.performance_stats) { |
3040 | card->perf_stats.outbound_handler_cnt++; | 3034 | card->perf_stats.outbound_handler_cnt++; |
3041 | card->perf_stats.outbound_handler_start_time = qeth_get_micros(); | 3035 | card->perf_stats.outbound_handler_start_time = |
3042 | #endif | 3036 | qeth_get_micros(); |
3037 | } | ||
3043 | for(i = first_element; i < (first_element + count); ++i){ | 3038 | for(i = first_element; i < (first_element + count); ++i){ |
3044 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; | 3039 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; |
3045 | /*we only handle the KICK_IT error by doing a recovery */ | 3040 | /*we only handle the KICK_IT error by doing a recovery */ |
@@ -3058,10 +3053,9 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
3058 | qeth_check_outbound_queue(queue); | 3053 | qeth_check_outbound_queue(queue); |
3059 | 3054 | ||
3060 | netif_wake_queue(queue->card->dev); | 3055 | netif_wake_queue(queue->card->dev); |
3061 | #ifdef CONFIG_QETH_PERF_STATS | 3056 | if (card->options.performance_stats) |
3062 | card->perf_stats.outbound_handler_time += qeth_get_micros() - | 3057 | card->perf_stats.outbound_handler_time += qeth_get_micros() - |
3063 | card->perf_stats.outbound_handler_start_time; | 3058 | card->perf_stats.outbound_handler_start_time; |
3064 | #endif | ||
3065 | } | 3059 | } |
3066 | 3060 | ||
3067 | static void | 3061 | static void |
@@ -3185,13 +3179,14 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3185 | 3179 | ||
3186 | QETH_DBF_TEXT(setup, 2, "allcqdbf"); | 3180 | QETH_DBF_TEXT(setup, 2, "allcqdbf"); |
3187 | 3181 | ||
3188 | if (card->qdio.state == QETH_QDIO_ALLOCATED) | 3182 | if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED, |
3183 | QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) | ||
3189 | return 0; | 3184 | return 0; |
3190 | 3185 | ||
3191 | card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), | 3186 | card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), |
3192 | GFP_KERNEL|GFP_DMA); | 3187 | GFP_KERNEL|GFP_DMA); |
3193 | if (!card->qdio.in_q) | 3188 | if (!card->qdio.in_q) |
3194 | return - ENOMEM; | 3189 | goto out_nomem; |
3195 | QETH_DBF_TEXT(setup, 2, "inq"); | 3190 | QETH_DBF_TEXT(setup, 2, "inq"); |
3196 | QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *)); | 3191 | QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *)); |
3197 | memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q)); | 3192 | memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q)); |
@@ -3200,27 +3195,19 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3200 | card->qdio.in_q->bufs[i].buffer = | 3195 | card->qdio.in_q->bufs[i].buffer = |
3201 | &card->qdio.in_q->qdio_bufs[i]; | 3196 | &card->qdio.in_q->qdio_bufs[i]; |
3202 | /* inbound buffer pool */ | 3197 | /* inbound buffer pool */ |
3203 | if (qeth_alloc_buffer_pool(card)){ | 3198 | if (qeth_alloc_buffer_pool(card)) |
3204 | kfree(card->qdio.in_q); | 3199 | goto out_freeinq; |
3205 | return -ENOMEM; | ||
3206 | } | ||
3207 | /* outbound */ | 3200 | /* outbound */ |
3208 | card->qdio.out_qs = | 3201 | card->qdio.out_qs = |
3209 | kmalloc(card->qdio.no_out_queues * | 3202 | kmalloc(card->qdio.no_out_queues * |
3210 | sizeof(struct qeth_qdio_out_q *), GFP_KERNEL); | 3203 | sizeof(struct qeth_qdio_out_q *), GFP_KERNEL); |
3211 | if (!card->qdio.out_qs){ | 3204 | if (!card->qdio.out_qs) |
3212 | qeth_free_buffer_pool(card); | 3205 | goto out_freepool; |
3213 | return -ENOMEM; | 3206 | for (i = 0; i < card->qdio.no_out_queues; ++i) { |
3214 | } | ||
3215 | for (i = 0; i < card->qdio.no_out_queues; ++i){ | ||
3216 | card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q), | 3207 | card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q), |
3217 | GFP_KERNEL|GFP_DMA); | 3208 | GFP_KERNEL|GFP_DMA); |
3218 | if (!card->qdio.out_qs[i]){ | 3209 | if (!card->qdio.out_qs[i]) |
3219 | while (i > 0) | 3210 | goto out_freeoutq; |
3220 | kfree(card->qdio.out_qs[--i]); | ||
3221 | kfree(card->qdio.out_qs); | ||
3222 | return -ENOMEM; | ||
3223 | } | ||
3224 | QETH_DBF_TEXT_(setup, 2, "outq %i", i); | 3211 | QETH_DBF_TEXT_(setup, 2, "outq %i", i); |
3225 | QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *)); | 3212 | QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *)); |
3226 | memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q)); | 3213 | memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q)); |
@@ -3237,8 +3224,19 @@ qeth_alloc_qdio_buffers(struct qeth_card *card) | |||
3237 | INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list); | 3224 | INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list); |
3238 | } | 3225 | } |
3239 | } | 3226 | } |
3240 | card->qdio.state = QETH_QDIO_ALLOCATED; | ||
3241 | return 0; | 3227 | return 0; |
3228 | |||
3229 | out_freeoutq: | ||
3230 | while (i > 0) | ||
3231 | kfree(card->qdio.out_qs[--i]); | ||
3232 | kfree(card->qdio.out_qs); | ||
3233 | out_freepool: | ||
3234 | qeth_free_buffer_pool(card); | ||
3235 | out_freeinq: | ||
3236 | kfree(card->qdio.in_q); | ||
3237 | out_nomem: | ||
3238 | atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); | ||
3239 | return -ENOMEM; | ||
3242 | } | 3240 | } |
3243 | 3241 | ||
3244 | static void | 3242 | static void |
@@ -3247,7 +3245,8 @@ qeth_free_qdio_buffers(struct qeth_card *card) | |||
3247 | int i, j; | 3245 | int i, j; |
3248 | 3246 | ||
3249 | QETH_DBF_TEXT(trace, 2, "freeqdbf"); | 3247 | QETH_DBF_TEXT(trace, 2, "freeqdbf"); |
3250 | if (card->qdio.state == QETH_QDIO_UNINITIALIZED) | 3248 | if (atomic_swap(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == |
3249 | QETH_QDIO_UNINITIALIZED) | ||
3251 | return; | 3250 | return; |
3252 | kfree(card->qdio.in_q); | 3251 | kfree(card->qdio.in_q); |
3253 | /* inbound buffer pool */ | 3252 | /* inbound buffer pool */ |
@@ -3260,7 +3259,6 @@ qeth_free_qdio_buffers(struct qeth_card *card) | |||
3260 | kfree(card->qdio.out_qs[i]); | 3259 | kfree(card->qdio.out_qs[i]); |
3261 | } | 3260 | } |
3262 | kfree(card->qdio.out_qs); | 3261 | kfree(card->qdio.out_qs); |
3263 | card->qdio.state = QETH_QDIO_UNINITIALIZED; | ||
3264 | } | 3262 | } |
3265 | 3263 | ||
3266 | static void | 3264 | static void |
@@ -3282,7 +3280,7 @@ static void | |||
3282 | qeth_init_qdio_info(struct qeth_card *card) | 3280 | qeth_init_qdio_info(struct qeth_card *card) |
3283 | { | 3281 | { |
3284 | QETH_DBF_TEXT(setup, 4, "intqdinf"); | 3282 | QETH_DBF_TEXT(setup, 4, "intqdinf"); |
3285 | card->qdio.state = QETH_QDIO_UNINITIALIZED; | 3283 | atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); |
3286 | /* inbound */ | 3284 | /* inbound */ |
3287 | card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; | 3285 | card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; |
3288 | card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT; | 3286 | card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT; |
@@ -3345,7 +3343,7 @@ qeth_qdio_establish(struct qeth_card *card) | |||
3345 | struct qdio_buffer **in_sbal_ptrs; | 3343 | struct qdio_buffer **in_sbal_ptrs; |
3346 | struct qdio_buffer **out_sbal_ptrs; | 3344 | struct qdio_buffer **out_sbal_ptrs; |
3347 | int i, j, k; | 3345 | int i, j, k; |
3348 | int rc; | 3346 | int rc = 0; |
3349 | 3347 | ||
3350 | QETH_DBF_TEXT(setup, 2, "qdioest"); | 3348 | QETH_DBF_TEXT(setup, 2, "qdioest"); |
3351 | 3349 | ||
@@ -3404,8 +3402,10 @@ qeth_qdio_establish(struct qeth_card *card) | |||
3404 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; | 3402 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; |
3405 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; | 3403 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; |
3406 | 3404 | ||
3407 | if (!(rc = qdio_initialize(&init_data))) | 3405 | if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED, |
3408 | card->qdio.state = QETH_QDIO_ESTABLISHED; | 3406 | QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) |
3407 | if ((rc = qdio_initialize(&init_data))) | ||
3408 | atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); | ||
3409 | 3409 | ||
3410 | kfree(out_sbal_ptrs); | 3410 | kfree(out_sbal_ptrs); |
3411 | kfree(in_sbal_ptrs); | 3411 | kfree(in_sbal_ptrs); |
@@ -3521,13 +3521,20 @@ qeth_qdio_clear_card(struct qeth_card *card, int use_halt) | |||
3521 | int rc = 0; | 3521 | int rc = 0; |
3522 | 3522 | ||
3523 | QETH_DBF_TEXT(trace,3,"qdioclr"); | 3523 | QETH_DBF_TEXT(trace,3,"qdioclr"); |
3524 | if (card->qdio.state == QETH_QDIO_ESTABLISHED){ | 3524 | switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED, |
3525 | QETH_QDIO_CLEANING)) { | ||
3526 | case QETH_QDIO_ESTABLISHED: | ||
3525 | if ((rc = qdio_cleanup(CARD_DDEV(card), | 3527 | if ((rc = qdio_cleanup(CARD_DDEV(card), |
3526 | (card->info.type == QETH_CARD_TYPE_IQD) ? | 3528 | (card->info.type == QETH_CARD_TYPE_IQD) ? |
3527 | QDIO_FLAG_CLEANUP_USING_HALT : | 3529 | QDIO_FLAG_CLEANUP_USING_HALT : |
3528 | QDIO_FLAG_CLEANUP_USING_CLEAR))) | 3530 | QDIO_FLAG_CLEANUP_USING_CLEAR))) |
3529 | QETH_DBF_TEXT_(trace, 3, "1err%d", rc); | 3531 | QETH_DBF_TEXT_(trace, 3, "1err%d", rc); |
3530 | card->qdio.state = QETH_QDIO_ALLOCATED; | 3532 | atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); |
3533 | break; | ||
3534 | case QETH_QDIO_CLEANING: | ||
3535 | return rc; | ||
3536 | default: | ||
3537 | break; | ||
3531 | } | 3538 | } |
3532 | if ((rc = qeth_clear_halt_card(card, use_halt))) | 3539 | if ((rc = qeth_clear_halt_card(card, use_halt))) |
3533 | QETH_DBF_TEXT_(trace, 3, "2err%d", rc); | 3540 | QETH_DBF_TEXT_(trace, 3, "2err%d", rc); |
@@ -3687,10 +3694,10 @@ qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3687 | /* return OK; otherwise ksoftirqd goes to 100% */ | 3694 | /* return OK; otherwise ksoftirqd goes to 100% */ |
3688 | return NETDEV_TX_OK; | 3695 | return NETDEV_TX_OK; |
3689 | } | 3696 | } |
3690 | #ifdef CONFIG_QETH_PERF_STATS | 3697 | if (card->options.performance_stats) { |
3691 | card->perf_stats.outbound_cnt++; | 3698 | card->perf_stats.outbound_cnt++; |
3692 | card->perf_stats.outbound_start_time = qeth_get_micros(); | 3699 | card->perf_stats.outbound_start_time = qeth_get_micros(); |
3693 | #endif | 3700 | } |
3694 | netif_stop_queue(dev); | 3701 | netif_stop_queue(dev); |
3695 | if ((rc = qeth_send_packet(card, skb))) { | 3702 | if ((rc = qeth_send_packet(card, skb))) { |
3696 | if (rc == -EBUSY) { | 3703 | if (rc == -EBUSY) { |
@@ -3704,10 +3711,9 @@ qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3704 | } | 3711 | } |
3705 | } | 3712 | } |
3706 | netif_wake_queue(dev); | 3713 | netif_wake_queue(dev); |
3707 | #ifdef CONFIG_QETH_PERF_STATS | 3714 | if (card->options.performance_stats) |
3708 | card->perf_stats.outbound_time += qeth_get_micros() - | 3715 | card->perf_stats.outbound_time += qeth_get_micros() - |
3709 | card->perf_stats.outbound_start_time; | 3716 | card->perf_stats.outbound_start_time; |
3710 | #endif | ||
3711 | return rc; | 3717 | return rc; |
3712 | } | 3718 | } |
3713 | 3719 | ||
@@ -3922,49 +3928,59 @@ qeth_get_ip_version(struct sk_buff *skb) | |||
3922 | } | 3928 | } |
3923 | } | 3929 | } |
3924 | 3930 | ||
3925 | static inline int | 3931 | static inline struct qeth_hdr * |
3926 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, | 3932 | __qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv) |
3927 | struct qeth_hdr **hdr, int ipv) | ||
3928 | { | 3933 | { |
3929 | int rc = 0; | ||
3930 | #ifdef CONFIG_QETH_VLAN | 3934 | #ifdef CONFIG_QETH_VLAN |
3931 | u16 *tag; | 3935 | u16 *tag; |
3932 | #endif | 3936 | if (card->vlangrp && vlan_tx_tag_present(skb) && |
3933 | |||
3934 | QETH_DBF_TEXT(trace, 6, "prepskb"); | ||
3935 | if (card->info.type == QETH_CARD_TYPE_OSN) { | ||
3936 | *hdr = (struct qeth_hdr *)(*skb)->data; | ||
3937 | return rc; | ||
3938 | } | ||
3939 | rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | ||
3940 | if (rc) | ||
3941 | return rc; | ||
3942 | #ifdef CONFIG_QETH_VLAN | ||
3943 | if (card->vlangrp && vlan_tx_tag_present(*skb) && | ||
3944 | ((ipv == 6) || card->options.layer2) ) { | 3937 | ((ipv == 6) || card->options.layer2) ) { |
3945 | /* | 3938 | /* |
3946 | * Move the mac addresses (6 bytes src, 6 bytes dest) | 3939 | * Move the mac addresses (6 bytes src, 6 bytes dest) |
3947 | * to the beginning of the new header. We are using three | 3940 | * to the beginning of the new header. We are using three |
3948 | * memcpys instead of one memmove to save cycles. | 3941 | * memcpys instead of one memmove to save cycles. |
3949 | */ | 3942 | */ |
3950 | skb_push(*skb, VLAN_HLEN); | 3943 | skb_push(skb, VLAN_HLEN); |
3951 | memcpy((*skb)->data, (*skb)->data + 4, 4); | 3944 | memcpy(skb->data, skb->data + 4, 4); |
3952 | memcpy((*skb)->data + 4, (*skb)->data + 8, 4); | 3945 | memcpy(skb->data + 4, skb->data + 8, 4); |
3953 | memcpy((*skb)->data + 8, (*skb)->data + 12, 4); | 3946 | memcpy(skb->data + 8, skb->data + 12, 4); |
3954 | tag = (u16 *)((*skb)->data + 12); | 3947 | tag = (u16 *)(skb->data + 12); |
3955 | /* | 3948 | /* |
3956 | * first two bytes = ETH_P_8021Q (0x8100) | 3949 | * first two bytes = ETH_P_8021Q (0x8100) |
3957 | * second two bytes = VLANID | 3950 | * second two bytes = VLANID |
3958 | */ | 3951 | */ |
3959 | *tag = __constant_htons(ETH_P_8021Q); | 3952 | *tag = __constant_htons(ETH_P_8021Q); |
3960 | *(tag + 1) = htons(vlan_tx_tag_get(*skb)); | 3953 | *(tag + 1) = htons(vlan_tx_tag_get(skb)); |
3961 | } | 3954 | } |
3962 | #endif | 3955 | #endif |
3963 | *hdr = (struct qeth_hdr *) | 3956 | return ((struct qeth_hdr *) |
3964 | qeth_push_skb(card, skb, sizeof(struct qeth_hdr)); | 3957 | qeth_push_skb(card, skb, sizeof(struct qeth_hdr))); |
3965 | if (*hdr == NULL) | 3958 | } |
3966 | return -EINVAL; | 3959 | |
3967 | return 0; | 3960 | static inline void |
3961 | __qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb) | ||
3962 | { | ||
3963 | if (orig_skb != new_skb) | ||
3964 | dev_kfree_skb_any(new_skb); | ||
3965 | } | ||
3966 | |||
3967 | static inline struct sk_buff * | ||
3968 | qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, | ||
3969 | struct qeth_hdr **hdr, int ipv) | ||
3970 | { | ||
3971 | struct sk_buff *new_skb; | ||
3972 | |||
3973 | QETH_DBF_TEXT(trace, 6, "prepskb"); | ||
3974 | |||
3975 | new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); | ||
3976 | if (new_skb == NULL) | ||
3977 | return NULL; | ||
3978 | *hdr = __qeth_prepare_skb(card, new_skb, ipv); | ||
3979 | if (*hdr == NULL) { | ||
3980 | __qeth_free_new_skb(skb, new_skb); | ||
3981 | return NULL; | ||
3982 | } | ||
3983 | return new_skb; | ||
3968 | } | 3984 | } |
3969 | 3985 | ||
3970 | static inline u8 | 3986 | static inline u8 |
@@ -4206,9 +4222,8 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue, | |||
4206 | flush_cnt = 1; | 4222 | flush_cnt = 1; |
4207 | } else { | 4223 | } else { |
4208 | QETH_DBF_TEXT(trace, 6, "fillbfpa"); | 4224 | QETH_DBF_TEXT(trace, 6, "fillbfpa"); |
4209 | #ifdef CONFIG_QETH_PERF_STATS | 4225 | if (queue->card->options.performance_stats) |
4210 | queue->card->perf_stats.skbs_sent_pack++; | 4226 | queue->card->perf_stats.skbs_sent_pack++; |
4211 | #endif | ||
4212 | if (buf->next_element_to_fill >= | 4227 | if (buf->next_element_to_fill >= |
4213 | QETH_MAX_BUFFER_ELEMENTS(queue->card)) { | 4228 | QETH_MAX_BUFFER_ELEMENTS(queue->card)) { |
4214 | /* | 4229 | /* |
@@ -4245,21 +4260,15 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4245 | * check if buffer is empty to make sure that we do not 'overtake' | 4260 | * check if buffer is empty to make sure that we do not 'overtake' |
4246 | * ourselves and try to fill a buffer that is already primed | 4261 | * ourselves and try to fill a buffer that is already primed |
4247 | */ | 4262 | */ |
4248 | if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { | 4263 | if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) |
4249 | card->stats.tx_dropped++; | 4264 | goto out; |
4250 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | ||
4251 | return -EBUSY; | ||
4252 | } | ||
4253 | if (ctx == NULL) | 4265 | if (ctx == NULL) |
4254 | queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % | 4266 | queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % |
4255 | QDIO_MAX_BUFFERS_PER_Q; | 4267 | QDIO_MAX_BUFFERS_PER_Q; |
4256 | else { | 4268 | else { |
4257 | buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx); | 4269 | buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx); |
4258 | if (buffers_needed < 0) { | 4270 | if (buffers_needed < 0) |
4259 | card->stats.tx_dropped++; | 4271 | goto out; |
4260 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | ||
4261 | return -EBUSY; | ||
4262 | } | ||
4263 | queue->next_buf_to_fill = | 4272 | queue->next_buf_to_fill = |
4264 | (queue->next_buf_to_fill + buffers_needed) % | 4273 | (queue->next_buf_to_fill + buffers_needed) % |
4265 | QDIO_MAX_BUFFERS_PER_Q; | 4274 | QDIO_MAX_BUFFERS_PER_Q; |
@@ -4274,6 +4283,9 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4274 | qeth_flush_buffers(queue, 0, index, flush_cnt); | 4283 | qeth_flush_buffers(queue, 0, index, flush_cnt); |
4275 | } | 4284 | } |
4276 | return 0; | 4285 | return 0; |
4286 | out: | ||
4287 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | ||
4288 | return -EBUSY; | ||
4277 | } | 4289 | } |
4278 | 4290 | ||
4279 | static inline int | 4291 | static inline int |
@@ -4299,8 +4311,7 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4299 | * check if buffer is empty to make sure that we do not 'overtake' | 4311 | * check if buffer is empty to make sure that we do not 'overtake' |
4300 | * ourselves and try to fill a buffer that is already primed | 4312 | * ourselves and try to fill a buffer that is already primed |
4301 | */ | 4313 | */ |
4302 | if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ | 4314 | if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { |
4303 | card->stats.tx_dropped++; | ||
4304 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | 4315 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); |
4305 | return -EBUSY; | 4316 | return -EBUSY; |
4306 | } | 4317 | } |
@@ -4323,7 +4334,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4323 | * again */ | 4334 | * again */ |
4324 | if (atomic_read(&buffer->state) != | 4335 | if (atomic_read(&buffer->state) != |
4325 | QETH_QDIO_BUF_EMPTY){ | 4336 | QETH_QDIO_BUF_EMPTY){ |
4326 | card->stats.tx_dropped++; | ||
4327 | qeth_flush_buffers(queue, 0, start_index, flush_count); | 4337 | qeth_flush_buffers(queue, 0, start_index, flush_count); |
4328 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); | 4338 | atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); |
4329 | return -EBUSY; | 4339 | return -EBUSY; |
@@ -4334,7 +4344,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4334 | * free buffers) to handle eddp context */ | 4344 | * free buffers) to handle eddp context */ |
4335 | if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){ | 4345 | if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){ |
4336 | printk("eddp tx_dropped 1\n"); | 4346 | printk("eddp tx_dropped 1\n"); |
4337 | card->stats.tx_dropped++; | ||
4338 | rc = -EBUSY; | 4347 | rc = -EBUSY; |
4339 | goto out; | 4348 | goto out; |
4340 | } | 4349 | } |
@@ -4346,7 +4355,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
4346 | tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill); | 4355 | tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill); |
4347 | if (tmp < 0) { | 4356 | if (tmp < 0) { |
4348 | printk("eddp tx_dropped 2\n"); | 4357 | printk("eddp tx_dropped 2\n"); |
4349 | card->stats.tx_dropped++; | ||
4350 | rc = - EBUSY; | 4358 | rc = - EBUSY; |
4351 | goto out; | 4359 | goto out; |
4352 | } | 4360 | } |
@@ -4380,10 +4388,8 @@ out: | |||
4380 | qeth_flush_buffers(queue, 0, start_index, flush_count); | 4388 | qeth_flush_buffers(queue, 0, start_index, flush_count); |
4381 | } | 4389 | } |
4382 | /* at this point the queue is UNLOCKED again */ | 4390 | /* at this point the queue is UNLOCKED again */ |
4383 | #ifdef CONFIG_QETH_PERF_STATS | 4391 | if (queue->card->options.performance_stats && do_pack) |
4384 | if (do_pack) | ||
4385 | queue->card->perf_stats.bufs_sent_pack += flush_count; | 4392 | queue->card->perf_stats.bufs_sent_pack += flush_count; |
4386 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
4387 | 4393 | ||
4388 | return rc; | 4394 | return rc; |
4389 | } | 4395 | } |
@@ -4394,21 +4400,21 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr, | |||
4394 | { | 4400 | { |
4395 | int elements_needed = 0; | 4401 | int elements_needed = 0; |
4396 | 4402 | ||
4397 | if (skb_shinfo(skb)->nr_frags > 0) { | 4403 | if (skb_shinfo(skb)->nr_frags > 0) |
4398 | elements_needed = (skb_shinfo(skb)->nr_frags + 1); | 4404 | elements_needed = (skb_shinfo(skb)->nr_frags + 1); |
4399 | } | 4405 | if (elements_needed == 0) |
4400 | if (elements_needed == 0 ) | ||
4401 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) | 4406 | elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) |
4402 | + skb->len) >> PAGE_SHIFT); | 4407 | + skb->len) >> PAGE_SHIFT); |
4403 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ | 4408 | if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){ |
4404 | PRINT_ERR("qeth_do_send_packet: invalid size of " | 4409 | PRINT_ERR("Invalid size of IP packet " |
4405 | "IP packet (Number=%d / Length=%d). Discarded.\n", | 4410 | "(Number=%d / Length=%d). Discarded.\n", |
4406 | (elements_needed+elems), skb->len); | 4411 | (elements_needed+elems), skb->len); |
4407 | return 0; | 4412 | return 0; |
4408 | } | 4413 | } |
4409 | return elements_needed; | 4414 | return elements_needed; |
4410 | } | 4415 | } |
4411 | 4416 | ||
4417 | |||
4412 | static inline int | 4418 | static inline int |
4413 | qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | 4419 | qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) |
4414 | { | 4420 | { |
@@ -4420,112 +4426,112 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) | |||
4420 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 4426 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; |
4421 | struct qeth_eddp_context *ctx = NULL; | 4427 | struct qeth_eddp_context *ctx = NULL; |
4422 | int tx_bytes = skb->len; | 4428 | int tx_bytes = skb->len; |
4423 | #ifdef CONFIG_QETH_PERF_STATS | ||
4424 | unsigned short nr_frags = skb_shinfo(skb)->nr_frags; | 4429 | unsigned short nr_frags = skb_shinfo(skb)->nr_frags; |
4425 | unsigned short tso_size = skb_shinfo(skb)->gso_size; | 4430 | unsigned short tso_size = skb_shinfo(skb)->gso_size; |
4426 | #endif | 4431 | struct sk_buff *new_skb, *new_skb2; |
4427 | int rc; | 4432 | int rc; |
4428 | 4433 | ||
4429 | QETH_DBF_TEXT(trace, 6, "sendpkt"); | 4434 | QETH_DBF_TEXT(trace, 6, "sendpkt"); |
4430 | 4435 | ||
4436 | new_skb = skb; | ||
4437 | if ((card->info.type == QETH_CARD_TYPE_OSN) && | ||
4438 | (skb->protocol == htons(ETH_P_IPV6))) | ||
4439 | return -EPERM; | ||
4440 | cast_type = qeth_get_cast_type(card, skb); | ||
4441 | if ((cast_type == RTN_BROADCAST) && | ||
4442 | (card->info.broadcast_capable == 0)) | ||
4443 | return -EPERM; | ||
4444 | queue = card->qdio.out_qs | ||
4445 | [qeth_get_priority_queue(card, skb, ipv, cast_type)]; | ||
4431 | if (!card->options.layer2) { | 4446 | if (!card->options.layer2) { |
4432 | ipv = qeth_get_ip_version(skb); | 4447 | ipv = qeth_get_ip_version(skb); |
4433 | if ((card->dev->hard_header == qeth_fake_header) && ipv) { | 4448 | if ((card->dev->hard_header == qeth_fake_header) && ipv) { |
4434 | if ((skb = qeth_pskb_unshare(skb,GFP_ATOMIC)) == NULL) { | 4449 | new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC); |
4435 | card->stats.tx_dropped++; | 4450 | if (!new_skb) |
4436 | dev_kfree_skb_irq(skb); | 4451 | return -ENOMEM; |
4437 | return 0; | ||
4438 | } | ||
4439 | if(card->dev->type == ARPHRD_IEEE802_TR){ | 4452 | if(card->dev->type == ARPHRD_IEEE802_TR){ |
4440 | skb_pull(skb, QETH_FAKE_LL_LEN_TR); | 4453 | skb_pull(new_skb, QETH_FAKE_LL_LEN_TR); |
4441 | } else { | 4454 | } else { |
4442 | skb_pull(skb, QETH_FAKE_LL_LEN_ETH); | 4455 | skb_pull(new_skb, QETH_FAKE_LL_LEN_ETH); |
4443 | } | 4456 | } |
4444 | } | 4457 | } |
4445 | } | 4458 | } |
4446 | if ((card->info.type == QETH_CARD_TYPE_OSN) && | ||
4447 | (skb->protocol == htons(ETH_P_IPV6))) { | ||
4448 | dev_kfree_skb_any(skb); | ||
4449 | return 0; | ||
4450 | } | ||
4451 | cast_type = qeth_get_cast_type(card, skb); | ||
4452 | if ((cast_type == RTN_BROADCAST) && | ||
4453 | (card->info.broadcast_capable == 0)){ | ||
4454 | card->stats.tx_dropped++; | ||
4455 | card->stats.tx_errors++; | ||
4456 | dev_kfree_skb_any(skb); | ||
4457 | return NETDEV_TX_OK; | ||
4458 | } | ||
4459 | queue = card->qdio.out_qs | ||
4460 | [qeth_get_priority_queue(card, skb, ipv, cast_type)]; | ||
4461 | |||
4462 | if (skb_is_gso(skb)) | 4459 | if (skb_is_gso(skb)) |
4463 | large_send = card->options.large_send; | 4460 | large_send = card->options.large_send; |
4464 | 4461 | /* check on OSN device*/ | |
4465 | /*are we able to do TSO ? If so ,prepare and send it from here */ | 4462 | if (card->info.type == QETH_CARD_TYPE_OSN) |
4463 | hdr = (struct qeth_hdr *)new_skb->data; | ||
4464 | /*are we able to do TSO ? */ | ||
4466 | if ((large_send == QETH_LARGE_SEND_TSO) && | 4465 | if ((large_send == QETH_LARGE_SEND_TSO) && |
4467 | (cast_type == RTN_UNSPEC)) { | 4466 | (cast_type == RTN_UNSPEC)) { |
4468 | rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type); | 4467 | rc = qeth_tso_prepare_packet(card, new_skb, ipv, cast_type); |
4469 | if (rc) { | 4468 | if (rc) { |
4470 | card->stats.tx_dropped++; | 4469 | __qeth_free_new_skb(skb, new_skb); |
4471 | card->stats.tx_errors++; | 4470 | return rc; |
4472 | dev_kfree_skb_any(skb); | ||
4473 | return NETDEV_TX_OK; | ||
4474 | } | 4471 | } |
4475 | elements_needed++; | 4472 | elements_needed++; |
4476 | } else { | 4473 | } else if (card->info.type != QETH_CARD_TYPE_OSN) { |
4477 | if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) { | 4474 | new_skb2 = qeth_prepare_skb(card, new_skb, &hdr, ipv); |
4478 | QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); | 4475 | if (!new_skb2) { |
4479 | return rc; | 4476 | __qeth_free_new_skb(skb, new_skb); |
4477 | return -EINVAL; | ||
4480 | } | 4478 | } |
4481 | if (card->info.type != QETH_CARD_TYPE_OSN) | 4479 | if (new_skb != skb) |
4482 | qeth_fill_header(card, hdr, skb, ipv, cast_type); | 4480 | __qeth_free_new_skb(new_skb2, new_skb); |
4481 | new_skb = new_skb2; | ||
4482 | qeth_fill_header(card, hdr, new_skb, ipv, cast_type); | ||
4483 | } | 4483 | } |
4484 | |||
4485 | if (large_send == QETH_LARGE_SEND_EDDP) { | 4484 | if (large_send == QETH_LARGE_SEND_EDDP) { |
4486 | ctx = qeth_eddp_create_context(card, skb, hdr); | 4485 | ctx = qeth_eddp_create_context(card, new_skb, hdr); |
4487 | if (ctx == NULL) { | 4486 | if (ctx == NULL) { |
4487 | __qeth_free_new_skb(skb, new_skb); | ||
4488 | PRINT_WARN("could not create eddp context\n"); | 4488 | PRINT_WARN("could not create eddp context\n"); |
4489 | return -EINVAL; | 4489 | return -EINVAL; |
4490 | } | 4490 | } |
4491 | } else { | 4491 | } else { |
4492 | int elems = qeth_get_elements_no(card,(void*) hdr, skb, | 4492 | int elems = qeth_get_elements_no(card,(void*) hdr, new_skb, |
4493 | elements_needed); | 4493 | elements_needed); |
4494 | if (!elems) | 4494 | if (!elems) { |
4495 | __qeth_free_new_skb(skb, new_skb); | ||
4495 | return -EINVAL; | 4496 | return -EINVAL; |
4497 | } | ||
4496 | elements_needed += elems; | 4498 | elements_needed += elems; |
4497 | } | 4499 | } |
4498 | 4500 | ||
4499 | if (card->info.type != QETH_CARD_TYPE_IQD) | 4501 | if (card->info.type != QETH_CARD_TYPE_IQD) |
4500 | rc = qeth_do_send_packet(card, queue, skb, hdr, | 4502 | rc = qeth_do_send_packet(card, queue, new_skb, hdr, |
4501 | elements_needed, ctx); | 4503 | elements_needed, ctx); |
4502 | else | 4504 | else |
4503 | rc = qeth_do_send_packet_fast(card, queue, skb, hdr, | 4505 | rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr, |
4504 | elements_needed, ctx); | 4506 | elements_needed, ctx); |
4505 | if (!rc){ | 4507 | if (!rc) { |
4506 | card->stats.tx_packets++; | 4508 | card->stats.tx_packets++; |
4507 | card->stats.tx_bytes += tx_bytes; | 4509 | card->stats.tx_bytes += tx_bytes; |
4508 | #ifdef CONFIG_QETH_PERF_STATS | 4510 | if (new_skb != skb) |
4509 | if (tso_size && | 4511 | dev_kfree_skb_any(skb); |
4510 | !(large_send == QETH_LARGE_SEND_NO)) { | 4512 | if (card->options.performance_stats) { |
4511 | card->perf_stats.large_send_bytes += tx_bytes; | 4513 | if (tso_size && |
4512 | card->perf_stats.large_send_cnt++; | 4514 | !(large_send == QETH_LARGE_SEND_NO)) { |
4513 | } | 4515 | card->perf_stats.large_send_bytes += tx_bytes; |
4514 | if (nr_frags > 0){ | 4516 | card->perf_stats.large_send_cnt++; |
4515 | card->perf_stats.sg_skbs_sent++; | 4517 | } |
4516 | /* nr_frags + skb->data */ | 4518 | if (nr_frags > 0) { |
4517 | card->perf_stats.sg_frags_sent += | 4519 | card->perf_stats.sg_skbs_sent++; |
4518 | nr_frags + 1; | 4520 | /* nr_frags + skb->data */ |
4521 | card->perf_stats.sg_frags_sent += | ||
4522 | nr_frags + 1; | ||
4523 | } | ||
4519 | } | 4524 | } |
4520 | #endif /* CONFIG_QETH_PERF_STATS */ | 4525 | } else { |
4526 | card->stats.tx_dropped++; | ||
4527 | __qeth_free_new_skb(skb, new_skb); | ||
4521 | } | 4528 | } |
4522 | if (ctx != NULL) { | 4529 | if (ctx != NULL) { |
4523 | /* drop creator's reference */ | 4530 | /* drop creator's reference */ |
4524 | qeth_eddp_put_context(ctx); | 4531 | qeth_eddp_put_context(ctx); |
4525 | /* free skb; it's not referenced by a buffer */ | 4532 | /* free skb; it's not referenced by a buffer */ |
4526 | if (rc == 0) | 4533 | if (!rc) |
4527 | dev_kfree_skb_any(skb); | 4534 | dev_kfree_skb_any(new_skb); |
4528 | |||
4529 | } | 4535 | } |
4530 | return rc; | 4536 | return rc; |
4531 | } | 4537 | } |
@@ -7338,6 +7344,8 @@ qeth_setrouting_v6(struct qeth_card *card) | |||
7338 | QETH_DBF_TEXT(trace,3,"setrtg6"); | 7344 | QETH_DBF_TEXT(trace,3,"setrtg6"); |
7339 | #ifdef CONFIG_QETH_IPV6 | 7345 | #ifdef CONFIG_QETH_IPV6 |
7340 | 7346 | ||
7347 | if (!qeth_is_supported(card, IPA_IPV6)) | ||
7348 | return 0; | ||
7341 | qeth_correct_routing_type(card, &card->options.route6.type, | 7349 | qeth_correct_routing_type(card, &card->options.route6.type, |
7342 | QETH_PROT_IPV6); | 7350 | QETH_PROT_IPV6); |
7343 | 7351 | ||
@@ -7876,12 +7884,12 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
7876 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); | 7884 | QETH_DBF_TEXT_(setup, 2, "5err%d", rc); |
7877 | goto out_remove; | 7885 | goto out_remove; |
7878 | } | 7886 | } |
7879 | card->state = CARD_STATE_SOFTSETUP; | ||
7880 | 7887 | ||
7881 | if ((rc = qeth_init_qdio_queues(card))){ | 7888 | if ((rc = qeth_init_qdio_queues(card))){ |
7882 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); | 7889 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); |
7883 | goto out_remove; | 7890 | goto out_remove; |
7884 | } | 7891 | } |
7892 | card->state = CARD_STATE_SOFTSETUP; | ||
7885 | netif_carrier_on(card->dev); | 7893 | netif_carrier_on(card->dev); |
7886 | 7894 | ||
7887 | qeth_set_allowed_threads(card, 0xffffffff, 0); | 7895 | qeth_set_allowed_threads(card, 0xffffffff, 0); |
@@ -8538,34 +8546,44 @@ qeth_ipv6_uninit(void) | |||
8538 | static void | 8546 | static void |
8539 | qeth_sysfs_unregister(void) | 8547 | qeth_sysfs_unregister(void) |
8540 | { | 8548 | { |
8549 | s390_root_dev_unregister(qeth_root_dev); | ||
8541 | qeth_remove_driver_attributes(); | 8550 | qeth_remove_driver_attributes(); |
8542 | ccw_driver_unregister(&qeth_ccw_driver); | 8551 | ccw_driver_unregister(&qeth_ccw_driver); |
8543 | ccwgroup_driver_unregister(&qeth_ccwgroup_driver); | 8552 | ccwgroup_driver_unregister(&qeth_ccwgroup_driver); |
8544 | s390_root_dev_unregister(qeth_root_dev); | ||
8545 | } | 8553 | } |
8554 | |||
8546 | /** | 8555 | /** |
8547 | * register qeth at sysfs | 8556 | * register qeth at sysfs |
8548 | */ | 8557 | */ |
8549 | static int | 8558 | static int |
8550 | qeth_sysfs_register(void) | 8559 | qeth_sysfs_register(void) |
8551 | { | 8560 | { |
8552 | int rc=0; | 8561 | int rc; |
8553 | 8562 | ||
8554 | rc = ccwgroup_driver_register(&qeth_ccwgroup_driver); | 8563 | rc = ccwgroup_driver_register(&qeth_ccwgroup_driver); |
8555 | if (rc) | 8564 | if (rc) |
8556 | return rc; | 8565 | goto out; |
8566 | |||
8557 | rc = ccw_driver_register(&qeth_ccw_driver); | 8567 | rc = ccw_driver_register(&qeth_ccw_driver); |
8558 | if (rc) | 8568 | if (rc) |
8559 | return rc; | 8569 | goto out_ccw_driver; |
8570 | |||
8560 | rc = qeth_create_driver_attributes(); | 8571 | rc = qeth_create_driver_attributes(); |
8561 | if (rc) | 8572 | if (rc) |
8562 | return rc; | 8573 | goto out_qeth_attr; |
8574 | |||
8563 | qeth_root_dev = s390_root_dev_register("qeth"); | 8575 | qeth_root_dev = s390_root_dev_register("qeth"); |
8564 | if (IS_ERR(qeth_root_dev)) { | 8576 | rc = IS_ERR(qeth_root_dev) ? PTR_ERR(qeth_root_dev) : 0; |
8565 | rc = PTR_ERR(qeth_root_dev); | 8577 | if (!rc) |
8566 | return rc; | 8578 | goto out; |
8567 | } | 8579 | |
8568 | return 0; | 8580 | qeth_remove_driver_attributes(); |
8581 | out_qeth_attr: | ||
8582 | ccw_driver_unregister(&qeth_ccw_driver); | ||
8583 | out_ccw_driver: | ||
8584 | ccwgroup_driver_unregister(&qeth_ccwgroup_driver); | ||
8585 | out: | ||
8586 | return rc; | ||
8569 | } | 8587 | } |
8570 | 8588 | ||
8571 | /*** | 8589 | /*** |
@@ -8574,7 +8592,7 @@ qeth_sysfs_register(void) | |||
8574 | static int __init | 8592 | static int __init |
8575 | qeth_init(void) | 8593 | qeth_init(void) |
8576 | { | 8594 | { |
8577 | int rc=0; | 8595 | int rc; |
8578 | 8596 | ||
8579 | PRINT_INFO("loading %s\n", version); | 8597 | PRINT_INFO("loading %s\n", version); |
8580 | 8598 | ||
@@ -8583,20 +8601,26 @@ qeth_init(void) | |||
8583 | spin_lock_init(&qeth_notify_lock); | 8601 | spin_lock_init(&qeth_notify_lock); |
8584 | rwlock_init(&qeth_card_list.rwlock); | 8602 | rwlock_init(&qeth_card_list.rwlock); |
8585 | 8603 | ||
8586 | if (qeth_register_dbf_views()) | 8604 | rc = qeth_register_dbf_views(); |
8605 | if (rc) | ||
8587 | goto out_err; | 8606 | goto out_err; |
8588 | if (qeth_sysfs_register()) | 8607 | |
8589 | goto out_sysfs; | 8608 | rc = qeth_sysfs_register(); |
8609 | if (rc) | ||
8610 | goto out_dbf; | ||
8590 | 8611 | ||
8591 | #ifdef CONFIG_QETH_IPV6 | 8612 | #ifdef CONFIG_QETH_IPV6 |
8592 | if (qeth_ipv6_init()) { | 8613 | rc = qeth_ipv6_init(); |
8593 | PRINT_ERR("Out of memory during ipv6 init.\n"); | 8614 | if (rc) { |
8615 | PRINT_ERR("Out of memory during ipv6 init code = %d\n", rc); | ||
8594 | goto out_sysfs; | 8616 | goto out_sysfs; |
8595 | } | 8617 | } |
8596 | #endif /* QETH_IPV6 */ | 8618 | #endif /* QETH_IPV6 */ |
8597 | if (qeth_register_notifiers()) | 8619 | rc = qeth_register_notifiers(); |
8620 | if (rc) | ||
8598 | goto out_ipv6; | 8621 | goto out_ipv6; |
8599 | if (qeth_create_procfs_entries()) | 8622 | rc = qeth_create_procfs_entries(); |
8623 | if (rc) | ||
8600 | goto out_notifiers; | 8624 | goto out_notifiers; |
8601 | 8625 | ||
8602 | return rc; | 8626 | return rc; |
@@ -8606,12 +8630,13 @@ out_notifiers: | |||
8606 | out_ipv6: | 8630 | out_ipv6: |
8607 | #ifdef CONFIG_QETH_IPV6 | 8631 | #ifdef CONFIG_QETH_IPV6 |
8608 | qeth_ipv6_uninit(); | 8632 | qeth_ipv6_uninit(); |
8609 | #endif /* QETH_IPV6 */ | ||
8610 | out_sysfs: | 8633 | out_sysfs: |
8634 | #endif /* QETH_IPV6 */ | ||
8611 | qeth_sysfs_unregister(); | 8635 | qeth_sysfs_unregister(); |
8636 | out_dbf: | ||
8612 | qeth_unregister_dbf_views(); | 8637 | qeth_unregister_dbf_views(); |
8613 | out_err: | 8638 | out_err: |
8614 | PRINT_ERR("Initialization failed"); | 8639 | PRINT_ERR("Initialization failed with code %d\n", rc); |
8615 | return rc; | 8640 | return rc; |
8616 | } | 8641 | } |
8617 | 8642 | ||
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c index 66f2da14e6e3..faa768e59257 100644 --- a/drivers/s390/net/qeth_proc.c +++ b/drivers/s390/net/qeth_proc.c | |||
@@ -173,7 +173,6 @@ static struct file_operations qeth_procfile_fops = { | |||
173 | #define QETH_PERF_PROCFILE_NAME "qeth_perf" | 173 | #define QETH_PERF_PROCFILE_NAME "qeth_perf" |
174 | static struct proc_dir_entry *qeth_perf_procfile; | 174 | static struct proc_dir_entry *qeth_perf_procfile; |
175 | 175 | ||
176 | #ifdef CONFIG_QETH_PERF_STATS | ||
177 | static int | 176 | static int |
178 | qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | 177 | qeth_perf_procfile_seq_show(struct seq_file *s, void *it) |
179 | { | 178 | { |
@@ -192,14 +191,21 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | |||
192 | CARD_DDEV_ID(card), | 191 | CARD_DDEV_ID(card), |
193 | QETH_CARD_IFNAME(card) | 192 | QETH_CARD_IFNAME(card) |
194 | ); | 193 | ); |
194 | if (!card->options.performance_stats) | ||
195 | seq_printf(s, "Performance statistics are deactivated.\n"); | ||
195 | seq_printf(s, " Skb's/buffers received : %lu/%u\n" | 196 | seq_printf(s, " Skb's/buffers received : %lu/%u\n" |
196 | " Skb's/buffers sent : %lu/%u\n\n", | 197 | " Skb's/buffers sent : %lu/%u\n\n", |
197 | card->stats.rx_packets, card->perf_stats.bufs_rec, | 198 | card->stats.rx_packets - |
198 | card->stats.tx_packets, card->perf_stats.bufs_sent | 199 | card->perf_stats.initial_rx_packets, |
200 | card->perf_stats.bufs_rec, | ||
201 | card->stats.tx_packets - | ||
202 | card->perf_stats.initial_tx_packets, | ||
203 | card->perf_stats.bufs_sent | ||
199 | ); | 204 | ); |
200 | seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n" | 205 | seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n" |
201 | " Skb's/buffers sent with packing : %u/%u\n\n", | 206 | " Skb's/buffers sent with packing : %u/%u\n\n", |
202 | card->stats.tx_packets - card->perf_stats.skbs_sent_pack, | 207 | card->stats.tx_packets - card->perf_stats.initial_tx_packets |
208 | - card->perf_stats.skbs_sent_pack, | ||
203 | card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack, | 209 | card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack, |
204 | card->perf_stats.skbs_sent_pack, | 210 | card->perf_stats.skbs_sent_pack, |
205 | card->perf_stats.bufs_sent_pack | 211 | card->perf_stats.bufs_sent_pack |
@@ -275,11 +281,6 @@ static struct file_operations qeth_perf_procfile_fops = { | |||
275 | .release = seq_release, | 281 | .release = seq_release, |
276 | }; | 282 | }; |
277 | 283 | ||
278 | #define qeth_perf_procfile_created qeth_perf_procfile | ||
279 | #else | ||
280 | #define qeth_perf_procfile_created 1 | ||
281 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
282 | |||
283 | int __init | 284 | int __init |
284 | qeth_create_procfs_entries(void) | 285 | qeth_create_procfs_entries(void) |
285 | { | 286 | { |
@@ -288,15 +289,13 @@ qeth_create_procfs_entries(void) | |||
288 | if (qeth_procfile) | 289 | if (qeth_procfile) |
289 | qeth_procfile->proc_fops = &qeth_procfile_fops; | 290 | qeth_procfile->proc_fops = &qeth_procfile_fops; |
290 | 291 | ||
291 | #ifdef CONFIG_QETH_PERF_STATS | ||
292 | qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME, | 292 | qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME, |
293 | S_IFREG | 0444, NULL); | 293 | S_IFREG | 0444, NULL); |
294 | if (qeth_perf_procfile) | 294 | if (qeth_perf_procfile) |
295 | qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; | 295 | qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; |
296 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
297 | 296 | ||
298 | if (qeth_procfile && | 297 | if (qeth_procfile && |
299 | qeth_perf_procfile_created) | 298 | qeth_perf_procfile) |
300 | return 0; | 299 | return 0; |
301 | else | 300 | else |
302 | return -ENOMEM; | 301 | return -ENOMEM; |
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index 001497bbea16..5836737ac58f 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c | |||
@@ -743,6 +743,47 @@ static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, | |||
743 | qeth_dev_layer2_store); | 743 | qeth_dev_layer2_store); |
744 | 744 | ||
745 | static ssize_t | 745 | static ssize_t |
746 | qeth_dev_performance_stats_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
747 | { | ||
748 | struct qeth_card *card = dev->driver_data; | ||
749 | |||
750 | if (!card) | ||
751 | return -EINVAL; | ||
752 | |||
753 | return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0); | ||
754 | } | ||
755 | |||
756 | static ssize_t | ||
757 | qeth_dev_performance_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
758 | { | ||
759 | struct qeth_card *card = dev->driver_data; | ||
760 | char *tmp; | ||
761 | int i; | ||
762 | |||
763 | if (!card) | ||
764 | return -EINVAL; | ||
765 | |||
766 | i = simple_strtoul(buf, &tmp, 16); | ||
767 | if ((i == 0) || (i == 1)) { | ||
768 | if (i == card->options.performance_stats) | ||
769 | return count; | ||
770 | card->options.performance_stats = i; | ||
771 | if (i == 0) | ||
772 | memset(&card->perf_stats, 0, | ||
773 | sizeof(struct qeth_perf_stats)); | ||
774 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; | ||
775 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; | ||
776 | } else { | ||
777 | PRINT_WARN("performance_stats: write 0 or 1 to this file!\n"); | ||
778 | return -EINVAL; | ||
779 | } | ||
780 | return count; | ||
781 | } | ||
782 | |||
783 | static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, | ||
784 | qeth_dev_performance_stats_store); | ||
785 | |||
786 | static ssize_t | ||
746 | qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf) | 787 | qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf) |
747 | { | 788 | { |
748 | struct qeth_card *card = dev->driver_data; | 789 | struct qeth_card *card = dev->driver_data; |
@@ -928,6 +969,7 @@ static struct device_attribute * qeth_device_attrs[] = { | |||
928 | &dev_attr_canonical_macaddr, | 969 | &dev_attr_canonical_macaddr, |
929 | &dev_attr_layer2, | 970 | &dev_attr_layer2, |
930 | &dev_attr_large_send, | 971 | &dev_attr_large_send, |
972 | &dev_attr_performance_stats, | ||
931 | NULL, | 973 | NULL, |
932 | }; | 974 | }; |
933 | 975 | ||
@@ -1110,12 +1152,12 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto, | |||
1110 | { | 1152 | { |
1111 | const char *start, *end; | 1153 | const char *start, *end; |
1112 | char *tmp; | 1154 | char *tmp; |
1113 | char buffer[49] = {0, }; | 1155 | char buffer[40] = {0, }; |
1114 | 1156 | ||
1115 | start = buf; | 1157 | start = buf; |
1116 | /* get address string */ | 1158 | /* get address string */ |
1117 | end = strchr(start, '/'); | 1159 | end = strchr(start, '/'); |
1118 | if (!end || (end-start >= 49)){ | 1160 | if (!end || (end - start >= 40)){ |
1119 | PRINT_WARN("Invalid format for ipato_addx/delx. " | 1161 | PRINT_WARN("Invalid format for ipato_addx/delx. " |
1120 | "Use <ip addr>/<mask bits>\n"); | 1162 | "Use <ip addr>/<mask bits>\n"); |
1121 | return -EINVAL; | 1163 | return -EINVAL; |
@@ -1127,7 +1169,12 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto, | |||
1127 | } | 1169 | } |
1128 | start = end + 1; | 1170 | start = end + 1; |
1129 | *mask_bits = simple_strtoul(start, &tmp, 10); | 1171 | *mask_bits = simple_strtoul(start, &tmp, 10); |
1130 | 1172 | if (!strlen(start) || | |
1173 | (tmp == start) || | ||
1174 | (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) { | ||
1175 | PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n"); | ||
1176 | return -EINVAL; | ||
1177 | } | ||
1131 | return 0; | 1178 | return 0; |
1132 | } | 1179 | } |
1133 | 1180 | ||
@@ -1698,11 +1745,16 @@ qeth_create_device_attributes(struct device *dev) | |||
1698 | sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); | 1745 | sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); |
1699 | sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group); | 1746 | sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group); |
1700 | sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); | 1747 | sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); |
1748 | return ret; | ||
1701 | } | 1749 | } |
1702 | if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group))) | 1750 | if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group))){ |
1751 | sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); | ||
1752 | sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group); | ||
1753 | sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group); | ||
1754 | sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group); | ||
1703 | return ret; | 1755 | return ret; |
1704 | 1756 | } | |
1705 | return ret; | 1757 | return 0; |
1706 | } | 1758 | } |
1707 | 1759 | ||
1708 | void | 1760 | void |
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index 593f298142c1..14504afb044e 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h | |||
@@ -24,7 +24,7 @@ static inline struct qeth_hdr_tso * | |||
24 | qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) | 24 | qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) |
25 | { | 25 | { |
26 | QETH_DBF_TEXT(trace, 5, "tsoprsk"); | 26 | QETH_DBF_TEXT(trace, 5, "tsoprsk"); |
27 | return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso)); | 27 | return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_tso)); |
28 | } | 28 | } |
29 | 29 | ||
30 | /** | 30 | /** |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 681dea8f9532..ca5bfb6914d2 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -251,6 +251,44 @@ static struct super_operations ext2_sops = { | |||
251 | #endif | 251 | #endif |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) | ||
255 | { | ||
256 | __u32 *objp = vobjp; | ||
257 | unsigned long ino = objp[0]; | ||
258 | __u32 generation = objp[1]; | ||
259 | struct inode *inode; | ||
260 | struct dentry *result; | ||
261 | |||
262 | if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO) | ||
263 | return ERR_PTR(-ESTALE); | ||
264 | if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count)) | ||
265 | return ERR_PTR(-ESTALE); | ||
266 | |||
267 | /* iget isn't really right if the inode is currently unallocated!! | ||
268 | * ext2_read_inode currently does appropriate checks, but | ||
269 | * it might be "neater" to call ext2_get_inode first and check | ||
270 | * if the inode is valid..... | ||
271 | */ | ||
272 | inode = iget(sb, ino); | ||
273 | if (inode == NULL) | ||
274 | return ERR_PTR(-ENOMEM); | ||
275 | if (is_bad_inode(inode) || | ||
276 | (generation && inode->i_generation != generation)) { | ||
277 | /* we didn't find the right inode.. */ | ||
278 | iput(inode); | ||
279 | return ERR_PTR(-ESTALE); | ||
280 | } | ||
281 | /* now to find a dentry. | ||
282 | * If possible, get a well-connected one | ||
283 | */ | ||
284 | result = d_alloc_anon(inode); | ||
285 | if (!result) { | ||
286 | iput(inode); | ||
287 | return ERR_PTR(-ENOMEM); | ||
288 | } | ||
289 | return result; | ||
290 | } | ||
291 | |||
254 | /* Yes, most of these are left as NULL!! | 292 | /* Yes, most of these are left as NULL!! |
255 | * A NULL value implies the default, which works with ext2-like file | 293 | * A NULL value implies the default, which works with ext2-like file |
256 | * systems, but can be improved upon. | 294 | * systems, but can be improved upon. |
@@ -258,6 +296,7 @@ static struct super_operations ext2_sops = { | |||
258 | */ | 296 | */ |
259 | static struct export_operations ext2_export_ops = { | 297 | static struct export_operations ext2_export_ops = { |
260 | .get_parent = ext2_get_parent, | 298 | .get_parent = ext2_get_parent, |
299 | .get_dentry = ext2_get_dentry, | ||
261 | }; | 300 | }; |
262 | 301 | ||
263 | static unsigned long get_sb_block(void **data) | 302 | static unsigned long get_sb_block(void **data) |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 0f0b1eadb98d..84be02e93652 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -925,7 +925,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
925 | set_buffer_new(bh_result); | 925 | set_buffer_new(bh_result); |
926 | got_it: | 926 | got_it: |
927 | map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); | 927 | map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); |
928 | if (blocks_to_boundary == 0) | 928 | if (count > blocks_to_boundary) |
929 | set_buffer_boundary(bh_result); | 929 | set_buffer_boundary(bh_result); |
930 | err = count; | 930 | err = count; |
931 | /* Clean up and exit */ | 931 | /* Clean up and exit */ |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 813d589cc6c0..3559086eee5f 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -554,6 +554,47 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
554 | return 0; | 554 | return 0; |
555 | } | 555 | } |
556 | 556 | ||
557 | |||
558 | static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) | ||
559 | { | ||
560 | __u32 *objp = vobjp; | ||
561 | unsigned long ino = objp[0]; | ||
562 | __u32 generation = objp[1]; | ||
563 | struct inode *inode; | ||
564 | struct dentry *result; | ||
565 | |||
566 | if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO) | ||
567 | return ERR_PTR(-ESTALE); | ||
568 | if (ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) | ||
569 | return ERR_PTR(-ESTALE); | ||
570 | |||
571 | /* iget isn't really right if the inode is currently unallocated!! | ||
572 | * | ||
573 | * ext3_read_inode will return a bad_inode if the inode had been | ||
574 | * deleted, so we should be safe. | ||
575 | * | ||
576 | * Currently we don't know the generation for parent directory, so | ||
577 | * a generation of 0 means "accept any" | ||
578 | */ | ||
579 | inode = iget(sb, ino); | ||
580 | if (inode == NULL) | ||
581 | return ERR_PTR(-ENOMEM); | ||
582 | if (is_bad_inode(inode) || | ||
583 | (generation && inode->i_generation != generation)) { | ||
584 | iput(inode); | ||
585 | return ERR_PTR(-ESTALE); | ||
586 | } | ||
587 | /* now to find a dentry. | ||
588 | * If possible, get a well-connected one | ||
589 | */ | ||
590 | result = d_alloc_anon(inode); | ||
591 | if (!result) { | ||
592 | iput(inode); | ||
593 | return ERR_PTR(-ENOMEM); | ||
594 | } | ||
595 | return result; | ||
596 | } | ||
597 | |||
557 | #ifdef CONFIG_QUOTA | 598 | #ifdef CONFIG_QUOTA |
558 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") | 599 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") |
559 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 600 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
@@ -622,6 +663,7 @@ static struct super_operations ext3_sops = { | |||
622 | 663 | ||
623 | static struct export_operations ext3_export_ops = { | 664 | static struct export_operations ext3_export_ops = { |
624 | .get_parent = ext3_get_parent, | 665 | .get_parent = ext3_get_parent, |
666 | .get_dentry = ext3_get_dentry, | ||
625 | }; | 667 | }; |
626 | 668 | ||
627 | enum { | 669 | enum { |
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index c19bd476e8ec..e52cef526d90 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -252,6 +252,11 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, | |||
252 | union jffs2_node_union *node; | 252 | union jffs2_node_union *node; |
253 | struct jffs2_eraseblock *jeb; | 253 | struct jffs2_eraseblock *jeb; |
254 | 254 | ||
255 | if (c->summary->sum_size == JFFS2_SUMMARY_NOSUM_SIZE) { | ||
256 | dbg_summary("Summary is disabled for this jeb! Skipping summary info!\n"); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
255 | node = invecs[0].iov_base; | 260 | node = invecs[0].iov_base; |
256 | jeb = &c->blocks[ofs / c->sector_size]; | 261 | jeb = &c->blocks[ofs / c->sector_size]; |
257 | ofs -= jeb->offset; | 262 | ofs -= jeb->offset; |
diff --git a/include/asm-alpha/Kbuild b/include/asm-alpha/Kbuild index e57fd57538b8..2b06b3bad5ff 100644 --- a/include/asm-alpha/Kbuild +++ b/include/asm-alpha/Kbuild | |||
@@ -1,5 +1,5 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | unifdef-y += console.h fpu.h sysinfo.h | 3 | unifdef-y += console.h fpu.h sysinfo.h compiler.h |
4 | 4 | ||
5 | header-y += gentrap.h regdef.h pal.h reg.h | 5 | header-y += gentrap.h regdef.h pal.h reg.h |
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h index 00c6f57ad9a7..d2768cc3d7a4 100644 --- a/include/asm-alpha/compiler.h +++ b/include/asm-alpha/compiler.h | |||
@@ -90,6 +90,7 @@ | |||
90 | __asm__("stw %1,%0" : "=m"(mem) : "r"(val)) | 90 | __asm__("stw %1,%0" : "=m"(mem) : "r"(val)) |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #ifdef __KERNEL__ | ||
93 | /* Some idiots over in <linux/compiler.h> thought inline should imply | 94 | /* Some idiots over in <linux/compiler.h> thought inline should imply |
94 | always_inline. This breaks stuff. We'll include this file whenever | 95 | always_inline. This breaks stuff. We'll include this file whenever |
95 | we run into such problems. */ | 96 | we run into such problems. */ |
@@ -101,4 +102,6 @@ | |||
101 | #undef __always_inline | 102 | #undef __always_inline |
102 | #define __always_inline inline __attribute__((always_inline)) | 103 | #define __always_inline inline __attribute__((always_inline)) |
103 | 104 | ||
105 | #endif /* __KERNEL__ */ | ||
106 | |||
104 | #endif /* __ALPHA_COMPILER_H */ | 107 | #endif /* __ALPHA_COMPILER_H */ |
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index 8c7cd50d4eae..d2bed3cb33ff 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ALPHA_PAGE_H | 1 | #ifndef _ALPHA_PAGE_H |
2 | #define _ALPHA_PAGE_H | 2 | #define _ALPHA_PAGE_H |
3 | 3 | ||
4 | #ifdef __KERNEL__ | ||
5 | |||
4 | #include <asm/pal.h> | 6 | #include <asm/pal.h> |
5 | 7 | ||
6 | /* PAGE_SHIFT determines the page size */ | 8 | /* PAGE_SHIFT determines the page size */ |
@@ -8,8 +10,6 @@ | |||
8 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | 10 | #define PAGE_SIZE (1UL << PAGE_SHIFT) |
9 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 11 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
10 | 12 | ||
11 | #ifdef __KERNEL__ | ||
12 | |||
13 | #ifndef __ASSEMBLY__ | 13 | #ifndef __ASSEMBLY__ |
14 | 14 | ||
15 | #define STRICT_MM_TYPECHECKS | 15 | #define STRICT_MM_TYPECHECKS |
@@ -92,9 +92,9 @@ typedef unsigned long pgprot_t; | |||
92 | 92 | ||
93 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 93 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ |
94 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 94 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
95 | #endif /* __KERNEL__ */ | ||
96 | 95 | ||
97 | #include <asm-generic/memory_model.h> | 96 | #include <asm-generic/memory_model.h> |
98 | #include <asm-generic/page.h> | 97 | #include <asm-generic/page.h> |
99 | 98 | ||
99 | #endif /* __KERNEL__ */ | ||
100 | #endif /* _ALPHA_PAGE_H */ | 100 | #endif /* _ALPHA_PAGE_H */ |
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d983b74e4d9f..fc1c8ddae149 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h | |||
@@ -324,6 +324,8 @@ | |||
324 | #define __NR_vmsplice 316 | 324 | #define __NR_vmsplice 316 |
325 | #define __NR_move_pages 317 | 325 | #define __NR_move_pages 317 |
326 | 326 | ||
327 | #ifdef __KERNEL__ | ||
328 | |||
327 | #define NR_syscalls 318 | 329 | #define NR_syscalls 318 |
328 | 330 | ||
329 | /* | 331 | /* |
@@ -423,8 +425,6 @@ __asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ | |||
423 | __syscall_return(type,__res); \ | 425 | __syscall_return(type,__res); \ |
424 | } | 426 | } |
425 | 427 | ||
426 | #ifdef __KERNEL__ | ||
427 | |||
428 | #define __ARCH_WANT_IPC_PARSE_VERSION | 428 | #define __ARCH_WANT_IPC_PARSE_VERSION |
429 | #define __ARCH_WANT_OLD_READDIR | 429 | #define __ARCH_WANT_OLD_READDIR |
430 | #define __ARCH_WANT_OLD_STAT | 430 | #define __ARCH_WANT_OLD_STAT |
diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild index 85d6f8005eb4..f1cb00f39c22 100644 --- a/include/asm-ia64/Kbuild +++ b/include/asm-ia64/Kbuild | |||
@@ -4,4 +4,4 @@ header-y += break.h fpu.h fpswa.h gcc_intrin.h ia64regs.h \ | |||
4 | intel_intrin.h intrinsics.h perfmon_default_smpl.h \ | 4 | intel_intrin.h intrinsics.h perfmon_default_smpl.h \ |
5 | ptrace_offsets.h rse.h setup.h ucontext.h | 5 | ptrace_offsets.h rse.h setup.h ucontext.h |
6 | 6 | ||
7 | unifdef-y += perfmon.h | 7 | unifdef-y += perfmon.h ustack.h |
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index f5a949ec6e1e..947cb72b520e 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h | |||
@@ -7,6 +7,7 @@ | |||
7 | * David Mosberger-Tang <davidm@hpl.hp.com> | 7 | * David Mosberger-Tang <davidm@hpl.hp.com> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | # ifdef __KERNEL__ | ||
10 | 11 | ||
11 | #include <asm/intrinsics.h> | 12 | #include <asm/intrinsics.h> |
12 | #include <asm/types.h> | 13 | #include <asm/types.h> |
@@ -64,7 +65,6 @@ | |||
64 | # define __pa(x) ((x) - PAGE_OFFSET) | 65 | # define __pa(x) ((x) - PAGE_OFFSET) |
65 | # define __va(x) ((x) + PAGE_OFFSET) | 66 | # define __va(x) ((x) + PAGE_OFFSET) |
66 | #else /* !__ASSEMBLY */ | 67 | #else /* !__ASSEMBLY */ |
67 | # ifdef __KERNEL__ | ||
68 | # define STRICT_MM_TYPECHECKS | 68 | # define STRICT_MM_TYPECHECKS |
69 | 69 | ||
70 | extern void clear_page (void *page); | 70 | extern void clear_page (void *page); |
@@ -174,7 +174,6 @@ get_order (unsigned long size) | |||
174 | return order; | 174 | return order; |
175 | } | 175 | } |
176 | 176 | ||
177 | # endif /* __KERNEL__ */ | ||
178 | #endif /* !__ASSEMBLY__ */ | 177 | #endif /* !__ASSEMBLY__ */ |
179 | 178 | ||
180 | #ifdef STRICT_MM_TYPECHECKS | 179 | #ifdef STRICT_MM_TYPECHECKS |
@@ -228,4 +227,5 @@ get_order (unsigned long size) | |||
228 | (((current->personality & READ_IMPLIES_EXEC) != 0) \ | 227 | (((current->personality & READ_IMPLIES_EXEC) != 0) \ |
229 | ? VM_EXEC : 0)) | 228 | ? VM_EXEC : 0)) |
230 | 229 | ||
230 | # endif /* __KERNEL__ */ | ||
231 | #endif /* _ASM_IA64_PAGE_H */ | 231 | #endif /* _ASM_IA64_PAGE_H */ |
diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h index 415abb23b210..1414316efd40 100644 --- a/include/asm-ia64/ptrace.h +++ b/include/asm-ia64/ptrace.h | |||
@@ -56,6 +56,8 @@ | |||
56 | 56 | ||
57 | 57 | ||
58 | #include <asm/fpu.h> | 58 | #include <asm/fpu.h> |
59 | |||
60 | #ifdef __KERNEL__ | ||
59 | #ifndef ASM_OFFSETS_C | 61 | #ifndef ASM_OFFSETS_C |
60 | #include <asm/asm-offsets.h> | 62 | #include <asm/asm-offsets.h> |
61 | #endif | 63 | #endif |
@@ -79,10 +81,9 @@ | |||
79 | 81 | ||
80 | #define KERNEL_STACK_SIZE IA64_STK_OFFSET | 82 | #define KERNEL_STACK_SIZE IA64_STK_OFFSET |
81 | 83 | ||
82 | #ifndef __ASSEMBLY__ | 84 | #endif /* __KERNEL__ */ |
83 | 85 | ||
84 | #include <asm/current.h> | 86 | #ifndef __ASSEMBLY__ |
85 | #include <asm/page.h> | ||
86 | 87 | ||
87 | /* | 88 | /* |
88 | * This struct defines the way the registers are saved on system | 89 | * This struct defines the way the registers are saved on system |
@@ -229,6 +230,9 @@ struct switch_stack { | |||
229 | 230 | ||
230 | #ifdef __KERNEL__ | 231 | #ifdef __KERNEL__ |
231 | 232 | ||
233 | #include <asm/current.h> | ||
234 | #include <asm/page.h> | ||
235 | |||
232 | #define __ARCH_SYS_PTRACE 1 | 236 | #define __ARCH_SYS_PTRACE 1 |
233 | 237 | ||
234 | /* | 238 | /* |
diff --git a/include/asm-ia64/ustack.h b/include/asm-ia64/ustack.h index da55c91246e3..a349467913ea 100644 --- a/include/asm-ia64/ustack.h +++ b/include/asm-ia64/ustack.h | |||
@@ -5,12 +5,15 @@ | |||
5 | * Constants for the user stack size | 5 | * Constants for the user stack size |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #ifdef __KERNEL__ | ||
8 | #include <asm/page.h> | 9 | #include <asm/page.h> |
9 | 10 | ||
10 | /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */ | 11 | /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */ |
11 | #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2) | 12 | #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2) |
12 | /* Make a default stack size of 2GB */ | ||
13 | #define DEFAULT_USER_STACK_SIZE (1UL << 31) | ||
14 | #define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) | 13 | #define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) |
14 | #endif | ||
15 | |||
16 | /* Make a default stack size of 2GiB */ | ||
17 | #define DEFAULT_USER_STACK_SIZE (1UL << 31) | ||
15 | 18 | ||
16 | #endif /* _ASM_IA64_USTACK_H */ | 19 | #endif /* _ASM_IA64_USTACK_H */ |
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h index 7f1ef99fd1e1..c00dd2b3dc50 100644 --- a/include/asm-s390/debug.h +++ b/include/asm-s390/debug.h | |||
@@ -10,7 +10,6 @@ | |||
10 | #define DEBUG_H | 10 | #define DEBUG_H |
11 | 11 | ||
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/string.h> | ||
14 | 13 | ||
15 | /* Note: | 14 | /* Note: |
16 | * struct __debug_entry must be defined outside of #ifdef __KERNEL__ | 15 | * struct __debug_entry must be defined outside of #ifdef __KERNEL__ |
@@ -35,6 +34,7 @@ struct __debug_entry{ | |||
35 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ | 34 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ |
36 | 35 | ||
37 | #ifdef __KERNEL__ | 36 | #ifdef __KERNEL__ |
37 | #include <linux/string.h> | ||
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/time.h> | 40 | #include <linux/time.h> |
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h index 710646e64f7d..c0d629d61d3e 100644 --- a/include/asm-s390/elf.h +++ b/include/asm-s390/elf.h | |||
@@ -93,19 +93,6 @@ | |||
93 | #define R_390_NUM 61 | 93 | #define R_390_NUM 61 |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * ELF register definitions.. | ||
97 | */ | ||
98 | |||
99 | #include <linux/sched.h> /* for task_struct */ | ||
100 | #include <asm/ptrace.h> | ||
101 | #include <asm/user.h> | ||
102 | #include <asm/system.h> /* for save_access_regs */ | ||
103 | |||
104 | |||
105 | typedef s390_fp_regs elf_fpregset_t; | ||
106 | typedef s390_regs elf_gregset_t; | ||
107 | |||
108 | /* | ||
109 | * These are used to set parameters in the core dumps. | 96 | * These are used to set parameters in the core dumps. |
110 | */ | 97 | */ |
111 | #ifndef __s390x__ | 98 | #ifndef __s390x__ |
@@ -117,6 +104,20 @@ typedef s390_regs elf_gregset_t; | |||
117 | #define ELF_ARCH EM_S390 | 104 | #define ELF_ARCH EM_S390 |
118 | 105 | ||
119 | /* | 106 | /* |
107 | * ELF register definitions.. | ||
108 | */ | ||
109 | |||
110 | #include <asm/ptrace.h> | ||
111 | #include <asm/user.h> | ||
112 | |||
113 | typedef s390_fp_regs elf_fpregset_t; | ||
114 | typedef s390_regs elf_gregset_t; | ||
115 | |||
116 | #ifdef __KERNEL__ | ||
117 | #include <linux/sched.h> /* for task_struct */ | ||
118 | #include <asm/system.h> /* for save_access_regs */ | ||
119 | |||
120 | /* | ||
120 | * This is used to ensure we don't load something for the wrong architecture. | 121 | * This is used to ensure we don't load something for the wrong architecture. |
121 | */ | 122 | */ |
122 | #define elf_check_arch(x) \ | 123 | #define elf_check_arch(x) \ |
@@ -198,7 +199,6 @@ static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) | |||
198 | 199 | ||
199 | #define ELF_PLATFORM (NULL) | 200 | #define ELF_PLATFORM (NULL) |
200 | 201 | ||
201 | #ifdef __KERNEL__ | ||
202 | #ifndef __s390x__ | 202 | #ifndef __s390x__ |
203 | #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) | 203 | #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) |
204 | #else /* __s390x__ */ | 204 | #else /* __s390x__ */ |
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h index b4f8f4a41a6e..a406fcb1e924 100644 --- a/include/asm-x86_64/elf.h +++ b/include/asm-x86_64/elf.h | |||
@@ -7,8 +7,6 @@ | |||
7 | 7 | ||
8 | #include <asm/ptrace.h> | 8 | #include <asm/ptrace.h> |
9 | #include <asm/user.h> | 9 | #include <asm/user.h> |
10 | #include <asm/processor.h> | ||
11 | #include <asm/compat.h> | ||
12 | 10 | ||
13 | /* x86-64 relocation types */ | 11 | /* x86-64 relocation types */ |
14 | #define R_X86_64_NONE 0 /* No reloc */ | 12 | #define R_X86_64_NONE 0 /* No reloc */ |
@@ -39,18 +37,23 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |||
39 | typedef struct user_i387_struct elf_fpregset_t; | 37 | typedef struct user_i387_struct elf_fpregset_t; |
40 | 38 | ||
41 | /* | 39 | /* |
42 | * This is used to ensure we don't load something for the wrong architecture. | ||
43 | */ | ||
44 | #define elf_check_arch(x) \ | ||
45 | ((x)->e_machine == EM_X86_64) | ||
46 | |||
47 | /* | ||
48 | * These are used to set parameters in the core dumps. | 40 | * These are used to set parameters in the core dumps. |
49 | */ | 41 | */ |
50 | #define ELF_CLASS ELFCLASS64 | 42 | #define ELF_CLASS ELFCLASS64 |
51 | #define ELF_DATA ELFDATA2LSB | 43 | #define ELF_DATA ELFDATA2LSB |
52 | #define ELF_ARCH EM_X86_64 | 44 | #define ELF_ARCH EM_X86_64 |
53 | 45 | ||
46 | #ifdef __KERNEL__ | ||
47 | #include <asm/processor.h> | ||
48 | #include <asm/compat.h> | ||
49 | |||
50 | /* | ||
51 | * This is used to ensure we don't load something for the wrong architecture. | ||
52 | */ | ||
53 | #define elf_check_arch(x) \ | ||
54 | ((x)->e_machine == EM_X86_64) | ||
55 | |||
56 | |||
54 | /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx | 57 | /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx |
55 | contains a pointer to a function which might be registered using `atexit'. | 58 | contains a pointer to a function which might be registered using `atexit'. |
56 | This provides a mean for the dynamic linker to call DT_FINI functions for | 59 | This provides a mean for the dynamic linker to call DT_FINI functions for |
@@ -141,7 +144,6 @@ typedef struct user_i387_struct elf_fpregset_t; | |||
141 | /* I'm not sure if we can use '-' here */ | 144 | /* I'm not sure if we can use '-' here */ |
142 | #define ELF_PLATFORM ("x86_64") | 145 | #define ELF_PLATFORM ("x86_64") |
143 | 146 | ||
144 | #ifdef __KERNEL__ | ||
145 | extern void set_personality_64bit(void); | 147 | extern void set_personality_64bit(void); |
146 | #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit() | 148 | #define SET_PERSONALITY(ex, ibcs2) set_personality_64bit() |
147 | /* | 149 | /* |
diff --git a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h index cef7a7d51b7e..3ede2a61973a 100644 --- a/include/asm-x86_64/signal.h +++ b/include/asm-x86_64/signal.h | |||
@@ -3,13 +3,13 @@ | |||
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | 4 | #ifndef __ASSEMBLY__ |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/linkage.h> | ||
7 | #include <linux/time.h> | 6 | #include <linux/time.h> |
8 | 7 | ||
9 | /* Avoid too many header ordering problems. */ | 8 | /* Avoid too many header ordering problems. */ |
10 | struct siginfo; | 9 | struct siginfo; |
11 | 10 | ||
12 | #ifdef __KERNEL__ | 11 | #ifdef __KERNEL__ |
12 | #include <linux/linkage.h> | ||
13 | /* Most things should be clean enough to redefine this at will, if care | 13 | /* Most things should be clean enough to redefine this at will, if care |
14 | is taken to make libc match. */ | 14 | is taken to make libc match. */ |
15 | 15 | ||
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 2d89d309a2a8..80fd48e84bbb 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
@@ -620,6 +620,8 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice) | |||
620 | #define __NR_move_pages 279 | 620 | #define __NR_move_pages 279 |
621 | __SYSCALL(__NR_move_pages, sys_move_pages) | 621 | __SYSCALL(__NR_move_pages, sys_move_pages) |
622 | 622 | ||
623 | #ifdef __KERNEL__ | ||
624 | |||
623 | #define __NR_syscall_max __NR_move_pages | 625 | #define __NR_syscall_max __NR_move_pages |
624 | 626 | ||
625 | #ifndef __NO_STUBS | 627 | #ifndef __NO_STUBS |
@@ -744,8 +746,6 @@ __syscall_return(type,__res); \ | |||
744 | 746 | ||
745 | #else /* __KERNEL_SYSCALLS__ */ | 747 | #else /* __KERNEL_SYSCALLS__ */ |
746 | 748 | ||
747 | #ifdef __KERNEL__ | ||
748 | |||
749 | #include <linux/syscalls.h> | 749 | #include <linux/syscalls.h> |
750 | #include <asm/ptrace.h> | 750 | #include <asm/ptrace.h> |
751 | 751 | ||
@@ -821,8 +821,6 @@ asmlinkage long sys_fork(struct pt_regs regs); | |||
821 | asmlinkage long sys_vfork(struct pt_regs regs); | 821 | asmlinkage long sys_vfork(struct pt_regs regs); |
822 | asmlinkage long sys_pipe(int *fildes); | 822 | asmlinkage long sys_pipe(int *fildes); |
823 | 823 | ||
824 | #endif /* __KERNEL_SYSCALLS__ */ | ||
825 | |||
826 | #ifndef __ASSEMBLY__ | 824 | #ifndef __ASSEMBLY__ |
827 | 825 | ||
828 | #include <linux/linkage.h> | 826 | #include <linux/linkage.h> |
@@ -838,9 +836,9 @@ asmlinkage long sys_rt_sigaction(int sig, | |||
838 | struct sigaction __user *oact, | 836 | struct sigaction __user *oact, |
839 | size_t sigsetsize); | 837 | size_t sigsetsize); |
840 | 838 | ||
841 | #endif | 839 | #endif /* __ASSEMBLY__ */ |
842 | 840 | ||
843 | #endif | 841 | #endif /* __KERNEL_SYSCALLS__ */ |
844 | 842 | ||
845 | /* | 843 | /* |
846 | * "Conditional" syscalls | 844 | * "Conditional" syscalls |
@@ -850,6 +848,8 @@ asmlinkage long sys_rt_sigaction(int sig, | |||
850 | */ | 848 | */ |
851 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") | 849 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") |
852 | 850 | ||
853 | #endif | 851 | #endif /* __NO_STUBS */ |
854 | 852 | ||
855 | #endif | 853 | #endif /* __KERNEL__ */ |
854 | |||
855 | #endif /* _ASM_X86_64_UNISTD_H_ */ | ||
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h index a85e16f56d73..146b24402a5f 100644 --- a/include/asm-x86_64/vsyscall.h +++ b/include/asm-x86_64/vsyscall.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef _ASM_X86_64_VSYSCALL_H_ | 1 | #ifndef _ASM_X86_64_VSYSCALL_H_ |
2 | #define _ASM_X86_64_VSYSCALL_H_ | 2 | #define _ASM_X86_64_VSYSCALL_H_ |
3 | 3 | ||
4 | #include <linux/seqlock.h> | ||
5 | |||
6 | enum vsyscall_num { | 4 | enum vsyscall_num { |
7 | __NR_vgettimeofday, | 5 | __NR_vgettimeofday, |
8 | __NR_vtime, | 6 | __NR_vtime, |
@@ -14,6 +12,7 @@ enum vsyscall_num { | |||
14 | #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) | 12 | #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) |
15 | 13 | ||
16 | #ifdef __KERNEL__ | 14 | #ifdef __KERNEL__ |
15 | #include <linux/seqlock.h> | ||
17 | 16 | ||
18 | #define __section_vxtime __attribute__ ((unused, __section__ (".vxtime"), aligned(16))) | 17 | #define __section_vxtime __attribute__ ((unused, __section__ (".vxtime"), aligned(16))) |
19 | #define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16))) | 18 | #define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16))) |
diff --git a/init/Kconfig b/init/Kconfig index a099fc6526d9..9a7656f0b5ec 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -182,23 +182,6 @@ config TASK_DELAY_ACCT | |||
182 | 182 | ||
183 | Say N if unsure. | 183 | Say N if unsure. |
184 | 184 | ||
185 | config SYSCTL | ||
186 | bool "Sysctl support" if EMBEDDED | ||
187 | default y | ||
188 | ---help--- | ||
189 | The sysctl interface provides a means of dynamically changing | ||
190 | certain kernel parameters and variables on the fly without requiring | ||
191 | a recompile of the kernel or reboot of the system. The primary | ||
192 | interface consists of a system call, but if you say Y to "/proc | ||
193 | file system support", a tree of modifiable sysctl entries will be | ||
194 | generated beneath the /proc/sys directory. They are explained in the | ||
195 | files in <file:Documentation/sysctl/>. Note that enabling this | ||
196 | option will enlarge the kernel by at least 8 KB. | ||
197 | |||
198 | As it is generally a good thing, you should say Y here unless | ||
199 | building a kernel for install/rescue disks or your system is very | ||
200 | limited in memory. | ||
201 | |||
202 | config AUDIT | 185 | config AUDIT |
203 | bool "Auditing support" | 186 | bool "Auditing support" |
204 | depends on NET | 187 | depends on NET |
@@ -261,13 +244,6 @@ config RELAY | |||
261 | 244 | ||
262 | source "usr/Kconfig" | 245 | source "usr/Kconfig" |
263 | 246 | ||
264 | config UID16 | ||
265 | bool "Enable 16-bit UID system calls" if EMBEDDED | ||
266 | depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) | ||
267 | default y | ||
268 | help | ||
269 | This enables the legacy 16-bit UID syscall wrappers. | ||
270 | |||
271 | config CC_OPTIMIZE_FOR_SIZE | 247 | config CC_OPTIMIZE_FOR_SIZE |
272 | bool "Optimize for size (Look out for broken compilers!)" | 248 | bool "Optimize for size (Look out for broken compilers!)" |
273 | default y | 249 | default y |
@@ -289,6 +265,30 @@ menuconfig EMBEDDED | |||
289 | environments which can tolerate a "non-standard" kernel. | 265 | environments which can tolerate a "non-standard" kernel. |
290 | Only use this if you really know what you are doing. | 266 | Only use this if you really know what you are doing. |
291 | 267 | ||
268 | config UID16 | ||
269 | bool "Enable 16-bit UID system calls" if EMBEDDED | ||
270 | depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) | ||
271 | default y | ||
272 | help | ||
273 | This enables the legacy 16-bit UID syscall wrappers. | ||
274 | |||
275 | config SYSCTL | ||
276 | bool "Sysctl support" if EMBEDDED | ||
277 | default y | ||
278 | ---help--- | ||
279 | The sysctl interface provides a means of dynamically changing | ||
280 | certain kernel parameters and variables on the fly without requiring | ||
281 | a recompile of the kernel or reboot of the system. The primary | ||
282 | interface consists of a system call, but if you say Y to "/proc | ||
283 | file system support", a tree of modifiable sysctl entries will be | ||
284 | generated beneath the /proc/sys directory. They are explained in the | ||
285 | files in <file:Documentation/sysctl/>. Note that enabling this | ||
286 | option will enlarge the kernel by at least 8 KB. | ||
287 | |||
288 | As it is generally a good thing, you should say Y here unless | ||
289 | building a kernel for install/rescue disks or your system is very | ||
290 | limited in memory. | ||
291 | |||
292 | config KALLSYMS | 292 | config KALLSYMS |
293 | bool "Load all symbols for debugging/kksymoops" if EMBEDDED | 293 | bool "Load all symbols for debugging/kksymoops" if EMBEDDED |
294 | default y | 294 | default y |
@@ -363,10 +363,6 @@ config BASE_FULL | |||
363 | kernel data structures. This saves memory on small machines, | 363 | kernel data structures. This saves memory on small machines, |
364 | but may reduce performance. | 364 | but may reduce performance. |
365 | 365 | ||
366 | config RT_MUTEXES | ||
367 | boolean | ||
368 | select PLIST | ||
369 | |||
370 | config FUTEX | 366 | config FUTEX |
371 | bool "Enable futex support" if EMBEDDED | 367 | bool "Enable futex support" if EMBEDDED |
372 | default y | 368 | default y |
@@ -414,6 +410,10 @@ config VM_EVENT_COUNTERS | |||
414 | 410 | ||
415 | endmenu # General setup | 411 | endmenu # General setup |
416 | 412 | ||
413 | config RT_MUTEXES | ||
414 | boolean | ||
415 | select PLIST | ||
416 | |||
417 | config TINY_SHMEM | 417 | config TINY_SHMEM |
418 | default !SHMEM | 418 | default !SHMEM |
419 | bool | 419 | bool |
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 872f91ba2ce8..35f10f7ff94a 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c | |||
@@ -63,8 +63,7 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) | |||
63 | desc->chip->enable(irq); | 63 | desc->chip->enable(irq); |
64 | 64 | ||
65 | if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { | 65 | if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { |
66 | desc->status &= ~IRQ_PENDING; | 66 | desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY; |
67 | desc->status = status | IRQ_REPLAY; | ||
68 | 67 | ||
69 | if (!desc->chip || !desc->chip->retrigger || | 68 | if (!desc->chip || !desc->chip->retrigger || |
70 | !desc->chip->retrigger(irq)) { | 69 | !desc->chip->retrigger(irq)) { |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 1d32defa38ab..5c470c57fb57 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -197,11 +197,12 @@ static void __call_usermodehelper(void *data) | |||
197 | { | 197 | { |
198 | struct subprocess_info *sub_info = data; | 198 | struct subprocess_info *sub_info = data; |
199 | pid_t pid; | 199 | pid_t pid; |
200 | int wait = sub_info->wait; | ||
200 | 201 | ||
201 | /* CLONE_VFORK: wait until the usermode helper has execve'd | 202 | /* CLONE_VFORK: wait until the usermode helper has execve'd |
202 | * successfully We need the data structures to stay around | 203 | * successfully We need the data structures to stay around |
203 | * until that is done. */ | 204 | * until that is done. */ |
204 | if (sub_info->wait) | 205 | if (wait) |
205 | pid = kernel_thread(wait_for_helper, sub_info, | 206 | pid = kernel_thread(wait_for_helper, sub_info, |
206 | CLONE_FS | CLONE_FILES | SIGCHLD); | 207 | CLONE_FS | CLONE_FILES | SIGCHLD); |
207 | else | 208 | else |
@@ -211,7 +212,7 @@ static void __call_usermodehelper(void *data) | |||
211 | if (pid < 0) { | 212 | if (pid < 0) { |
212 | sub_info->retval = pid; | 213 | sub_info->retval = pid; |
213 | complete(sub_info->complete); | 214 | complete(sub_info->complete); |
214 | } else if (!sub_info->wait) | 215 | } else if (!wait) |
215 | complete(sub_info->complete); | 216 | complete(sub_info->complete); |
216 | } | 217 | } |
217 | 218 | ||
diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst index aa9990a3ccd6..12e1daf875c8 100644 --- a/scripts/Makefile.headersinst +++ b/scripts/Makefile.headersinst | |||
@@ -93,14 +93,14 @@ STUBDEF=__ASM_STUB_`echo $@ | tr a-z. A-Z_`; \ | |||
93 | echo "\#ifndef $$STUBDEF" ; \ | 93 | echo "\#ifndef $$STUBDEF" ; \ |
94 | echo "\#define $$STUBDEF" ; \ | 94 | echo "\#define $$STUBDEF" ; \ |
95 | echo "\# if $(ARCHDEF)" ; \ | 95 | echo "\# if $(ARCHDEF)" ; \ |
96 | if [ -r $(srctree)/include/$(archasm)/$@ ]; then \ | 96 | if [ -r $(INSTALL_HDR_PATH)/include/$(archasm)/$@ ]; then \ |
97 | echo "\# include <$(archasm)/$@>" ; \ | 97 | echo "\# include <$(archasm)/$@>" ; \ |
98 | else \ | 98 | else \ |
99 | echo "\# error $(archasm)/$@ does not exist in" \ | 99 | echo "\# error $(archasm)/$@ does not exist in" \ |
100 | "the $(ARCH) architecture" ; \ | 100 | "the $(ARCH) architecture" ; \ |
101 | fi ; \ | 101 | fi ; \ |
102 | echo "\# elif $(ALTARCHDEF)" ; \ | 102 | echo "\# elif $(ALTARCHDEF)" ; \ |
103 | if [ -r $(srctree)/include/$(altarchasm)/$@ ]; then \ | 103 | if [ -r $(INSTALL_HDR_PATH)/include/$(altarchasm)/$@ ]; then \ |
104 | echo "\# include <$(altarchasm)/$@>" ; \ | 104 | echo "\# include <$(altarchasm)/$@>" ; \ |
105 | else \ | 105 | else \ |
106 | echo "\# error $(altarchasm)/$@ does not exist in" \ | 106 | echo "\# error $(altarchasm)/$@ does not exist in" \ |
@@ -149,7 +149,9 @@ endif | |||
149 | hdrinst := -rR -f $(srctree)/scripts/Makefile.headersinst obj | 149 | hdrinst := -rR -f $(srctree)/scripts/Makefile.headersinst obj |
150 | 150 | ||
151 | .PHONY: altarch-dir | 151 | .PHONY: altarch-dir |
152 | altarch-dir: | 152 | # All the files in the normal arch dir must be created first, since we test |
153 | # for their existence. | ||
154 | altarch-dir: $(subdir-y) $(header-y) $(unifdef-y) $(objhdr-y) | ||
153 | $(Q)$(MAKE) $(hdrinst)=include/asm-$(ALTARCH) dst=include/asm-$(ALTARCH) | 155 | $(Q)$(MAKE) $(hdrinst)=include/asm-$(ALTARCH) dst=include/asm-$(ALTARCH) |
154 | $(Q)$(MAKE) $(hdrinst)=include/asm dst=include/asm | 156 | $(Q)$(MAKE) $(hdrinst)=include/asm dst=include/asm |
155 | 157 | ||
diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 18ecd4d5df7f..060f4c563a5c 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host | |||
@@ -30,7 +30,7 @@ | |||
30 | # libkconfig.so as the executable conf. | 30 | # libkconfig.so as the executable conf. |
31 | # Note: Shared libraries consisting of C++ files are not supported | 31 | # Note: Shared libraries consisting of C++ files are not supported |
32 | 32 | ||
33 | __hostprogs := $(sort $(hostprogs-y)$(hostprogs-m)) | 33 | __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) |
34 | 34 | ||
35 | # hostprogs-y := tools/build may have been specified. Retreive directory | 35 | # hostprogs-y := tools/build may have been specified. Retreive directory |
36 | host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) | 36 | host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) |