diff options
Diffstat (limited to 'drivers/ieee1394/cmp.c')
-rw-r--r-- | drivers/ieee1394/cmp.c | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/drivers/ieee1394/cmp.c b/drivers/ieee1394/cmp.c deleted file mode 100644 index 69aed26e83a1..000000000000 --- a/drivers/ieee1394/cmp.c +++ /dev/null @@ -1,311 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - * - * cmp.c - Connection Management Procedures - * Copyright (C) 2001 Kristian Høgsberg - * - * 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 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 the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* TODO - * ---- - * - * - Implement IEC61883-1 output plugs and connection management. - * This should probably be part of the general subsystem, as it could - * be shared with dv1394. - * - * - Add IEC61883 unit directory when loading this module. This - * requires a run-time changeable config rom. - */ - -#include <linux/module.h> -#include <linux/list.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/wait.h> -#include <linux/interrupt.h> - -#include "hosts.h" -#include "highlevel.h" -#include "ieee1394.h" -#include "ieee1394_core.h" -#include "cmp.h" - -struct plug { - union { - struct cmp_pcr pcr; - quadlet_t quadlet; - } u; - void (*update)(struct cmp_pcr *plug, void *data); - void *data; -}; - -struct cmp_host { - struct hpsb_host *host; - - union { - struct cmp_mpr ompr; - quadlet_t ompr_quadlet; - } u; - struct plug opcr[2]; - - union { - struct cmp_mpr impr; - quadlet_t impr_quadlet; - } v; - struct plug ipcr[2]; -}; - -enum { - CMP_P2P_CONNECTION, - CMP_BC_CONNECTION -}; - -#define CSR_PCR_MAP 0x900 -#define CSR_PCR_MAP_END 0x9fc - -static struct hpsb_highlevel cmp_highlevel; - -static void cmp_add_host(struct hpsb_host *host); -static void cmp_host_reset(struct hpsb_host *host); -static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf, - u64 addr, size_t length, u16 flags); -static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, - u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 flags); - -static struct hpsb_highlevel cmp_highlevel = { - .name = "cmp", - .add_host = cmp_add_host, - .host_reset = cmp_host_reset, -}; - -static struct hpsb_address_ops pcr_ops = { - .read = pcr_read, - .lock = pcr_lock, -}; - - -struct cmp_pcr * -cmp_register_opcr(struct hpsb_host *host, int opcr_number, int payload, - void (*update)(struct cmp_pcr *pcr, void *data), - void *data) -{ - struct cmp_host *ch; - struct plug *plug; - - ch = hpsb_get_hostinfo(&cmp_highlevel, host); - - if (opcr_number >= ch->u.ompr.nplugs || - ch->opcr[opcr_number].update != NULL) - return NULL; - - plug = &ch->opcr[opcr_number]; - plug->u.pcr.online = 1; - plug->u.pcr.bcast_count = 0; - plug->u.pcr.p2p_count = 0; - plug->u.pcr.overhead = 0; - plug->u.pcr.payload = payload; - plug->update = update; - plug->data = data; - - return &plug->u.pcr; -} - -void cmp_unregister_opcr(struct hpsb_host *host, struct cmp_pcr *opcr) -{ - struct cmp_host *ch; - struct plug *plug; - - ch = hpsb_get_hostinfo(&cmp_highlevel, host); - plug = (struct plug *)opcr; - if (plug - ch->opcr >= ch->u.ompr.nplugs) BUG(); - - plug->u.pcr.online = 0; - plug->update = NULL; -} - -static void reset_plugs(struct cmp_host *ch) -{ - int i; - - ch->u.ompr.non_persistent_ext = 0xff; - for (i = 0; i < ch->u.ompr.nplugs; i++) { - ch->opcr[i].u.pcr.bcast_count = 0; - ch->opcr[i].u.pcr.p2p_count = 0; - ch->opcr[i].u.pcr.overhead = 0; - } -} - -static void cmp_add_host(struct hpsb_host *host) -{ - struct cmp_host *ch = hpsb_create_hostinfo(&cmp_highlevel, host, sizeof (*ch)); - - if (ch == NULL) { - HPSB_ERR("Failed to allocate cmp_host"); - return; - } - - hpsb_register_addrspace(&cmp_highlevel, host, &pcr_ops, - CSR_REGISTER_BASE + CSR_PCR_MAP, - CSR_REGISTER_BASE + CSR_PCR_MAP_END); - - ch->host = host; - ch->u.ompr.rate = IEEE1394_SPEED_100; - ch->u.ompr.bcast_channel_base = 63; - ch->u.ompr.nplugs = 2; - - reset_plugs(ch); -} - -static void cmp_host_reset(struct hpsb_host *host) -{ - struct cmp_host *ch; - - ch = hpsb_get_hostinfo(&cmp_highlevel, host); - if (ch == NULL) { - HPSB_ERR("cmp: Tried to reset unknown host"); - return; - } - - reset_plugs(ch); -} - -static int pcr_read(struct hpsb_host *host, int nodeid, quadlet_t *buf, - u64 addr, size_t length, u16 flags) -{ - int csraddr = addr - CSR_REGISTER_BASE; - int plug; - struct cmp_host *ch; - - if (length != 4) - return RCODE_TYPE_ERROR; - - ch = hpsb_get_hostinfo(&cmp_highlevel, host); - if (csraddr == 0x900) { - *buf = cpu_to_be32(ch->u.ompr_quadlet); - return RCODE_COMPLETE; - } - else if (csraddr < 0x904 + ch->u.ompr.nplugs * 4) { - plug = (csraddr - 0x904) / 4; - *buf = cpu_to_be32(ch->opcr[plug].u.quadlet); - return RCODE_COMPLETE; - } - else if (csraddr < 0x980) { - return RCODE_ADDRESS_ERROR; - } - else if (csraddr == 0x980) { - *buf = cpu_to_be32(ch->v.impr_quadlet); - return RCODE_COMPLETE; - } - else if (csraddr < 0x984 + ch->v.impr.nplugs * 4) { - plug = (csraddr - 0x984) / 4; - *buf = cpu_to_be32(ch->ipcr[plug].u.quadlet); - return RCODE_COMPLETE; - } - else - return RCODE_ADDRESS_ERROR; -} - -static int pcr_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, - u64 addr, quadlet_t data, quadlet_t arg, int extcode, u16 flags) -{ - int csraddr = addr - CSR_REGISTER_BASE; - int plug; - struct cmp_host *ch; - - ch = hpsb_get_hostinfo(&cmp_highlevel, host); - - if (extcode != EXTCODE_COMPARE_SWAP) - return RCODE_TYPE_ERROR; - - if (csraddr == 0x900) { - /* FIXME: Ignore writes to bits 30-31 and 0-7 */ - *store = cpu_to_be32(ch->u.ompr_quadlet); - if (arg == cpu_to_be32(ch->u.ompr_quadlet)) - ch->u.ompr_quadlet = be32_to_cpu(data); - - return RCODE_COMPLETE; - } - if (csraddr < 0x904 + ch->u.ompr.nplugs * 4) { - plug = (csraddr - 0x904) / 4; - *store = cpu_to_be32(ch->opcr[plug].u.quadlet); - - if (arg == *store) - ch->opcr[plug].u.quadlet = be32_to_cpu(data); - - if (be32_to_cpu(*store) != ch->opcr[plug].u.quadlet && - ch->opcr[plug].update != NULL) - ch->opcr[plug].update(&ch->opcr[plug].u.pcr, - ch->opcr[plug].data); - - return RCODE_COMPLETE; - } - else if (csraddr < 0x980) { - return RCODE_ADDRESS_ERROR; - } - else if (csraddr == 0x980) { - /* FIXME: Ignore writes to bits 24-31 and 0-7 */ - *store = cpu_to_be32(ch->u.ompr_quadlet); - if (arg == cpu_to_be32(ch->u.ompr_quadlet)) - ch->u.ompr_quadlet = be32_to_cpu(data); - - return RCODE_COMPLETE; - } - else if (csraddr < 0x984 + ch->v.impr.nplugs * 4) { - plug = (csraddr - 0x984) / 4; - *store = cpu_to_be32(ch->ipcr[plug].u.quadlet); - - if (arg == *store) - ch->ipcr[plug].u.quadlet = be32_to_cpu(data); - - if (be32_to_cpu(*store) != ch->ipcr[plug].u.quadlet && - ch->ipcr[plug].update != NULL) - ch->ipcr[plug].update(&ch->ipcr[plug].u.pcr, - ch->ipcr[plug].data); - - return RCODE_COMPLETE; - } - else - return RCODE_ADDRESS_ERROR; -} - - -/* Module interface */ - -MODULE_AUTHOR("Kristian Hogsberg <hogsberg@users.sf.net>"); -MODULE_DESCRIPTION("Connection Management Procedures (CMP)"); -MODULE_SUPPORTED_DEVICE("cmp"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cmp_register_opcr); -EXPORT_SYMBOL(cmp_unregister_opcr); - -static int __init cmp_init_module (void) -{ - hpsb_register_highlevel (&cmp_highlevel); - - HPSB_INFO("Loaded CMP driver"); - - return 0; -} - -static void __exit cmp_exit_module (void) -{ - hpsb_unregister_highlevel(&cmp_highlevel); - - HPSB_INFO("Unloaded CMP driver"); -} - -module_init(cmp_init_module); -module_exit(cmp_exit_module); |