From ba692f93e6c6d6f37934e5aee7de33dbf0a17edd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 17 Oct 2007 14:28:38 -0700 Subject: [PATCH] --- yaml --- r: 71066 b: refs/heads/master c: 7259888e84d5b6680c9d1f933654f4bdeed61700 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/filesystems/9p.txt | 22 +- trunk/arch/ia64/kernel/machine_kexec.c | 4 +- trunk/drivers/mmc/core/mmc.c | 3 +- trunk/drivers/mmc/host/at91_mci.c | 4 +- trunk/drivers/net/wireless/Kconfig | 6 - trunk/drivers/net/wireless/libertas/Makefile | 2 - trunk/drivers/net/wireless/libertas/defs.h | 2 - trunk/drivers/net/wireless/libertas/if_sdio.c | 1079 ----------------- trunk/drivers/net/wireless/libertas/if_sdio.h | 45 - trunk/fs/9p/fid.c | 157 +-- trunk/fs/9p/v9fs.c | 189 +-- trunk/fs/9p/v9fs.h | 38 +- trunk/fs/9p/vfs_file.c | 6 +- trunk/fs/9p/vfs_inode.c | 50 +- trunk/fs/9p/vfs_super.c | 19 +- trunk/include/linux/mmc/sdio_ids.h | 6 - trunk/include/net/9p/9p.h | 21 +- trunk/include/net/9p/client.h | 9 +- trunk/include/net/9p/conn.h | 4 +- trunk/include/net/9p/transport.h | 27 +- trunk/net/9p/Kconfig | 10 - trunk/net/9p/Makefile | 5 +- trunk/net/9p/client.c | 13 +- trunk/net/9p/conv.c | 32 +- trunk/net/9p/mod.c | 71 +- trunk/net/9p/mux.c | 5 +- trunk/net/9p/sysctl.c | 81 ++ trunk/net/9p/trans_fd.c | 419 +++---- 29 files changed, 497 insertions(+), 1834 deletions(-) delete mode 100644 trunk/drivers/net/wireless/libertas/if_sdio.c delete mode 100644 trunk/drivers/net/wireless/libertas/if_sdio.h create mode 100644 trunk/net/9p/sysctl.c diff --git a/[refs] b/[refs] index 844dc5b81729..67597f94d094 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9d8190f87b5458160ba75d05e8ad6abefbe48a26 +refs/heads/master: 7259888e84d5b6680c9d1f933654f4bdeed61700 diff --git a/trunk/Documentation/filesystems/9p.txt b/trunk/Documentation/filesystems/9p.txt index d6fd6c6e4244..cda6905cbe49 100644 --- a/trunk/Documentation/filesystems/9p.txt +++ b/trunk/Documentation/filesystems/9p.txt @@ -35,12 +35,12 @@ For remote file server: For Plan 9 From User Space applications (http://swtch.com/plan9) - mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER + mount -t 9p `namespace`/acme /mnt/9 -o proto=unix,uname=$USER OPTIONS ======= - trans=name select an alternative transport. Valid options are + proto=name select an alternative transport. Valid options are currently: unix - specifying a named pipe mount point tcp - specifying a normal TCP/IP connection @@ -68,9 +68,9 @@ OPTIONS 0x40 = display transport debug 0x80 = display allocation debug - rfdno=n the file descriptor for reading with trans=fd + rfdno=n the file descriptor for reading with proto=fd - wfdno=n the file descriptor for writing with trans=fd + wfdno=n the file descriptor for writing with proto=fd maxdata=n the number of bytes to use for 9p packet payload (msize) @@ -78,9 +78,9 @@ OPTIONS noextend force legacy mode (no 9p2000.u semantics) - dfltuid attempt to mount as a particular uid + uid attempt to mount as a particular uid - dfltgid attempt to mount with a particular gid + gid attempt to mount with a particular gid afid security channel - used by Plan 9 authentication protocols @@ -88,16 +88,6 @@ OPTIONS This can be used to share devices/named pipes/sockets between hosts. This functionality will be expanded in later versions. - access there are three access modes. - user = if a user tries to access a file on v9fs - filesystem for the first time, v9fs sends an - attach command (Tattach) for that user. - This is the default mode. - = allows only user with uid= to access - the files on the mounted filesystem - any = v9fs does single attach and performs all - operations as one user - RESOURCES ========= diff --git a/trunk/arch/ia64/kernel/machine_kexec.c b/trunk/arch/ia64/kernel/machine_kexec.c index 0dd3b2394cdd..d6cd45f4c6c7 100644 --- a/trunk/arch/ia64/kernel/machine_kexec.c +++ b/trunk/arch/ia64/kernel/machine_kexec.c @@ -17,6 +17,8 @@ #include #include #include + +#include #include #include #include @@ -127,7 +129,7 @@ void machine_kexec(struct kimage *image) void arch_crash_save_vmcoreinfo(void) { -#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE +#if defined(CONFIG_ARCH_DISCONTIGMEM_ENABLE) && defined(CONFIG_NUMA) VMCOREINFO_SYMBOL(pgdat_list); VMCOREINFO_LENGTH(pgdat_list, MAX_NUMNODES); diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index 68c0e3b2f0e8..65fe28860f54 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -213,8 +213,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), ext_csd_struct); - err = -EINVAL; - goto out; + return -EINVAL; } if (ext_csd_struct >= 2) { diff --git a/trunk/drivers/mmc/host/at91_mci.c b/trunk/drivers/mmc/host/at91_mci.c index 7a452c2ad1f9..6ba98a49612d 100644 --- a/trunk/drivers/mmc/host/at91_mci.c +++ b/trunk/drivers/mmc/host/at91_mci.c @@ -581,7 +581,9 @@ static void at91_mci_completed_command(struct at91mci_host *host) pr_debug("Status = %08X [%08X %08X %08X %08X]\n", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); - if (status & AT91_MCI_ERRORS) { + if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE | + AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE | + AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) { if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) { cmd->error = 0; } diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index dae5c8d5a318..5a6fdfd0f140 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -282,12 +282,6 @@ config LIBERTAS_CS ---help--- A driver for Marvell Libertas 8385 CompactFlash devices. -config LIBERTAS_SDIO - tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards" - depends on LIBERTAS && MMC - ---help--- - A driver for Marvell Libertas 8385 and 8686 SDIO devices. - config LIBERTAS_DEBUG bool "Enable full debugging output in the Libertas module." depends on LIBERTAS diff --git a/trunk/drivers/net/wireless/libertas/Makefile b/trunk/drivers/net/wireless/libertas/Makefile index 0e2787691f96..c469d569f090 100644 --- a/trunk/drivers/net/wireless/libertas/Makefile +++ b/trunk/drivers/net/wireless/libertas/Makefile @@ -7,9 +7,7 @@ libertas-objs := main.o wext.o \ usb8xxx-objs += if_usb.o libertas_cs-objs += if_cs.o -libertas_sdio-objs += if_sdio.o obj-$(CONFIG_LIBERTAS) += libertas.o obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o -obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o diff --git a/trunk/drivers/net/wireless/libertas/defs.h b/trunk/drivers/net/wireless/libertas/defs.h index 3a0c9beefcf8..7c5b7f7b45db 100644 --- a/trunk/drivers/net/wireless/libertas/defs.h +++ b/trunk/drivers/net/wireless/libertas/defs.h @@ -39,7 +39,6 @@ #define LBS_DEB_FW 0x00080000 #define LBS_DEB_THREAD 0x00100000 #define LBS_DEB_HEX 0x00200000 -#define LBS_DEB_SDIO 0x00400000 extern unsigned int libertas_debug; @@ -81,7 +80,6 @@ do { if ((libertas_debug & (grp)) == (grp)) \ #define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args) #define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args) #define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args) -#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " thread", fmt, ##args) #define lbs_pr_info(format, args...) \ printk(KERN_INFO DRV_NAME": " format, ## args) diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c deleted file mode 100644 index a8e17076e7de..000000000000 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * linux/drivers/net/wireless/libertas/if_sdio.c - * - * Copyright 2007 Pierre Ossman - * - * Inspired by if_cs.c, Copyright 2007 Holger Schurig - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This hardware has more or less no CMD53 support, so all registers - * must be accessed using sdio_readb()/sdio_writeb(). - * - * Transfers must be in one transaction or the firmware goes bonkers. - * This means that the transfer must either be small enough to do a - * byte based transfer or it must be padded to a multiple of the - * current block size. - * - * As SDIO is still new to the kernel, it is unfortunately common with - * bugs in the host controllers related to that. One such bug is that - * controllers cannot do transfers that aren't a multiple of 4 bytes. - * If you don't have time to fix the host controller driver, you can - * work around the problem by modifying if_sdio_host_to_card() and - * if_sdio_card_to_host() to pad the data. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "host.h" -#include "decl.h" -#include "defs.h" -#include "dev.h" -#include "if_sdio.h" - -static char *libertas_helper_name = NULL; -module_param_named(helper_name, libertas_helper_name, charp, 0644); - -static char *libertas_fw_name = NULL; -module_param_named(fw_name, libertas_fw_name, charp, 0644); - -static const struct sdio_device_id if_sdio_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, if_sdio_ids); - -struct if_sdio_model { - int model; - const char *helper; - const char *firmware; -}; - -static struct if_sdio_model if_sdio_models[] = { - { - /* 8385 */ - .model = 0x04, - .helper = "sd8385_helper.bin", - .firmware = "sd8385.bin", - }, - { - /* 8686 */ - .model = 0x0B, - .helper = "sd8686_helper.bin", - .firmware = "sd8686.bin", - }, -}; - -struct if_sdio_packet { - struct if_sdio_packet *next; - u16 nb; - u8 buffer[0] __attribute__((aligned(4))); -}; - -struct if_sdio_card { - struct sdio_func *func; - wlan_private *priv; - - int model; - unsigned long ioport; - - const char *helper; - const char *firmware; - - u8 buffer[65536]; - u8 int_cause; - u32 event; - - spinlock_t lock; - struct if_sdio_packet *packets; - struct work_struct packet_worker; -}; - -/********************************************************************/ -/* I/O */ -/********************************************************************/ - -static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err) -{ - int ret, reg; - u16 scratch; - - if (card->model == 0x04) - reg = IF_SDIO_SCRATCH_OLD; - else - reg = IF_SDIO_SCRATCH; - - scratch = sdio_readb(card->func, reg, &ret); - if (!ret) - scratch |= sdio_readb(card->func, reg + 1, &ret) << 8; - - if (err) - *err = ret; - - if (ret) - return 0xffff; - - return scratch; -} - -static int if_sdio_handle_cmd(struct if_sdio_card *card, - u8 *buffer, unsigned size) -{ - int ret; - unsigned long flags; - - lbs_deb_enter(LBS_DEB_SDIO); - - spin_lock_irqsave(&card->priv->adapter->driver_lock, flags); - - if (!card->priv->adapter->cur_cmd) { - lbs_deb_sdio("discarding spurious response\n"); - ret = 0; - goto out; - } - - if (size > MRVDRV_SIZE_OF_CMD_BUFFER) { - lbs_deb_sdio("response packet too large (%d bytes)\n", - (int)size); - ret = -E2BIG; - goto out; - } - - memcpy(card->priv->adapter->cur_cmd->bufvirtualaddr, buffer, size); - card->priv->upld_len = size; - - card->int_cause |= MRVDRV_CMD_UPLD_RDY; - - libertas_interrupt(card->priv->dev); - - ret = 0; - -out: - spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags); - - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_handle_data(struct if_sdio_card *card, - u8 *buffer, unsigned size) -{ - int ret; - struct sk_buff *skb; - char *data; - - lbs_deb_enter(LBS_DEB_SDIO); - - if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { - lbs_deb_sdio("response packet too large (%d bytes)\n", - (int)size); - ret = -E2BIG; - goto out; - } - - skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); - if (!skb) { - ret = -ENOMEM; - goto out; - } - - data = skb_put(skb, size); - - memcpy(data, buffer, size); - - libertas_process_rxed_packet(card->priv, skb); - - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_handle_event(struct if_sdio_card *card, - u8 *buffer, unsigned size) -{ - int ret; - unsigned long flags; - u32 event; - - lbs_deb_enter(LBS_DEB_SDIO); - - if (card->model == 0x04) { - event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); - if (ret) - goto out; - } else { - if (size < 4) { - lbs_deb_sdio("event packet too small (%d bytes)\n", - (int)size); - ret = -EINVAL; - goto out; - } - event = buffer[3] << 24; - event |= buffer[2] << 16; - event |= buffer[1] << 8; - event |= buffer[0] << 0; - event <<= SBI_EVENT_CAUSE_SHIFT; - } - - spin_lock_irqsave(&card->priv->adapter->driver_lock, flags); - - card->event = event; - card->int_cause |= MRVDRV_CARDEVENT; - - libertas_interrupt(card->priv->dev); - - spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags); - - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_card_to_host(struct if_sdio_card *card) -{ - int ret; - u8 status; - u16 size, type, chunk; - unsigned long timeout; - - lbs_deb_enter(LBS_DEB_SDIO); - - size = if_sdio_read_scratch(card, &ret); - if (ret) - goto out; - - if (size < 4) { - lbs_deb_sdio("invalid packet size (%d bytes) from firmware\n", - (int)size); - ret = -EINVAL; - goto out; - } - - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto out; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto out; - } - mdelay(1); - } - - /* - * The transfer must be in one transaction or the firmware - * goes suicidal. - */ - chunk = size; - if ((chunk > card->func->cur_blksize) || (chunk > 512)) { - chunk = (chunk + card->func->cur_blksize - 1) / - card->func->cur_blksize * card->func->cur_blksize; - } - - ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk); - if (ret) - goto out; - - chunk = card->buffer[0] | (card->buffer[1] << 8); - type = card->buffer[2] | (card->buffer[3] << 8); - - lbs_deb_sdio("packet of type %d and size %d bytes\n", - (int)type, (int)chunk); - - if (chunk > size) { - lbs_deb_sdio("packet fragment (%d > %d)\n", - (int)chunk, (int)size); - ret = -EINVAL; - goto out; - } - - if (chunk < size) { - lbs_deb_sdio("packet fragment (%d < %d)\n", - (int)chunk, (int)size); - } - - switch (type) { - case MVMS_CMD: - ret = if_sdio_handle_cmd(card, card->buffer + 4, chunk - 4); - if (ret) - goto out; - break; - case MVMS_DAT: - ret = if_sdio_handle_data(card, card->buffer + 4, chunk - 4); - if (ret) - goto out; - break; - case MVMS_EVENT: - ret = if_sdio_handle_event(card, card->buffer + 4, chunk - 4); - if (ret) - goto out; - break; - default: - lbs_deb_sdio("invalid type (%d) from firmware\n", - (int)type); - ret = -EINVAL; - goto out; - } - -out: - if (ret) - lbs_pr_err("problem fetching packet from firmware\n"); - - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static void if_sdio_host_to_card_worker(struct work_struct *work) -{ - struct if_sdio_card *card; - struct if_sdio_packet *packet; - unsigned long timeout; - u8 status; - int ret; - unsigned long flags; - - lbs_deb_enter(LBS_DEB_SDIO); - - card = container_of(work, struct if_sdio_card, packet_worker); - - while (1) { - spin_lock_irqsave(&card->lock, flags); - packet = card->packets; - if (packet) - card->packets = packet->next; - spin_unlock_irqrestore(&card->lock, flags); - - if (!packet) - break; - - sdio_claim_host(card->func); - - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if (status & IF_SDIO_IO_RDY) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } - - ret = sdio_writesb(card->func, card->ioport, - packet->buffer, packet->nb); - if (ret) - goto release; -release: - sdio_release_host(card->func); - - kfree(packet); - } - - lbs_deb_leave(LBS_DEB_SDIO); -} - -/********************************************************************/ -/* Firmware */ -/********************************************************************/ - -static int if_sdio_prog_helper(struct if_sdio_card *card) -{ - int ret; - u8 status; - const struct firmware *fw; - unsigned long timeout; - u8 *chunk_buffer; - u32 chunk_size; - u8 *firmware; - size_t size; - - lbs_deb_enter(LBS_DEB_SDIO); - - ret = request_firmware(&fw, card->helper, &card->func->dev); - if (ret) { - lbs_pr_err("can't load helper firmware\n"); - goto out; - } - - chunk_buffer = kzalloc(64, GFP_KERNEL); - if (!chunk_buffer) { - ret = -ENOMEM; - goto release_fw; - } - - sdio_claim_host(card->func); - - ret = sdio_set_block_size(card->func, 32); - if (ret) - goto release; - - firmware = fw->data; - size = fw->size; - - while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } - - chunk_size = min(size, (size_t)60); - - *((u32*)chunk_buffer) = cpu_to_le32(chunk_size); - memcpy(chunk_buffer + 4, firmware, chunk_size); -/* - lbs_deb_sdio("sending %d bytes chunk\n", chunk_size); -*/ - ret = sdio_writesb(card->func, card->ioport, - chunk_buffer, 64); - if (ret) - goto release; - - firmware += chunk_size; - size -= chunk_size; - } - - /* an empty block marks the end of the transfer */ - memset(chunk_buffer, 0, 4); - ret = sdio_writesb(card->func, card->ioport, chunk_buffer, 64); - if (ret) - goto release; - - lbs_deb_sdio("waiting for helper to boot...\n"); - - /* wait for the helper to boot by looking at the size register */ - timeout = jiffies + HZ; - while (1) { - u16 req_size; - - req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); - if (ret) - goto release; - - req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; - if (ret) - goto release; - - if (req_size != 0) - break; - - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - - msleep(10); - } - - ret = 0; - -release: - sdio_set_block_size(card->func, 0); - sdio_release_host(card->func); - kfree(chunk_buffer); -release_fw: - release_firmware(fw); - -out: - if (ret) - lbs_pr_err("failed to load helper firmware\n"); - - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_prog_real(struct if_sdio_card *card) -{ - int ret; - u8 status; - const struct firmware *fw; - unsigned long timeout; - u8 *chunk_buffer; - u32 chunk_size; - u8 *firmware; - size_t size, req_size; - - lbs_deb_enter(LBS_DEB_SDIO); - - ret = request_firmware(&fw, card->firmware, &card->func->dev); - if (ret) { - lbs_pr_err("can't load firmware\n"); - goto out; - } - - chunk_buffer = kzalloc(512, GFP_KERNEL); - if (!chunk_buffer) { - ret = -ENOMEM; - goto release_fw; - } - - sdio_claim_host(card->func); - - ret = sdio_set_block_size(card->func, 32); - if (ret) - goto release; - - firmware = fw->data; - size = fw->size; - - while (size) { - timeout = jiffies + HZ; - while (1) { - status = sdio_readb(card->func, IF_SDIO_STATUS, &ret); - if (ret) - goto release; - if ((status & IF_SDIO_IO_RDY) && - (status & IF_SDIO_DL_RDY)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } - - req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); - if (ret) - goto release; - - req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; - if (ret) - goto release; -/* - lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); -*/ - if (req_size == 0) { - lbs_deb_sdio("firmware helper gave up early\n"); - ret = -EIO; - goto release; - } - - if (req_size & 0x01) { - lbs_deb_sdio("firmware helper signalled error\n"); - ret = -EIO; - goto release; - } - - if (req_size > size) - req_size = size; - - while (req_size) { - chunk_size = min(req_size, (size_t)512); - - memcpy(chunk_buffer, firmware, chunk_size); -/* - lbs_deb_sdio("sending %d bytes (%d bytes) chunk\n", - chunk_size, (chunk_size + 31) / 32 * 32); -*/ - ret = sdio_writesb(card->func, card->ioport, - chunk_buffer, (chunk_size + 31) / 32 * 32); - if (ret) - goto release; - - firmware += chunk_size; - size -= chunk_size; - req_size -= chunk_size; - } - } - - ret = 0; - - lbs_deb_sdio("waiting for firmware to boot...\n"); - - /* wait for the firmware to boot */ - timeout = jiffies + HZ; - while (1) { - u16 scratch; - - scratch = if_sdio_read_scratch(card, &ret); - if (ret) - goto release; - - if (scratch == IF_SDIO_FIRMWARE_OK) - break; - - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - - msleep(10); - } - - ret = 0; - -release: - sdio_set_block_size(card->func, 0); - sdio_release_host(card->func); - kfree(chunk_buffer); -release_fw: - release_firmware(fw); - -out: - if (ret) - lbs_pr_err("failed to load firmware\n"); - - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_prog_firmware(struct if_sdio_card *card) -{ - int ret; - u16 scratch; - - lbs_deb_enter(LBS_DEB_SDIO); - - sdio_claim_host(card->func); - scratch = if_sdio_read_scratch(card, &ret); - sdio_release_host(card->func); - - if (ret) - goto out; - - if (scratch == IF_SDIO_FIRMWARE_OK) { - lbs_deb_sdio("firmware already loaded\n"); - goto success; - } - - ret = if_sdio_prog_helper(card); - if (ret) - goto out; - - ret = if_sdio_prog_real(card); - if (ret) - goto out; - -success: - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -/*******************************************************************/ -/* Libertas callbacks */ -/*******************************************************************/ - -static int if_sdio_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) -{ - int ret; - struct if_sdio_card *card; - struct if_sdio_packet *packet, *cur; - u16 size; - unsigned long flags; - - lbs_deb_enter_args(LBS_DEB_SDIO, "type %d, bytes %d", type, nb); - - card = priv->card; - - if (nb > (65536 - sizeof(struct if_sdio_packet) - 4)) { - ret = -EINVAL; - goto out; - } - - /* - * The transfer must be in one transaction or the firmware - * goes suicidal. - */ - size = nb + 4; - if ((size > card->func->cur_blksize) || (size > 512)) { - size = (size + card->func->cur_blksize - 1) / - card->func->cur_blksize * card->func->cur_blksize; - } - - packet = kzalloc(sizeof(struct if_sdio_packet) + size, - GFP_ATOMIC); - if (!packet) { - ret = -ENOMEM; - goto out; - } - - packet->next = NULL; - packet->nb = size; - - /* - * SDIO specific header. - */ - packet->buffer[0] = (nb + 4) & 0xff; - packet->buffer[1] = ((nb + 4) >> 8) & 0xff; - packet->buffer[2] = type; - packet->buffer[3] = 0; - - memcpy(packet->buffer + 4, buf, nb); - - spin_lock_irqsave(&card->lock, flags); - - if (!card->packets) - card->packets = packet; - else { - cur = card->packets; - while (cur->next) - cur = cur->next; - cur->next = packet; - } - - switch (type) { - case MVMS_CMD: - priv->dnld_sent = DNLD_CMD_SENT; - break; - case MVMS_DAT: - priv->dnld_sent = DNLD_DATA_SENT; - break; - default: - lbs_deb_sdio("unknown packet type %d\n", (int)type); - } - - spin_unlock_irqrestore(&card->lock, flags); - - schedule_work(&card->packet_worker); - - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg) -{ - struct if_sdio_card *card; - - lbs_deb_enter(LBS_DEB_SDIO); - - card = priv->card; - - *ireg = card->int_cause; - card->int_cause = 0; - - lbs_deb_leave(LBS_DEB_SDIO); - - return 0; -} - -static int if_sdio_read_event_cause(wlan_private *priv) -{ - struct if_sdio_card *card; - - lbs_deb_enter(LBS_DEB_SDIO); - - card = priv->card; - - priv->adapter->eventcause = card->event; - - lbs_deb_leave(LBS_DEB_SDIO); - - return 0; -} - -/*******************************************************************/ -/* SDIO callbacks */ -/*******************************************************************/ - -static void if_sdio_interrupt(struct sdio_func *func) -{ - int ret; - struct if_sdio_card *card; - u8 cause; - - lbs_deb_enter(LBS_DEB_SDIO); - - card = sdio_get_drvdata(func); - - cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret); - if (ret) - goto out; - - lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause); - - sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret); - if (ret) - goto out; - - /* - * Ignore the define name, this really means the card has - * successfully received the command. - */ - if (cause & IF_SDIO_H_INT_DNLD) { - if ((card->priv->dnld_sent == DNLD_DATA_SENT) && - (card->priv->adapter->connect_status == LIBERTAS_CONNECTED)) - netif_wake_queue(card->priv->dev); - card->priv->dnld_sent = DNLD_RES_RECEIVED; - } - - if (cause & IF_SDIO_H_INT_UPLD) { - ret = if_sdio_card_to_host(card); - if (ret) - goto out; - } - - ret = 0; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); -} - -static int if_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - struct if_sdio_card *card; - wlan_private *priv; - int ret, i; - unsigned int model; - struct if_sdio_packet *packet; - - lbs_deb_enter(LBS_DEB_SDIO); - - for (i = 0;i < func->card->num_info;i++) { - if (sscanf(func->card->info[i], - "802.11 SDIO ID: %x", &model) == 1) - break; - if (sscanf(func->card->info[i], - "ID: %x", &model) == 1) - break; - } - - if (i == func->card->num_info) { - lbs_pr_err("unable to identify card model\n"); - return -ENODEV; - } - - card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL); - if (!card) - return -ENOMEM; - - card->func = func; - card->model = model; - spin_lock_init(&card->lock); - INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); - - for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { - if (card->model == if_sdio_models[i].model) - break; - } - - if (i == ARRAY_SIZE(if_sdio_models)) { - lbs_pr_err("unkown card model 0x%x\n", card->model); - ret = -ENODEV; - goto free; - } - - card->helper = if_sdio_models[i].helper; - card->firmware = if_sdio_models[i].firmware; - - if (libertas_helper_name) { - lbs_deb_sdio("overriding helper firmware: %s\n", - libertas_helper_name); - card->helper = libertas_helper_name; - } - - if (libertas_fw_name) { - lbs_deb_sdio("overriding firmware: %s\n", libertas_fw_name); - card->firmware = libertas_fw_name; - } - - sdio_claim_host(func); - - ret = sdio_enable_func(func); - if (ret) - goto release; - - ret = sdio_claim_irq(func, if_sdio_interrupt); - if (ret) - goto disable; - - card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret); - if (ret) - goto release_int; - - card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8; - if (ret) - goto release_int; - - card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16; - if (ret) - goto release_int; - - sdio_release_host(func); - - sdio_set_drvdata(func, card); - - lbs_deb_sdio("class = 0x%X, vendor = 0x%X, " - "device = 0x%X, model = 0x%X, ioport = 0x%X\n", - func->class, func->vendor, func->device, - model, (unsigned)card->ioport); - - ret = if_sdio_prog_firmware(card); - if (ret) - goto reclaim; - - priv = libertas_add_card(card, &func->dev); - if (!priv) { - ret = -ENOMEM; - goto reclaim; - } - - card->priv = priv; - - priv->card = card; - priv->hw_host_to_card = if_sdio_host_to_card; - priv->hw_get_int_status = if_sdio_get_int_status; - priv->hw_read_event_cause = if_sdio_read_event_cause; - - priv->adapter->fw_ready = 1; - - /* - * Enable interrupts now that everything is set up - */ - sdio_claim_host(func); - sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); - sdio_release_host(func); - if (ret) - goto reclaim; - - ret = libertas_start_card(priv); - if (ret) - goto err_activate_card; - -out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; - -err_activate_card: - flush_scheduled_work(); - free_netdev(priv->dev); - kfree(priv->adapter); -reclaim: - sdio_claim_host(func); -release_int: - sdio_release_irq(func); -disable: - sdio_disable_func(func); -release: - sdio_release_host(func); -free: - while (card->packets) { - packet = card->packets; - card->packets = card->packets->next; - kfree(packet); - } - - kfree(card); - - goto out; -} - -static void if_sdio_remove(struct sdio_func *func) -{ - struct if_sdio_card *card; - struct if_sdio_packet *packet; - - lbs_deb_enter(LBS_DEB_SDIO); - - card = sdio_get_drvdata(func); - - card->priv->adapter->surpriseremoved = 1; - - lbs_deb_sdio("call remove card\n"); - libertas_stop_card(card->priv); - libertas_remove_card(card->priv); - - flush_scheduled_work(); - - sdio_claim_host(func); - sdio_release_irq(func); - sdio_disable_func(func); - sdio_release_host(func); - - while (card->packets) { - packet = card->packets; - card->packets = card->packets->next; - kfree(packet); - } - - kfree(card); - - lbs_deb_leave(LBS_DEB_SDIO); -} - -static struct sdio_driver if_sdio_driver = { - .name = "libertas_sdio", - .id_table = if_sdio_ids, - .probe = if_sdio_probe, - .remove = if_sdio_remove, -}; - -/*******************************************************************/ -/* Module functions */ -/*******************************************************************/ - -static int if_sdio_init_module(void) -{ - int ret = 0; - - lbs_deb_enter(LBS_DEB_SDIO); - - printk(KERN_INFO "libertas_sdio: Libertas SDIO driver\n"); - printk(KERN_INFO "libertas_sdio: Copyright Pierre Ossman\n"); - - ret = sdio_register_driver(&if_sdio_driver); - - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - - return ret; -} - -static void if_sdio_exit_module(void) -{ - lbs_deb_enter(LBS_DEB_SDIO); - - sdio_unregister_driver(&if_sdio_driver); - - lbs_deb_leave(LBS_DEB_SDIO); -} - -module_init(if_sdio_init_module); -module_exit(if_sdio_exit_module); - -MODULE_DESCRIPTION("Libertas SDIO WLAN Driver"); -MODULE_AUTHOR("Pierre Ossman"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.h b/trunk/drivers/net/wireless/libertas/if_sdio.h deleted file mode 100644 index dfcaea7b168f..000000000000 --- a/trunk/drivers/net/wireless/libertas/if_sdio.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/drivers/net/wireless/libertas/if_sdio.h - * - * Copyright 2007 Pierre Ossman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#ifndef LIBERTAS_IF_SDIO_H -#define LIBERTAS_IF_SDIO_H - -#define IF_SDIO_IOPORT 0x00 - -#define IF_SDIO_H_INT_MASK 0x04 -#define IF_SDIO_H_INT_OFLOW 0x08 -#define IF_SDIO_H_INT_UFLOW 0x04 -#define IF_SDIO_H_INT_DNLD 0x02 -#define IF_SDIO_H_INT_UPLD 0x01 - -#define IF_SDIO_H_INT_STATUS 0x05 -#define IF_SDIO_H_INT_RSR 0x06 -#define IF_SDIO_H_INT_STATUS2 0x07 - -#define IF_SDIO_RD_BASE 0x10 - -#define IF_SDIO_STATUS 0x20 -#define IF_SDIO_IO_RDY 0x08 -#define IF_SDIO_CIS_RDY 0x04 -#define IF_SDIO_UL_RDY 0x02 -#define IF_SDIO_DL_RDY 0x01 - -#define IF_SDIO_C_INT_MASK 0x24 -#define IF_SDIO_C_INT_STATUS 0x28 -#define IF_SDIO_C_INT_RSR 0x2C - -#define IF_SDIO_SCRATCH 0x34 -#define IF_SDIO_SCRATCH_OLD 0x80fe -#define IF_SDIO_FIRMWARE_OK 0xfedc - -#define IF_SDIO_EVENT 0x80fc - -#endif diff --git a/trunk/fs/9p/fid.c b/trunk/fs/9p/fid.c index b364da70ff28..15e05a15b575 100644 --- a/trunk/fs/9p/fid.c +++ b/trunk/fs/9p/fid.c @@ -1,7 +1,6 @@ /* * V9FS FID Management * - * Copyright (C) 2007 by Latchesar Ionkov * Copyright (C) 2005, 2006 by Eric Van Hensbergen * * This program is free software; you can redistribute it and/or modify @@ -35,9 +34,9 @@ #include "fid.h" /** - * v9fs_fid_add - add a fid to a dentry - * @dentry: dentry that the fid is being added to + * v9fs_fid_insert - add a fid to a dentry * @fid: fid to add + * @dentry: dentry that it is being added to * */ @@ -67,144 +66,52 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) } /** - * v9fs_fid_find - retrieve a fid that belongs to the specified uid + * v9fs_fid_lookup - return a locked fid from a dentry * @dentry: dentry to look for fid in - * @uid: return fid that belongs to the specified user - * @any: if non-zero, return any fid associated with the dentry + * + * find a fid in the dentry, obtain its semaphore and return a reference to it. + * code calling lookup is responsible for releasing lock + * + * TODO: only match fids that have the same uid as current user * */ -static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any) +struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) { struct v9fs_dentry *dent; - struct p9_fid *fid, *ret; - - P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", - dentry->d_iname, dentry, uid, any); - dent = (struct v9fs_dentry *) dentry->d_fsdata; - ret = NULL; - if (dent) { - spin_lock(&dent->lock); - list_for_each_entry(fid, &dent->fidlist, dlist) { - if (any || fid->uid == uid) { - ret = fid; - break; - } - } - spin_unlock(&dent->lock); - } + struct p9_fid *fid; - return ret; + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); + dent = dentry->d_fsdata; + if (dent) + fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); + else + fid = ERR_PTR(-EBADF); + + P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid); + return fid; } /** - * v9fs_fid_lookup - lookup for a fid, try to walk if not found + * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and + * release it * @dentry: dentry to look for fid in * - * Look for a fid in the specified dentry for the current user. - * If no fid is found, try to create one walking from a fid from the parent - * dentry (if it has one), or the root dentry. If the user haven't accessed - * the fs yet, attach now and walk from the root. + * find a fid in the dentry and then clone to a new private fid + * + * TODO: only match fids that have the same uid as current user + * */ -struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) -{ - int i, n, l, clone, any, access; - u32 uid; - struct p9_fid *fid; - struct dentry *d, *ds; - struct v9fs_session_info *v9ses; - char **wnames, *uname; - - v9ses = v9fs_inode2v9ses(dentry->d_inode); - access = v9ses->flags & V9FS_ACCESS_MASK; - switch (access) { - case V9FS_ACCESS_SINGLE: - case V9FS_ACCESS_USER: - uid = current->fsuid; - any = 0; - break; - - case V9FS_ACCESS_ANY: - uid = v9ses->uid; - any = 1; - break; - - default: - uid = ~0; - any = 0; - break; - } - - fid = v9fs_fid_find(dentry, uid, any); - if (fid) - return fid; - - ds = dentry->d_parent; - fid = v9fs_fid_find(ds, uid, any); - if (!fid) { /* walk from the root */ - n = 0; - for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent) - n++; - - fid = v9fs_fid_find(ds, uid, any); - if (!fid) { /* the user is not attached to the fs yet */ - if (access == V9FS_ACCESS_SINGLE) - return ERR_PTR(-EPERM); - - if (v9fs_extended(v9ses)) - uname = NULL; - else - uname = v9ses->uname; - - fid = p9_client_attach(v9ses->clnt, NULL, uname, uid, - v9ses->aname); - - if (IS_ERR(fid)) - return fid; - - v9fs_fid_add(ds, fid); - } - } else /* walk from the parent */ - n = 1; - - if (ds == dentry) - return fid; - - wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL); - if (!wnames) - return ERR_PTR(-ENOMEM); - - for (d = dentry, i = n; i >= 0; i--, d = d->d_parent) - wnames[i] = (char *) d->d_name.name; - - clone = 1; - i = 0; - while (i < n) { - l = min(n - i, P9_MAXWELEM); - fid = p9_client_walk(fid, l, &wnames[i], clone); - if (!fid) { - kfree(wnames); - return fid; - } - - i += l; - clone = 0; - } - - kfree(wnames); - v9fs_fid_add(dentry, fid); - return fid; -} - struct p9_fid *v9fs_fid_clone(struct dentry *dentry) { - struct p9_fid *fid, *ret; + struct p9_fid *ofid, *fid; - fid = v9fs_fid_lookup(dentry); - if (IS_ERR(fid)) - return fid; + P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); + ofid = v9fs_fid_lookup(dentry); + if (IS_ERR(ofid)) + return ofid; - ret = p9_client_walk(fid, 0, NULL, 1); - return ret; + fid = p9_client_walk(ofid, 0, NULL, 1); + return fid; } diff --git a/trunk/fs/9p/v9fs.c b/trunk/fs/9p/v9fs.c index 873802de21cd..0a7068e30ecb 100644 --- a/trunk/fs/9p/v9fs.c +++ b/trunk/fs/9p/v9fs.c @@ -38,41 +38,56 @@ /* * Option Parsing (code inspired by NFS code) - * NOTE: each transport will parse its own options + * */ enum { /* Options that take integer arguments */ - Opt_debug, Opt_msize, Opt_dfltuid, Opt_dfltgid, Opt_afid, + Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, + Opt_rfdno, Opt_wfdno, /* String options */ - Opt_uname, Opt_remotename, Opt_trans, + Opt_uname, Opt_remotename, /* Options that take no arguments */ - Opt_legacy, Opt_nodevmap, + Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, /* Cache options */ Opt_cache_loose, - /* Access options */ - Opt_access, /* Error token */ Opt_err }; static match_table_t tokens = { {Opt_debug, "debug=%x"}, + {Opt_port, "port=%u"}, {Opt_msize, "msize=%u"}, - {Opt_dfltuid, "dfltuid=%u"}, - {Opt_dfltgid, "dfltgid=%u"}, + {Opt_uid, "uid=%u"}, + {Opt_gid, "gid=%u"}, {Opt_afid, "afid=%u"}, + {Opt_rfdno, "rfdno=%u"}, + {Opt_wfdno, "wfdno=%u"}, {Opt_uname, "uname=%s"}, {Opt_remotename, "aname=%s"}, - {Opt_trans, "trans=%s"}, + {Opt_unix, "proto=unix"}, + {Opt_tcp, "proto=tcp"}, + {Opt_fd, "proto=fd"}, +#ifdef CONFIG_PCI_9P + {Opt_pci, "proto=pci"}, +#endif + {Opt_tcp, "tcp"}, + {Opt_unix, "unix"}, + {Opt_fd, "fd"}, {Opt_legacy, "noextend"}, {Opt_nodevmap, "nodevmap"}, {Opt_cache_loose, "cache=loose"}, {Opt_cache_loose, "loose"}, - {Opt_access, "access=%s"}, {Opt_err, NULL} }; +extern struct p9_transport *p9pci_trans_create(void); + +/* + * Parse option string. + */ + /** * v9fs_parse_options - parse mount options into session structure * @options: options string passed from mount @@ -80,21 +95,23 @@ static match_table_t tokens = { * */ -static void v9fs_parse_options(struct v9fs_session_info *v9ses) +static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) { - char *options = v9ses->options; - substring_t args[MAX_OPT_ARGS]; char *p; + substring_t args[MAX_OPT_ARGS]; int option; int ret; - char *s, *e; /* setup defaults */ - v9ses->maxdata = 8192; + v9ses->port = V9FS_PORT; + v9ses->maxdata = 9000; + v9ses->proto = PROTO_TCP; + v9ses->extended = 1; v9ses->afid = ~0; v9ses->debug = 0; + v9ses->rfdno = ~0; + v9ses->wfdno = ~0; v9ses->cache = 0; - v9ses->trans = v9fs_default_trans(); if (!options) return; @@ -118,29 +135,47 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) p9_debug_level = option; #endif break; + case Opt_port: + v9ses->port = option; + break; case Opt_msize: v9ses->maxdata = option; break; - case Opt_dfltuid: - v9ses->dfltuid = option; + case Opt_uid: + v9ses->uid = option; break; - case Opt_dfltgid: - v9ses->dfltgid = option; + case Opt_gid: + v9ses->gid = option; break; case Opt_afid: v9ses->afid = option; break; - case Opt_trans: - v9ses->trans = v9fs_match_trans(&args[0]); + case Opt_rfdno: + v9ses->rfdno = option; + break; + case Opt_wfdno: + v9ses->wfdno = option; + break; + case Opt_tcp: + v9ses->proto = PROTO_TCP; + break; + case Opt_unix: + v9ses->proto = PROTO_UNIX; + break; + case Opt_pci: + v9ses->proto = PROTO_PCI; + break; + case Opt_fd: + v9ses->proto = PROTO_FD; break; case Opt_uname: - match_strcpy(v9ses->uname, &args[0]); + match_strcpy(v9ses->name, &args[0]); break; case Opt_remotename: - match_strcpy(v9ses->aname, &args[0]); + match_strcpy(v9ses->remotename, &args[0]); break; case Opt_legacy: - v9ses->flags &= ~V9FS_EXTENDED; + v9ses->extended = 0; break; case Opt_nodevmap: v9ses->nodev = 1; @@ -148,22 +183,6 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses) case Opt_cache_loose: v9ses->cache = CACHE_LOOSE; break; - - case Opt_access: - s = match_strdup(&args[0]); - v9ses->flags &= ~V9FS_ACCESS_MASK; - if (strcmp(s, "user") == 0) - v9ses->flags |= V9FS_ACCESS_USER; - else if (strcmp(s, "any") == 0) - v9ses->flags |= V9FS_ACCESS_ANY; - else { - v9ses->flags |= V9FS_ACCESS_SINGLE; - v9ses->uid = simple_strtol(s, &e, 10); - if (*e != '\0') - v9ses->uid = ~0; - } - break; - default: continue; } @@ -182,46 +201,56 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, const char *dev_name, char *data) { int retval = -EINVAL; - struct p9_trans *trans = NULL; + struct p9_transport *trans; struct p9_fid *fid; - v9ses->uname = __getname(); - if (!v9ses->uname) + v9ses->name = __getname(); + if (!v9ses->name) return ERR_PTR(-ENOMEM); - v9ses->aname = __getname(); - if (!v9ses->aname) { - __putname(v9ses->uname); + v9ses->remotename = __getname(); + if (!v9ses->remotename) { + __putname(v9ses->name); return ERR_PTR(-ENOMEM); } - v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER; - strcpy(v9ses->uname, V9FS_DEFUSER); - strcpy(v9ses->aname, V9FS_DEFANAME); - v9ses->uid = ~0; - v9ses->dfltuid = V9FS_DEFUID; - v9ses->dfltgid = V9FS_DEFGID; - v9ses->options = kstrdup(data, GFP_KERNEL); - v9fs_parse_options(v9ses); - - if (v9ses->trans == NULL) { - retval = -EPROTONOSUPPORT; - P9_DPRINTK(P9_DEBUG_ERROR, - "No transport defined or default transport\n"); + strcpy(v9ses->name, V9FS_DEFUSER); + strcpy(v9ses->remotename, V9FS_DEFANAME); + + v9fs_parse_options(data, v9ses); + + switch (v9ses->proto) { + case PROTO_TCP: + trans = p9_trans_create_tcp(dev_name, v9ses->port); + break; + case PROTO_UNIX: + trans = p9_trans_create_unix(dev_name); + *v9ses->remotename = 0; + break; + case PROTO_FD: + trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); + *v9ses->remotename = 0; + break; +#ifdef CONFIG_PCI_9P + case PROTO_PCI: + trans = p9pci_trans_create(); + *v9ses->remotename = 0; + break; +#endif + default: + printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); + retval = -ENOPROTOOPT; goto error; - } + }; - trans = v9ses->trans->create(dev_name, v9ses->options); if (IS_ERR(trans)) { retval = PTR_ERR(trans); trans = NULL; goto error; } - if ((v9ses->maxdata+P9_IOHDRSZ) > v9ses->trans->maxsize) - v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ; - v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ, - v9fs_extended(v9ses)); + v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, + v9ses->extended); if (IS_ERR(v9ses->clnt)) { retval = PTR_ERR(v9ses->clnt); @@ -230,20 +259,8 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, goto error; } - if (!v9ses->clnt->dotu) - v9ses->flags &= ~V9FS_EXTENDED; - - /* for legacy mode, fall back to V9FS_ACCESS_ANY */ - if (!v9fs_extended(v9ses) && - ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { - - v9ses->flags &= ~V9FS_ACCESS_MASK; - v9ses->flags |= V9FS_ACCESS_ANY; - v9ses->uid = ~0; - } - - fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, - v9ses->aname); + fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, + v9ses->remotename); if (IS_ERR(fid)) { retval = PTR_ERR(fid); fid = NULL; @@ -251,11 +268,6 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, goto error; } - if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) - fid->uid = v9ses->uid; - else - fid->uid = ~0; - return fid; error: @@ -276,9 +288,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) v9ses->clnt = NULL; } - __putname(v9ses->uname); - __putname(v9ses->aname); - kfree(v9ses->options); + __putname(v9ses->name); + __putname(v9ses->remotename); } /** @@ -300,7 +311,7 @@ extern int v9fs_error_init(void); static int __init init_v9fs(void) { printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); - /* TODO: Setup list of registered trasnport modules */ + return register_filesystem(&v9fs_fs_type); } diff --git a/trunk/fs/9p/v9fs.h b/trunk/fs/9p/v9fs.h index db4b4193f2e2..abc4b1668ace 100644 --- a/trunk/fs/9p/v9fs.h +++ b/trunk/fs/9p/v9fs.h @@ -29,30 +29,31 @@ struct v9fs_session_info { /* options */ unsigned int maxdata; - unsigned char flags; /* session flags */ + unsigned char extended; /* set to 1 if we are using UNIX extensions */ unsigned char nodev; /* set to 1 if no disable device mapping */ + unsigned short port; /* port to connect to */ unsigned short debug; /* debug level */ + unsigned short proto; /* protocol to use */ unsigned int afid; /* authentication fid */ + unsigned int rfdno; /* read file descriptor number */ + unsigned int wfdno; /* write file descriptor number */ unsigned int cache; /* cache mode */ - char *options; /* copy of mount options */ - char *uname; /* user name to mount as */ - char *aname; /* name of remote hierarchy being mounted */ - unsigned int dfltuid; /* default uid/muid for legacy support */ - unsigned int dfltgid; /* default gid for legacy support */ - u32 uid; /* if ACCESS_SINGLE, the uid that has access */ - struct p9_trans_module *trans; /* 9p transport */ + char *name; /* user name to mount as */ + char *remotename; /* name of remote hierarchy being mounted */ + unsigned int uid; /* default uid/muid for legacy support */ + unsigned int gid; /* default gid for legacy support */ + struct p9_client *clnt; /* 9p client */ struct dentry *debugfs_dir; }; -/* session flags */ +/* possible values of ->proto */ enum { - V9FS_EXTENDED = 0x01, /* 9P2000.u */ - V9FS_ACCESS_MASK = 0x06, /* access mask */ - V9FS_ACCESS_SINGLE = 0x02, /* only one user can access the files */ - V9FS_ACCESS_USER = 0x04, /* attache per user */ - V9FS_ACCESS_ANY = 0x06, /* use the same attach for all users */ + PROTO_TCP, + PROTO_UNIX, + PROTO_FD, + PROTO_PCI, }; /* possible values of ->cache */ @@ -72,18 +73,11 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses); #define V9FS_MAGIC 0x01021997 /* other default globals */ -#define V9FS_PORT 564 +#define V9FS_PORT 564 #define V9FS_DEFUSER "nobody" #define V9FS_DEFANAME "" -#define V9FS_DEFUID (-2) -#define V9FS_DEFGID (-2) static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) { return (inode->i_sb->s_fs_info); } - -static inline int v9fs_extended(struct v9fs_session_info *v9ses) -{ - return v9ses->flags & V9FS_EXTENDED; -} diff --git a/trunk/fs/9p/vfs_file.c b/trunk/fs/9p/vfs_file.c index ba4b1caa9c43..716691689fd5 100644 --- a/trunk/fs/9p/vfs_file.c +++ b/trunk/fs/9p/vfs_file.c @@ -162,17 +162,15 @@ v9fs_file_write(struct file *filp, const char __user * data, fid = filp->private_data; ret = p9_client_uwrite(fid, data, *offset, count); - if (ret > 0) { - invalidate_inode_pages2_range(inode->i_mapping, *offset, - *offset+ret); + if (ret > 0) *offset += ret; - } if (*offset > inode->i_size) { inode->i_size = *offset; inode->i_blocks = (inode->i_size + 512 - 1) >> 9; } + invalidate_inode_pages2(inode->i_mapping); return ret; } diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index 175b4d9bf3f8..e5c45eed58a9 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -59,7 +59,7 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) res = mode & 0777; if (S_ISDIR(mode)) res |= P9_DMDIR; - if (v9fs_extended(v9ses)) { + if (v9ses->extended) { if (S_ISLNK(mode)) res |= P9_DMSYMLINK; if (v9ses->nodev == 0) { @@ -99,21 +99,21 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) if ((mode & P9_DMDIR) == P9_DMDIR) res |= S_IFDIR; - else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses))) + else if ((mode & P9_DMSYMLINK) && (v9ses->extended)) res |= S_IFLNK; - else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses)) + else if ((mode & P9_DMSOCKET) && (v9ses->extended) && (v9ses->nodev == 0)) res |= S_IFSOCK; - else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses)) + else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended) && (v9ses->nodev == 0)) res |= S_IFIFO; - else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses)) + else if ((mode & P9_DMDEVICE) && (v9ses->extended) && (v9ses->nodev == 0)) res |= S_IFBLK; else res |= S_IFREG; - if (v9fs_extended(v9ses)) { + if (v9ses->extended) { if ((mode & P9_DMSETUID) == P9_DMSETUID) res |= S_ISUID; @@ -214,7 +214,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) case S_IFBLK: case S_IFCHR: case S_IFSOCK: - if (!v9fs_extended(v9ses)) { + if(!v9ses->extended) { P9_DPRINTK(P9_DEBUG_ERROR, "special files without extended mode\n"); return ERR_PTR(-EINVAL); @@ -227,7 +227,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) inode->i_fop = &v9fs_file_operations; break; case S_IFLNK: - if (!v9fs_extended(v9ses)) { + if(!v9ses->extended) { P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); return ERR_PTR(-EINVAL); @@ -236,7 +236,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) break; case S_IFDIR: inc_nlink(inode); - if (v9fs_extended(v9ses)) + if(v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else inode->i_op = &v9fs_dir_inode_operations; @@ -364,7 +364,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) file_inode = file->d_inode; v9ses = v9fs_inode2v9ses(file_inode); v9fid = v9fs_fid_clone(file); - if (IS_ERR(v9fid)) + if(IS_ERR(v9fid)) return PTR_ERR(v9fid); return p9_client_remove(v9fid); @@ -398,7 +398,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, fid = NULL; name = (char *) dentry->d_name.name; dfid = v9fs_fid_clone(dentry->d_parent); - if (IS_ERR(dfid)) { + if(IS_ERR(dfid)) { err = PTR_ERR(dfid); dfid = NULL; goto error; @@ -432,7 +432,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, goto error; } - if (v9ses->cache) + if(v9ses->cache) dentry->d_op = &v9fs_cached_dentry_operations; else dentry->d_op = &v9fs_dentry_operations; @@ -593,7 +593,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, if (result < 0) goto error; - if ((fid->qid.version) && (v9ses->cache)) + if((fid->qid.version)&&(v9ses->cache)) dentry->d_op = &v9fs_cached_dentry_operations; else dentry->d_op = &v9fs_dentry_operations; @@ -658,17 +658,17 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_inode = old_dentry->d_inode; v9ses = v9fs_inode2v9ses(old_inode); oldfid = v9fs_fid_lookup(old_dentry); - if (IS_ERR(oldfid)) + if(IS_ERR(oldfid)) return PTR_ERR(oldfid); olddirfid = v9fs_fid_clone(old_dentry->d_parent); - if (IS_ERR(olddirfid)) { + if(IS_ERR(olddirfid)) { retval = PTR_ERR(olddirfid); goto done; } newdirfid = v9fs_fid_clone(new_dentry->d_parent); - if (IS_ERR(newdirfid)) { + if(IS_ERR(newdirfid)) { retval = PTR_ERR(newdirfid); goto clunk_olddir; } @@ -682,7 +682,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, } v9fs_blank_wstat(&wstat); - wstat.muid = v9ses->uname; + wstat.muid = v9ses->name; wstat.name = (char *) new_dentry->d_name.name; retval = p9_client_wstat(oldfid, &wstat); @@ -768,7 +768,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) if (iattr->ia_valid & ATTR_SIZE) wstat.length = iattr->ia_size; - if (v9fs_extended(v9ses)) { + if (v9ses->extended) { if (iattr->ia_valid & ATTR_UID) wstat.n_uid = iattr->ia_uid; @@ -805,10 +805,10 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, inode->i_mtime.tv_sec = stat->mtime; inode->i_ctime.tv_sec = stat->mtime; - inode->i_uid = v9ses->dfltuid; - inode->i_gid = v9ses->dfltgid; + inode->i_uid = v9ses->uid; + inode->i_gid = v9ses->gid; - if (v9fs_extended(v9ses)) { + if (v9ses->extended) { inode->i_uid = stat->n_uid; inode->i_gid = stat->n_gid; } @@ -887,10 +887,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) retval = -EPERM; v9ses = v9fs_inode2v9ses(dentry->d_inode); fid = v9fs_fid_lookup(dentry); - if (IS_ERR(fid)) + if(IS_ERR(fid)) return PTR_ERR(fid); - if (!v9fs_extended(v9ses)) + if (!v9ses->extended) return -EBADF; st = p9_client_stat(fid); @@ -1011,7 +1011,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, struct p9_fid *fid; v9ses = v9fs_inode2v9ses(dir); - if (!v9fs_extended(v9ses)) { + if (!v9ses->extended) { P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); return -EPERM; } @@ -1070,7 +1070,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, old_dentry->d_name.name); oldfid = v9fs_fid_clone(old_dentry); - if (IS_ERR(oldfid)) + if(IS_ERR(oldfid)) return PTR_ERR(oldfid); name = __getname(); diff --git a/trunk/fs/9p/vfs_super.c b/trunk/fs/9p/vfs_super.c index bb0cef9a6b8a..ba904371218b 100644 --- a/trunk/fs/9p/vfs_super.c +++ b/trunk/fs/9p/vfs_super.c @@ -216,7 +216,24 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt) { struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; - seq_printf(m, "%s", v9ses->options); + if (v9ses->debug != 0) + seq_printf(m, ",debug=%x", v9ses->debug); + if (v9ses->port != V9FS_PORT) + seq_printf(m, ",port=%u", v9ses->port); + if (v9ses->maxdata != 9000) + seq_printf(m, ",msize=%u", v9ses->maxdata); + if (v9ses->afid != ~0) + seq_printf(m, ",afid=%u", v9ses->afid); + if (v9ses->proto == PROTO_UNIX) + seq_puts(m, ",proto=unix"); + if (v9ses->extended == 0) + seq_puts(m, ",noextend"); + if (v9ses->nodev == 1) + seq_puts(m, ",nodevmap"); + seq_printf(m, ",name=%s", v9ses->name); + seq_printf(m, ",aname=%s", v9ses->remotename); + seq_printf(m, ",uid=%u", v9ses->uid); + seq_printf(m, ",gid=%u", v9ses->gid); return 0; } diff --git a/trunk/include/linux/mmc/sdio_ids.h b/trunk/include/linux/mmc/sdio_ids.h index ea1bf5ba092f..09306d47ff5e 100644 --- a/trunk/include/linux/mmc/sdio_ids.h +++ b/trunk/include/linux/mmc/sdio_ids.h @@ -19,11 +19,5 @@ #define SDIO_CLASS_WLAN 0x07 /* WLAN interface */ #define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */ -/* - * Vendors and devices. Sort key: vendor first, device next. - */ - -#define SDIO_VENDOR_ID_MARVELL 0x02df -#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 #endif diff --git a/trunk/include/net/9p/9p.h b/trunk/include/net/9p/9p.h index 686425a97b0f..7726ff41c3e6 100644 --- a/trunk/include/net/9p/9p.h +++ b/trunk/include/net/9p/9p.h @@ -216,7 +216,6 @@ struct p9_tauth { u32 afid; struct p9_str uname; struct p9_str aname; - u32 n_uname; /* 9P2000.u extensions */ }; struct p9_rauth { @@ -240,7 +239,6 @@ struct p9_tattach { u32 afid; struct p9_str uname; struct p9_str aname; - u32 n_uname; /* 9P2000.u extensions */ }; struct p9_rattach { @@ -384,9 +382,8 @@ int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); void p9_set_tag(struct p9_fcall *fc, u16 tag); struct p9_fcall *p9_create_tversion(u32 msize, char *version); struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, - char *aname, u32 n_uname, int dotu); -struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, - u32 n_uname, int dotu); + char *aname); +struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname); struct p9_fcall *p9_create_tflush(u16 oldtag); struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, char **wnames); @@ -415,4 +412,18 @@ int p9_idpool_check(int id, struct p9_idpool *p); int p9_error_init(void); int p9_errstr2errno(char *, int); + +#ifdef CONFIG_SYSCTL +int __init p9_sysctl_register(void); +void __exit p9_sysctl_unregister(void); +#else +static inline int p9_sysctl_register(void) +{ + return 0; +} +static inline void p9_sysctl_unregister(void) +{ +} +#endif + #endif /* NET_9P_H */ diff --git a/trunk/include/net/9p/client.h b/trunk/include/net/9p/client.h index 9b9221a21392..d65ed7c69063 100644 --- a/trunk/include/net/9p/client.h +++ b/trunk/include/net/9p/client.h @@ -29,7 +29,7 @@ struct p9_client { spinlock_t lock; /* protect client structure */ int msize; unsigned char dotu; - struct p9_trans *trans; + struct p9_transport *trans; struct p9_conn *conn; struct p9_idpool *fidpool; @@ -52,14 +52,13 @@ struct p9_fid { struct list_head dlist; /* list of all fids attached to a dentry */ }; -struct p9_client *p9_client_create(struct p9_trans *trans, int msize, +struct p9_client *p9_client_create(struct p9_transport *trans, int msize, int dotu); void p9_client_destroy(struct p9_client *clnt); void p9_client_disconnect(struct p9_client *clnt); struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, - char *uname, u32 n_uname, char *aname); -struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, - u32 n_uname, char *aname); + char *uname, char *aname); +struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname); struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone); int p9_client_open(struct p9_fid *fid, int mode); diff --git a/trunk/include/net/9p/conn.h b/trunk/include/net/9p/conn.h index 756d8784f953..583b6a2cb3df 100644 --- a/trunk/include/net/9p/conn.h +++ b/trunk/include/net/9p/conn.h @@ -42,8 +42,8 @@ struct p9_req; */ typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); -struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize, - unsigned char *dotu); +struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, + unsigned char *dotu); void p9_conn_destroy(struct p9_conn *); int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc); diff --git a/trunk/include/net/9p/transport.h b/trunk/include/net/9p/transport.h index 9dd4a05619a8..462d42279fb0 100644 --- a/trunk/include/net/9p/transport.h +++ b/trunk/include/net/9p/transport.h @@ -26,31 +26,24 @@ #ifndef NET_9P_TRANSPORT_H #define NET_9P_TRANSPORT_H -enum p9_trans_status { +enum p9_transport_status { Connected, Disconnected, Hung, }; -struct p9_trans { - enum p9_trans_status status; +struct p9_transport { + enum p9_transport_status status; void *priv; - int (*write) (struct p9_trans *, void *, int); - int (*read) (struct p9_trans *, void *, int); - void (*close) (struct p9_trans *); - unsigned int (*poll)(struct p9_trans *, struct poll_table_struct *); -}; -struct p9_trans_module { - struct list_head list; - char *name; /* name of transport */ - int maxsize; /* max message size of transport */ - int def; /* this transport should be default */ - struct p9_trans * (*create)(const char *devname, char *options); + int (*write) (struct p9_transport *, void *, int); + int (*read) (struct p9_transport *, void *, int); + void (*close) (struct p9_transport *); + unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *); }; -void v9fs_register_trans(struct p9_trans_module *m); -struct p9_trans_module *v9fs_match_trans(const substring_t *name); -struct p9_trans_module *v9fs_default_trans(void); +struct p9_transport *p9_trans_create_tcp(const char *addr, int port); +struct p9_transport *p9_trans_create_unix(const char *addr); +struct p9_transport *p9_trans_create_fd(int rfd, int wfd); #endif /* NET_9P_TRANSPORT_H */ diff --git a/trunk/net/9p/Kconfig b/trunk/net/9p/Kconfig index eecbf12f6393..66821cd64a76 100644 --- a/trunk/net/9p/Kconfig +++ b/trunk/net/9p/Kconfig @@ -13,16 +13,6 @@ menuconfig NET_9P If unsure, say N. -config NET_9P_FD - depends on NET_9P - default y if NET_9P - tristate "9P File Descriptor Transports (Experimental)" - help - This builds support for file descriptor transports for 9p - which includes support for TCP/IP, named pipes, or passed - file descriptors. TCP/IP is the default transport for 9p, - so if you are going to use 9p, you'll likely want this. - config NET_9P_DEBUG bool "Debug information" depends on NET_9P diff --git a/trunk/net/9p/Makefile b/trunk/net/9p/Makefile index 5059bc06f8f3..85b3a7838acf 100644 --- a/trunk/net/9p/Makefile +++ b/trunk/net/9p/Makefile @@ -1,8 +1,8 @@ obj-$(CONFIG_NET_9P) := 9pnet.o -obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o 9pnet-objs := \ mod.o \ + trans_fd.o \ mux.o \ client.o \ conv.o \ @@ -10,5 +10,4 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o fcprint.o \ util.o \ -9pnet_fd-objs := \ - trans_fd.o \ +9pnet-$(CONFIG_SYSCTL) += sysctl.o diff --git a/trunk/net/9p/client.c b/trunk/net/9p/client.c index af9199364049..cb170750337c 100644 --- a/trunk/net/9p/client.c +++ b/trunk/net/9p/client.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt); static void p9_fid_destroy(struct p9_fid *fid); static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu); -struct p9_client *p9_client_create(struct p9_trans *trans, int msize, +struct p9_client *p9_client_create(struct p9_transport *trans, int msize, int dotu) { int err, n; @@ -147,7 +146,7 @@ void p9_client_disconnect(struct p9_client *clnt) EXPORT_SYMBOL(p9_client_disconnect); struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, - char *uname, u32 n_uname, char *aname) + char *uname, char *aname) { int err; struct p9_fcall *tc, *rc; @@ -166,8 +165,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, goto error; } - tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname, - n_uname, clnt->dotu); + tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; @@ -192,8 +190,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, } EXPORT_SYMBOL(p9_client_attach); -struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, - u32 n_uname, char *aname) +struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname) { int err; struct p9_fcall *tc, *rc; @@ -212,7 +209,7 @@ struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, goto error; } - tc = p9_create_tauth(fid->fid, uname, aname, n_uname, clnt->dotu); + tc = p9_create_tauth(fid->fid, uname, aname); if (IS_ERR(tc)) { err = PTR_ERR(tc); tc = NULL; diff --git a/trunk/net/9p/conv.c b/trunk/net/9p/conv.c index aa2aa9884f95..d979d958ea19 100644 --- a/trunk/net/9p/conv.c +++ b/trunk/net/9p/conv.c @@ -547,8 +547,7 @@ struct p9_fcall *p9_create_tversion(u32 msize, char *version) } EXPORT_SYMBOL(p9_create_tversion); -struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, - u32 n_uname, int dotu) +struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname) { int size; struct p9_fcall *fc; @@ -556,16 +555,7 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, struct cbuf *bufp = &buffer; /* afid[4] uname[s] aname[s] */ - size = 4 + 2 + 2; - if (uname) - size += strlen(uname); - - if (aname) - size += strlen(aname); - - if (dotu) - size += 4; /* n_uname */ - + size = 4 + 2 + strlen(uname) + 2 + strlen(aname); fc = p9_create_common(bufp, size, P9_TAUTH); if (IS_ERR(fc)) goto error; @@ -573,8 +563,6 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, p9_put_int32(bufp, afid, &fc->params.tauth.afid); p9_put_str(bufp, uname, &fc->params.tauth.uname); p9_put_str(bufp, aname, &fc->params.tauth.aname); - if (dotu) - p9_put_int32(bufp, n_uname, &fc->params.tauth.n_uname); if (buf_check_overflow(bufp)) { kfree(fc); @@ -586,8 +574,7 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname, EXPORT_SYMBOL(p9_create_tauth); struct p9_fcall * -p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, - u32 n_uname, int dotu) +p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname) { int size; struct p9_fcall *fc; @@ -595,16 +582,7 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, struct cbuf *bufp = &buffer; /* fid[4] afid[4] uname[s] aname[s] */ - size = 4 + 4 + 2 + 2; - if (uname) - size += strlen(uname); - - if (aname) - size += strlen(aname); - - if (dotu) - size += 4; /* n_uname */ - + size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); fc = p9_create_common(bufp, size, P9_TATTACH); if (IS_ERR(fc)) goto error; @@ -613,8 +591,6 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname, p9_put_int32(bufp, afid, &fc->params.tattach.afid); p9_put_str(bufp, uname, &fc->params.tattach.uname); p9_put_str(bufp, aname, &fc->params.tattach.aname); - if (dotu) - p9_put_int32(bufp, n_uname, &fc->params.tattach.n_uname); error: return fc; diff --git a/trunk/net/9p/mod.c b/trunk/net/9p/mod.c index 41d70f47375d..4f9e1d2ac257 100644 --- a/trunk/net/9p/mod.c +++ b/trunk/net/9p/mod.c @@ -27,10 +27,6 @@ #include #include #include -#include -#include -#include -#include #ifdef CONFIG_NET_9P_DEBUG unsigned int p9_debug_level = 0; /* feature-rific global debug level */ @@ -41,64 +37,8 @@ MODULE_PARM_DESC(debug, "9P debugging level"); extern int p9_mux_global_init(void); extern void p9_mux_global_exit(void); - -/* - * Dynamic Transport Registration Routines - * - */ - -static LIST_HEAD(v9fs_trans_list); -static struct p9_trans_module *v9fs_default_transport; - -/** - * v9fs_register_trans - register a new transport with 9p - * @m - structure describing the transport module and entry points - * - */ -void v9fs_register_trans(struct p9_trans_module *m) -{ - list_add_tail(&m->list, &v9fs_trans_list); - if (m->def) - v9fs_default_transport = m; -} -EXPORT_SYMBOL(v9fs_register_trans); - -/** - * v9fs_match_trans - match transport versus registered transports - * @arg: string identifying transport - * - */ -struct p9_trans_module *v9fs_match_trans(const substring_t *name) -{ - struct list_head *p; - struct p9_trans_module *t = NULL; - - list_for_each(p, &v9fs_trans_list) { - t = list_entry(p, struct p9_trans_module, list); - if (strncmp(t->name, name->from, name->to-name->from) == 0) - break; - } - return t; -} -EXPORT_SYMBOL(v9fs_match_trans); - -/** - * v9fs_default_trans - returns pointer to default transport - * - */ - -struct p9_trans_module *v9fs_default_trans(void) -{ - if (v9fs_default_transport) - return v9fs_default_transport; - else if (!list_empty(&v9fs_trans_list)) - return list_first_entry(&v9fs_trans_list, - struct p9_trans_module, list); - else - return NULL; -} -EXPORT_SYMBOL(v9fs_default_trans); - +extern int p9_sysctl_register(void); +extern void p9_sysctl_unregister(void); /** * v9fs_init - Initialize module @@ -116,6 +56,12 @@ static int __init init_p9(void) return ret; } + ret = p9_sysctl_register(); + if (ret) { + printk(KERN_WARNING "9p: registering sysctl failed\n"); + return ret; + } + return ret; } @@ -126,6 +72,7 @@ static int __init init_p9(void) static void __exit exit_p9(void) { + p9_sysctl_unregister(); p9_mux_global_exit(); } diff --git a/trunk/net/9p/mux.c b/trunk/net/9p/mux.c index f14014793bed..5d70558c4c61 100644 --- a/trunk/net/9p/mux.c +++ b/trunk/net/9p/mux.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -72,7 +71,7 @@ struct p9_conn { struct p9_mux_poll_task *poll_task; int msize; unsigned char *extended; - struct p9_trans *trans; + struct p9_transport *trans; struct p9_idpool *tagpool; int err; wait_queue_head_t equeue; @@ -272,7 +271,7 @@ static void p9_mux_poll_stop(struct p9_conn *m) * @msize - maximum message size * @extended - pointer to the extended flag */ -struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize, +struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, unsigned char *extended) { int i, n; diff --git a/trunk/net/9p/sysctl.c b/trunk/net/9p/sysctl.c new file mode 100644 index 000000000000..8b61027a24ea --- /dev/null +++ b/trunk/net/9p/sysctl.c @@ -0,0 +1,81 @@ +/* + * net/9p/sysctl.c + * + * 9P sysctl interface + * + * Copyright (C) 2007 by Latchesar Ionkov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to: + * Free Software Foundation + * 51 Franklin Street, Fifth Floor + * Boston, MA 02111-1301 USA + * + */ + +#include +#include +#include +#include +#include + +static struct ctl_table p9_table[] = { +#ifdef CONFIG_NET_9P_DEBUG + { + .ctl_name = CTL_UNNUMBERED, + .procname = "debug", + .data = &p9_debug_level, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, +#endif + {}, +}; + +static struct ctl_table p9_net_table[] = { + { + .ctl_name = CTL_UNNUMBERED, + .procname = "9p", + .maxlen = 0, + .mode = 0555, + .child = p9_table, + }, + {}, +}; + +static struct ctl_table p9_ctl_table[] = { + { + .ctl_name = CTL_NET, + .procname = "net", + .maxlen = 0, + .mode = 0555, + .child = p9_net_table, + }, + {}, +}; + +static struct ctl_table_header *p9_table_header; + +int __init p9_sysctl_register(void) +{ + p9_table_header = register_sysctl_table(p9_ctl_table); + if (!p9_table_header) + return -ENOMEM; + + return 0; +} + +void __exit p9_sysctl_unregister(void) +{ + unregister_sysctl_table(p9_table_header); +} diff --git a/trunk/net/9p/trans_fd.c b/trunk/net/9p/trans_fd.c index 30269a4ff22a..fd636e94358f 100644 --- a/trunk/net/9p/trans_fd.c +++ b/trunk/net/9p/trans_fd.c @@ -5,7 +5,7 @@ * * Copyright (C) 2006 by Russ Cox * Copyright (C) 2004-2005 by Latchesar Ionkov - * Copyright (C) 2004-2007 by Eric Van Hensbergen + * Copyright (C) 2004-2005 by Eric Van Hensbergen * Copyright (C) 1997-2002 by Ron Minnich * * This program is free software; you can redistribute it and/or modify @@ -36,114 +36,160 @@ #include #include #include -#include #include #include #define P9_PORT 564 -#define MAX_SOCK_BUF (64*1024) - - -struct p9_fd_opts { - int rfd; - int wfd; - u16 port; -}; struct p9_trans_fd { struct file *rd; struct file *wr; }; -/* - * Option Parsing (code inspired by NFS code) - * - a little lazy - parse all fd-transport options - */ +static int p9_socket_open(struct p9_transport *trans, struct socket *csocket); +static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd); +static int p9_fd_read(struct p9_transport *trans, void *v, int len); +static int p9_fd_write(struct p9_transport *trans, void *v, int len); +static unsigned int p9_fd_poll(struct p9_transport *trans, + struct poll_table_struct *pt); +static void p9_fd_close(struct p9_transport *trans); -enum { - /* Options that take integer arguments */ - Opt_port, Opt_rfdno, Opt_wfdno, -}; +struct p9_transport *p9_trans_create_tcp(const char *addr, int port) +{ + int err; + struct p9_transport *trans; + struct socket *csocket; + struct sockaddr_in sin_server; -static match_table_t tokens = { - {Opt_port, "port=%u"}, - {Opt_rfdno, "rfdno=%u"}, - {Opt_wfdno, "wfdno=%u"}, -}; + csocket = NULL; + trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); + if (!trans) + return ERR_PTR(-ENOMEM); -/** - * v9fs_parse_options - parse mount options into session structure - * @options: options string passed from mount - * @v9ses: existing v9fs session information - * - */ + trans->write = p9_fd_write; + trans->read = p9_fd_read; + trans->close = p9_fd_close; + trans->poll = p9_fd_poll; + + sin_server.sin_family = AF_INET; + sin_server.sin_addr.s_addr = in_aton(addr); + sin_server.sin_port = htons(port); + sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); + + if (!csocket) { + P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); + err = -EIO; + goto error; + } -static void parse_opts(char *options, struct p9_fd_opts *opts) + err = csocket->ops->connect(csocket, + (struct sockaddr *)&sin_server, + sizeof(struct sockaddr_in), 0); + if (err < 0) { + P9_EPRINTK(KERN_ERR, + "p9_trans_tcp: problem connecting socket to %s\n", + addr); + goto error; + } + + err = p9_socket_open(trans, csocket); + if (err < 0) + goto error; + + return trans; + +error: + if (csocket) + sock_release(csocket); + + kfree(trans); + return ERR_PTR(err); +} +EXPORT_SYMBOL(p9_trans_create_tcp); + +struct p9_transport *p9_trans_create_unix(const char *addr) { - char *p; - substring_t args[MAX_OPT_ARGS]; - int option; - int ret; + int err; + struct socket *csocket; + struct sockaddr_un sun_server; + struct p9_transport *trans; - opts->port = P9_PORT; - opts->rfd = ~0; - opts->wfd = ~0; + csocket = NULL; + trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); + if (!trans) + return ERR_PTR(-ENOMEM); - if (!options) - return; + trans->write = p9_fd_write; + trans->read = p9_fd_read; + trans->close = p9_fd_close; + trans->poll = p9_fd_poll; - while ((p = strsep(&options, ",")) != NULL) { - int token; - if (!*p) - continue; - token = match_token(p, tokens, args); - ret = match_int(&args[0], &option); - if (ret < 0) { - P9_DPRINTK(P9_DEBUG_ERROR, - "integer field, but no integer?\n"); - continue; - } - switch (token) { - case Opt_port: - opts->port = option; - break; - case Opt_rfdno: - opts->rfd = option; - break; - case Opt_wfdno: - opts->wfd = option; - break; - default: - continue; - } + if (strlen(addr) > UNIX_PATH_MAX) { + P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", + addr); + err = -ENAMETOOLONG; + goto error; } + + sun_server.sun_family = PF_UNIX; + strcpy(sun_server.sun_path, addr); + sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); + err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, + sizeof(struct sockaddr_un) - 1, 0); + if (err < 0) { + P9_EPRINTK(KERN_ERR, + "p9_trans_unix: problem connecting socket: %s: %d\n", + addr, err); + goto error; + } + + err = p9_socket_open(trans, csocket); + if (err < 0) + goto error; + + return trans; + +error: + if (csocket) + sock_release(csocket); + + kfree(trans); + return ERR_PTR(err); } +EXPORT_SYMBOL(p9_trans_create_unix); -static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd) +struct p9_transport *p9_trans_create_fd(int rfd, int wfd) { - struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), - GFP_KERNEL); - if (!ts) - return -ENOMEM; + int err; + struct p9_transport *trans; - ts->rd = fget(rfd); - ts->wr = fget(wfd); - if (!ts->rd || !ts->wr) { - if (ts->rd) - fput(ts->rd); - if (ts->wr) - fput(ts->wr); - kfree(ts); - return -EIO; + if (rfd == ~0 || wfd == ~0) { + printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); + return ERR_PTR(-ENOPROTOOPT); } - trans->priv = ts; - trans->status = Connected; + trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); + if (!trans) + return ERR_PTR(-ENOMEM); - return 0; + trans->write = p9_fd_write; + trans->read = p9_fd_read; + trans->close = p9_fd_close; + trans->poll = p9_fd_poll; + + err = p9_fd_open(trans, rfd, wfd); + if (err < 0) + goto error; + + return trans; + +error: + kfree(trans); + return ERR_PTR(err); } +EXPORT_SYMBOL(p9_trans_create_fd); -static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) +static int p9_socket_open(struct p9_transport *trans, struct socket *csocket) { int fd, ret; @@ -166,6 +212,30 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) return 0; } +static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd) +{ + struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), + GFP_KERNEL); + if (!ts) + return -ENOMEM; + + ts->rd = fget(rfd); + ts->wr = fget(wfd); + if (!ts->rd || !ts->wr) { + if (ts->rd) + fput(ts->rd); + if (ts->wr) + fput(ts->wr); + kfree(ts); + return -EIO; + } + + trans->priv = ts; + trans->status = Connected; + + return 0; +} + /** * p9_fd_read- read from a fd * @v9ses: session information @@ -173,7 +243,7 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) * @len: size of receive buffer * */ -static int p9_fd_read(struct p9_trans *trans, void *v, int len) +static int p9_fd_read(struct p9_transport *trans, void *v, int len) { int ret; struct p9_trans_fd *ts = NULL; @@ -200,7 +270,7 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len) * @len: size of send buffer * */ -static int p9_fd_write(struct p9_trans *trans, void *v, int len) +static int p9_fd_write(struct p9_transport *trans, void *v, int len) { int ret; mm_segment_t oldfs; @@ -227,7 +297,7 @@ static int p9_fd_write(struct p9_trans *trans, void *v, int len) } static unsigned int -p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) +p9_fd_poll(struct p9_transport *trans, struct poll_table_struct *pt) { int ret, n; struct p9_trans_fd *ts = NULL; @@ -271,7 +341,7 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) * @trans: private socket structure * */ -static void p9_fd_close(struct p9_trans *trans) +static void p9_fd_close(struct p9_transport *trans) { struct p9_trans_fd *ts; @@ -291,182 +361,3 @@ static void p9_fd_close(struct p9_trans *trans) kfree(ts); } -static struct p9_trans *p9_trans_create_tcp(const char *addr, char *args) -{ - int err; - struct p9_trans *trans; - struct socket *csocket; - struct sockaddr_in sin_server; - struct p9_fd_opts opts; - - parse_opts(args, &opts); - - csocket = NULL; - trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); - if (!trans) - return ERR_PTR(-ENOMEM); - - trans->write = p9_fd_write; - trans->read = p9_fd_read; - trans->close = p9_fd_close; - trans->poll = p9_fd_poll; - - sin_server.sin_family = AF_INET; - sin_server.sin_addr.s_addr = in_aton(addr); - sin_server.sin_port = htons(opts.port); - sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); - - if (!csocket) { - P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); - err = -EIO; - goto error; - } - - err = csocket->ops->connect(csocket, - (struct sockaddr *)&sin_server, - sizeof(struct sockaddr_in), 0); - if (err < 0) { - P9_EPRINTK(KERN_ERR, - "p9_trans_tcp: problem connecting socket to %s\n", - addr); - goto error; - } - - err = p9_socket_open(trans, csocket); - if (err < 0) - goto error; - - return trans; - -error: - if (csocket) - sock_release(csocket); - - kfree(trans); - return ERR_PTR(err); -} - -static struct p9_trans *p9_trans_create_unix(const char *addr, char *args) -{ - int err; - struct socket *csocket; - struct sockaddr_un sun_server; - struct p9_trans *trans; - - csocket = NULL; - trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); - if (!trans) - return ERR_PTR(-ENOMEM); - - trans->write = p9_fd_write; - trans->read = p9_fd_read; - trans->close = p9_fd_close; - trans->poll = p9_fd_poll; - - if (strlen(addr) > UNIX_PATH_MAX) { - P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", - addr); - err = -ENAMETOOLONG; - goto error; - } - - sun_server.sun_family = PF_UNIX; - strcpy(sun_server.sun_path, addr); - sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); - err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, - sizeof(struct sockaddr_un) - 1, 0); - if (err < 0) { - P9_EPRINTK(KERN_ERR, - "p9_trans_unix: problem connecting socket: %s: %d\n", - addr, err); - goto error; - } - - err = p9_socket_open(trans, csocket); - if (err < 0) - goto error; - - return trans; - -error: - if (csocket) - sock_release(csocket); - - kfree(trans); - return ERR_PTR(err); -} - -static struct p9_trans *p9_trans_create_fd(const char *name, char *args) -{ - int err; - struct p9_trans *trans; - struct p9_fd_opts opts; - - parse_opts(args, &opts); - - if (opts.rfd == ~0 || opts.wfd == ~0) { - printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); - return ERR_PTR(-ENOPROTOOPT); - } - - trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); - if (!trans) - return ERR_PTR(-ENOMEM); - - trans->write = p9_fd_write; - trans->read = p9_fd_read; - trans->close = p9_fd_close; - trans->poll = p9_fd_poll; - - err = p9_fd_open(trans, opts.rfd, opts.wfd); - if (err < 0) - goto error; - - return trans; - -error: - kfree(trans); - return ERR_PTR(err); -} - -static struct p9_trans_module p9_tcp_trans = { - .name = "tcp", - .maxsize = MAX_SOCK_BUF, - .def = 1, - .create = p9_trans_create_tcp, -}; - -static struct p9_trans_module p9_unix_trans = { - .name = "unix", - .maxsize = MAX_SOCK_BUF, - .def = 0, - .create = p9_trans_create_unix, -}; - -static struct p9_trans_module p9_fd_trans = { - .name = "fd", - .maxsize = MAX_SOCK_BUF, - .def = 0, - .create = p9_trans_create_fd, -}; - -static int __init p9_trans_fd_init(void) -{ - v9fs_register_trans(&p9_tcp_trans); - v9fs_register_trans(&p9_unix_trans); - v9fs_register_trans(&p9_fd_trans); - - return 1; -} - -static void __exit p9_trans_fd_exit(void) { - printk(KERN_ERR "Removal of 9p transports not implemented\n"); - BUG(); -} - -module_init(p9_trans_fd_init); -module_exit(p9_trans_fd_exit); - -MODULE_AUTHOR("Latchesar Ionkov "); -MODULE_AUTHOR("Eric Van Hensbergen "); -MODULE_LICENSE("GPL");