#include <asm/types.h>
 
+struct file;
 struct pci_dev;
 struct scatterlist;
 struct vm_area_struct;
 
 EXPORT_SYMBOL(hpsb_make_phypacket);
 EXPORT_SYMBOL(hpsb_read);
 EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
 EXPORT_SYMBOL(hpsb_packet_success);
 
 /** highlevel.c **/
 
 
        return retval;
 }
+
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+             u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
+{
+       struct hpsb_packet *packet;
+       int retval = 0;
+
+       BUG_ON(in_interrupt());
+
+       packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
+       if (!packet)
+               return -ENOMEM;
+
+       packet->generation = generation;
+       retval = hpsb_send_packet_and_wait(packet);
+       if (retval < 0)
+               goto hpsb_lock_fail;
+
+       retval = hpsb_packet_success(packet);
+
+       if (retval == 0)
+               *data = packet->data[0];
+
+hpsb_lock_fail:
+       hpsb_free_tlabel(packet);
+       hpsb_free_packet(packet);
+
+       return retval;
+}
 
              u64 addr, quadlet_t *buffer, size_t length);
 int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
               u64 addr, quadlet_t *buffer, size_t length);
+int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
+             u64 addr, int extcode, quadlet_t *data, quadlet_t arg);
 
 #ifdef HPSB_DEBUG_TLABELS
 extern spinlock_t hpsb_tlabel_lock;
 
 #define IEEE1394_ISO_H
 
 #include <linux/spinlock_types.h>
+#include <linux/wait.h>
 #include <asm/atomic.h>
 #include <asm/types.h>
 
 
 
 obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
 
-obj-$(CONFIG_DVB_FIRESAT)      += firesat/
+obj-$(CONFIG_DVB_FIREDTV)      += firesat/
 
-config DVB_FIRESAT
-       tristate "FireSAT devices"
+config DVB_FIREDTV
+       tristate "FireDTV (FireWire attached DVB receivers)"
        depends on DVB_CORE && IEEE1394 && INPUT
        help
-         Support for external IEEE1394 adapters designed by Digital Everywhere and
-         produced by El Gato, shipped under the brand name 'FireDTV/FloppyDTV'.
+         Support for DVB receivers from Digital Everywhere, known as FireDTV
+         and FloppyDTV, which are connected via IEEE 1394 (FireWire).
 
-         These devices don't have a MPEG decoder built in, so you need
+         These devices don't have an MPEG decoder built in, so you need
          an external software decoder to watch TV.
 
-         Say Y if you own such a device and want to use it.
+         To compile this driver as a module, say M here: the module will be
+         called firedtv.
 
-firesat-objs := firesat_1394.o \
+firedtv-objs := firesat_1394.o \
                firesat_dvb.o   \
                firesat_fe.o    \
                firesat_iso.o   \
                firesat-rc.o    \
                firesat-ci.o
 
-obj-$(CONFIG_DVB_FIRESAT) += firesat.o
+obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
 
 EXTRA_CFLAGS := -Idrivers/ieee1394
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 
 /*
- * FireSAT AVC driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
- * Copyright (c) 2008 Ben Backx <ben@bbackx.com>
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include "firesat.h"
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+
 #include <ieee1394_transactions.h>
 #include <nodemgr.h>
-#include <asm/byteorder.h>
-#include <linux/delay.h>
-#include <linux/crc32.h>
+
 #include "avc_api.h"
+#include "firesat.h"
 #include "firesat-rc.h"
 
 #define RESPONSE_REGISTER                              0xFFFFF0000D00ULL
 module_param(avc_comm_debug, int, 0644);
 MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)");
 
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
-
 /* Frees an allocated packet */
 static void avc_free_packet(struct hpsb_packet *packet)
 {
        return 0;
 }
 
-int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
+int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm)
+{
        int ret;
-       if(down_interruptible(&firesat->avc_sem))
+
+       if (mutex_lock_interruptible(&firesat->avc_mutex))
                return -EINTR;
 
        ret = __AVCWrite(firesat, CmdFrm, RspFrm);
 
-       up(&firesat->avc_sem);
+       mutex_unlock(&firesat->avc_mutex);
        return ret;
 }
 
-static void do_schedule_remotecontrol(unsigned long ignored);
-DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0);
-
-static void do_schedule_remotecontrol(unsigned long ignored) {
-       struct firesat *firesat;
-       unsigned long flags;
-
-       spin_lock_irqsave(&firesat_list_lock, flags);
-       list_for_each_entry(firesat,&firesat_list,list) {
-               if(atomic_read(&firesat->reschedule_remotecontrol) == 1) {
-                       if(down_trylock(&firesat->avc_sem))
-                               tasklet_schedule(&schedule_remotecontrol);
-                       else {
-                               if(__AVCRegisterRemoteControl(firesat, 1) == 0)
-                                       atomic_set(&firesat->reschedule_remotecontrol, 0);
-                               else
-                                       tasklet_schedule(&schedule_remotecontrol);
-
-                               up(&firesat->avc_sem);
-                       }
+int AVCRecv(struct firesat *firesat, u8 *data, size_t length)
+{
+       AVCRspFrm *RspFrm = (AVCRspFrm *)data;
+
+       if (length >= 8 &&
+           RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
+           RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
+           RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
+           RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
+               if (RspFrm->resp == CHANGED) {
+                       firesat_handle_rc(RspFrm->operand[4] << 8 |
+                                         RspFrm->operand[5]);
+                       schedule_work(&firesat->remote_ctrl_work);
+               } else if (RspFrm->resp != INTERIM) {
+                       printk(KERN_INFO "firedtv: remote control result = "
+                              "%d\n", RspFrm->resp);
                }
-       }
-       spin_unlock_irqrestore(&firesat_list_lock, flags);
-}
-
-int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
-//     printk(KERN_INFO "%s\n",__func__);
-
-       // remote control handling
-
-#if 0
-       AVCRspFrm *RspFrm = (AVCRspFrm*)data;
-
-       if(/*RspFrm->length >= 8 && ###*/
-                       ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
-                       RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
-                       RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2)) &&
-                       RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
-               if(RspFrm->resp == CHANGED) {
-//                     printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]);
-                       firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5]));
-
-                       // schedule
-                       atomic_set(&firesat->reschedule_remotecontrol, 1);
-                       tasklet_schedule(&schedule_remotecontrol);
-               } else if(RspFrm->resp != INTERIM)
-                       printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
                return 0;
        }
-#endif
+
        if(atomic_read(&firesat->avc_reply_received) == 1) {
                printk(KERN_ERR "%s: received out-of-order AVC response, "
                       "ignored\n",__func__);
        return 0;
 }
 
-int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) {
+int AVCIdentifySubunit(struct firesat *firesat)
+{
        AVCCmdFrm CmdFrm;
        AVCRspFrm RspFrm;
 
                printk(KERN_ERR "%s: Invalid response length\n", __func__);
                return -EINVAL;
        }
-       if(systemId)
-               *systemId = RspFrm.operand[7];
        return 0;
 }
 
        return 0;
 }
 
-static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal)
+int AVCRegisterRemoteControl(struct firesat *firesat)
 {
        AVCCmdFrm CmdFrm;
 
 
        CmdFrm.length = 8;
 
-       if(internal) {
-               if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
-                       return -EIO;
-       } else
-               if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
-                       return -EIO;
-
-       return 0;
+       return AVCWrite(firesat, &CmdFrm, NULL);
 }
 
-int AVCRegisterRemoteControl(struct firesat*firesat)
+void avc_remote_ctrl_work(struct work_struct *work)
 {
-       return __AVCRegisterRemoteControl(firesat, 0);
+       struct firesat *firesat =
+                       container_of(work, struct firesat, remote_ctrl_work);
+
+       /* Should it be rescheduled in failure cases? */
+       AVCRegisterRemoteControl(firesat);
 }
 
 int AVCTuner_Host2Ca(struct firesat *firesat)
 
-/***************************************************************************
-                          avc_api.h  -  description
-                             -------------------
-    begin                : Wed May 1 2000
-    copyright            : (C) 2000 by Manfred Weihs
-    copyright            : (C) 2003 by Philipp Gutgsell
-    copyright            : (C) 2008 by Henrik Kurelid (henrik@kurelid.se)
-    email                : 0014guph@edu.fh-kaernten.ac.at
- ***************************************************************************/
-
-/***************************************************************************
- *                                                                         *
- *   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 is based on code written by Peter Halwachs,
- Thomas Groiss and Andreas Monitzer.
-*/
-
-
-#ifndef __AVC_API_H__
-#define __AVC_API_H__
-
-#include <linux/dvb/frontend.h>
+ * AV/C API
+ *
+ * Copyright (C) 2000 Manfred Weihs
+ * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
+ *
+ * This is based on code written by Peter Halwachs, Thomas Groiss and
+ * Andreas Monitzer.
+ *
+ *     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 _AVC_API_H
+#define _AVC_API_H
+
+#include <linux/types.h>
 
 /*************************************************************
        Constants from EN510221
 
 #define LNBCONTROL_DONTCARE 0xff
 
-
-extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm);
-extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
-
-extern int AVCTuner_DSIT(struct firesat *firesat,
-                           int Source_Plug,
-                                                  struct dvb_frontend_parameters *params,
-                           __u8 *status);
-
-extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
-extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status);
-extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
-extern int AVCTuner_GetTS(struct firesat *firesat);
-
-extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport);
-extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
-extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
-extern int AVCRegisterRemoteControl(struct firesat *firesat);
-extern int AVCTuner_Host2Ca(struct firesat *firesat);
-extern int avc_ca_app_info(struct firesat *firesat, char *app_info,
-                          int *length);
-extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
-extern int avc_ca_reset(struct firesat *firesat);
-extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
-extern int avc_ca_get_time_date(struct firesat *firesat, int *interval);
-extern int avc_ca_enter_menu(struct firesat *firesat);
-extern int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object,
-                         int *length);
-
-#endif
-
+struct dvb_diseqc_master_cmd;
+struct dvb_frontend_parameters;
+struct firesat;
+
+int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm,
+               AVCRspFrm *RspFrm);
+int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
+
+int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug,
+               struct dvb_frontend_parameters *params, __u8 *status);
+
+int AVCTunerStatus(struct firesat *firesat,
+               ANTENNA_INPUT_INFO *antenna_input_info);
+int AVCTuner_DSD(struct firesat *firesat,
+               struct dvb_frontend_parameters *params, __u8 *status);
+int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
+int AVCTuner_GetTS(struct firesat *firesat);
+
+int AVCIdentifySubunit(struct firesat *firesat);
+int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
+               char conttone, char nrdiseq,
+               struct dvb_diseqc_master_cmd *diseqcmd);
+int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
+void avc_remote_ctrl_work(struct work_struct *work);
+int AVCRegisterRemoteControl(struct firesat *firesat);
+int AVCTuner_Host2Ca(struct firesat *firesat);
+int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length);
+int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
+int avc_ca_reset(struct firesat *firesat);
+int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
+int avc_ca_get_time_date(struct firesat *firesat, int *interval);
+int avc_ca_enter_menu(struct firesat *firesat);
+int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length);
+
+#endif /* _AVC_API_H */
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) ?
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include "cmp.h"
-#include <ieee1394.h>
-#include <nodemgr.h>
-#include <highlevel.h>
-#include <ohci1394.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
 #include <hosts.h>
+#include <ieee1394.h>
 #include <ieee1394_core.h>
 #include <ieee1394_transactions.h>
+#include <nodemgr.h>
+
 #include "avc_api.h"
+#include "cmp.h"
+#include "firesat.h"
 
 typedef struct _OPCR
 {
 
 #define FIRESAT_SPEED IEEE1394_SPEED_400
 
-/* hpsb_lock is being removed from the kernel-source,
- * therefor we define our own 'firesat_hpsb_lock'*/
-
-int send_packet_and_wait(struct hpsb_packet *packet);
-
-int firesat_hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-               u64 addr, int extcode, quadlet_t * data, quadlet_t arg) {
-
-       struct hpsb_packet *packet;
-       int retval = 0;
-
-       BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
-
-       packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
-       if (!packet)
-               return -ENOMEM;
-
-       packet->generation = generation;
-       retval = send_packet_and_wait(packet);
-       if (retval < 0)
-               goto hpsb_lock_fail;
-
-       retval = hpsb_packet_success(packet);
-
-       if (retval == 0) {
-               *data = packet->data[0];
-       }
-
-       hpsb_lock_fail:
-       hpsb_free_tlabel(packet);
-       hpsb_free_packet(packet);
-
-       return retval;
-}
-
-
-static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) {
+static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len)
+{
        int ret;
-       if(down_interruptible(&firesat->avc_sem))
+
+       if (mutex_lock_interruptible(&firesat->avc_mutex))
                return -EINTR;
 
-       ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
-               addr, buffer, length);
+       ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid,
+                       firesat->nodeentry->generation, addr, buf, len);
 
-       up(&firesat->avc_sem);
+       mutex_unlock(&firesat->avc_mutex);
        return ret;
 }
 
-static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) {
+static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr,
+               quadlet_t arg, int ext_tcode)
+{
        int ret;
-       if(down_interruptible(&firesat->avc_sem))
+
+       if (mutex_lock_interruptible(&firesat->avc_mutex))
                return -EINTR;
 
-       ret = firesat_hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation,
-               addr, ext_tcode, data, arg);
+       ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid,
+                       firesat->nodeentry->generation,
+                       addr, ext_tcode, data, arg);
 
-       up(&firesat->avc_sem);
+       mutex_unlock(&firesat->avc_mutex);
        return ret;
 }
 
     }
        return 0;
 }
-
-static void complete_packet(void *data) {
-       complete((struct completion *) data);
-}
-
-int send_packet_and_wait(struct hpsb_packet *packet) {
-       struct completion done;
-       int retval;
-
-       init_completion(&done);
-       hpsb_set_packet_complete_task(packet, complete_packet, &done);
-       retval = hpsb_send_packet(packet);
-       if (retval == 0)
-               wait_for_completion(&done);
-
-       return retval;
-}
 
-#ifndef __FIRESAT__CMP_H_
-#define __FIRESAT__CMP_H_
+#ifndef _CMP_H
+#define _CMP_H
 
-#include "firesat.h"
+struct firesat;
 
-extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel);
-extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel);
+int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug,
+               int iso_channel);
+int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,
+               int iso_channel);
 
-#endif
+#endif /* _CMP_H */
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include "firesat-ci.h"
-#include "firesat.h"
-#include "avc_api.h"
-
 #include <linux/dvb/ca.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+
 #include <dvbdev.h>
 
+#include "avc_api.h"
+#include "firesat.h"
+#include "firesat-ci.h"
+
 static unsigned int ca_debug = 0;
 module_param(ca_debug, int, 0644);
 MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)");
 
-#ifndef __FIRESAT_CA_H
-#define __FIRESAT_CA_H
+#ifndef _FIREDTV_CI_H
+#define _FIREDTV_CI_H
 
-#include "firesat.h"
+struct firesat;
 
 int firesat_ca_init(struct firesat *firesat);
 void firesat_ca_release(struct firesat *firesat);
 
-#endif
+#endif /* _FIREDTV_CI_H */
 
-#include "firesat.h"
-#include "firesat-rc.h"
+/*
+ * FireDTV driver (formerly known as FireSAT)
+ *
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ *
+ *     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.
+ */
 
+#include <linux/bitops.h>
 #include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "firesat-rc.h"
+
+/* fixed table with older keycodes, geared towards MythTV */
+const static u16 oldtable[] = {
+
+       /* code from device: 0x4501...0x451f */
 
-static u16 firesat_irtable[] = {
        KEY_ESC,
        KEY_F9,
        KEY_1,
        KEY_RIGHT,
        KEY_P,
        KEY_M,
+
+       /* code from device: 0x4540...0x4542 */
+
        KEY_R,
        KEY_V,
        KEY_C,
-       0
 };
 
-static struct input_dev firesat_idev;
+/* user-modifiable table for a remote as sold in 2008 */
+static u16 keytable[] = {
+
+       /* code from device: 0x0300...0x031f */
+
+       [0x00] = KEY_POWER,
+       [0x01] = KEY_SLEEP,
+       [0x02] = KEY_STOP,
+       [0x03] = KEY_OK,
+       [0x04] = KEY_RIGHT,
+       [0x05] = KEY_1,
+       [0x06] = KEY_2,
+       [0x07] = KEY_3,
+       [0x08] = KEY_LEFT,
+       [0x09] = KEY_4,
+       [0x0a] = KEY_5,
+       [0x0b] = KEY_6,
+       [0x0c] = KEY_UP,
+       [0x0d] = KEY_7,
+       [0x0e] = KEY_8,
+       [0x0f] = KEY_9,
+       [0x10] = KEY_DOWN,
+       [0x11] = KEY_TITLE,     /* "OSD" - fixme */
+       [0x12] = KEY_0,
+       [0x13] = KEY_F20,       /* "16:9" - fixme */
+       [0x14] = KEY_SCREEN,    /* "FULL" - fixme */
+       [0x15] = KEY_MUTE,
+       [0x16] = KEY_SUBTITLE,
+       [0x17] = KEY_RECORD,
+       [0x18] = KEY_TEXT,
+       [0x19] = KEY_AUDIO,
+       [0x1a] = KEY_RED,
+       [0x1b] = KEY_PREVIOUS,
+       [0x1c] = KEY_REWIND,
+       [0x1d] = KEY_PLAYPAUSE,
+       [0x1e] = KEY_NEXT,
+       [0x1f] = KEY_VOLUMEUP,
+
+       /* code from device: 0x0340...0x0354 */
+
+       [0x20] = KEY_CHANNELUP,
+       [0x21] = KEY_F21,       /* "4:3" - fixme */
+       [0x22] = KEY_TV,
+       [0x23] = KEY_DVD,
+       [0x24] = KEY_VCR,
+       [0x25] = KEY_AUX,
+       [0x26] = KEY_GREEN,
+       [0x27] = KEY_YELLOW,
+       [0x28] = KEY_BLUE,
+       [0x29] = KEY_CHANNEL,   /* "CH.LIST" */
+       [0x2a] = KEY_VENDOR,    /* "CI" - fixme */
+       [0x2b] = KEY_VOLUMEDOWN,
+       [0x2c] = KEY_CHANNELDOWN,
+       [0x2d] = KEY_LAST,
+       [0x2e] = KEY_INFO,
+       [0x2f] = KEY_FORWARD,
+       [0x30] = KEY_LIST,
+       [0x31] = KEY_FAVORITES,
+       [0x32] = KEY_MENU,
+       [0x33] = KEY_EPG,
+       [0x34] = KEY_EXIT,
+};
+
+static struct input_dev *idev;
 
 int firesat_register_rc(void)
 {
-       int index;
+       int i, err;
+
+       idev = input_allocate_device();
+       if (!idev)
+               return -ENOMEM;
 
-       memset(&firesat_idev, 0, sizeof(firesat_idev));
+       idev->name = "FireDTV remote control";
+       idev->evbit[0] = BIT_MASK(EV_KEY);
+       idev->keycode = keytable;
+       idev->keycodesize = sizeof(keytable[0]);
+       idev->keycodemax = ARRAY_SIZE(keytable);
 
-       firesat_idev.evbit[0] = BIT(EV_KEY);
+       for (i = 0; i < ARRAY_SIZE(keytable); i++)
+               set_bit(keytable[i], idev->keybit);
 
-       for (index = 0; firesat_irtable[index] != 0; index++)
-               set_bit(firesat_irtable[index], firesat_idev.keybit);
+       err = input_register_device(idev);
+       if (err)
+               input_free_device(idev);
 
-       return input_register_device(&firesat_idev);
+       return err;
 }
 
-int firesat_unregister_rc(void)
+void firesat_unregister_rc(void)
 {
-       input_unregister_device(&firesat_idev);
-       return 0;
+       input_unregister_device(idev);
 }
 
-int firesat_got_remotecontrolcode(u16 code)
+void firesat_handle_rc(unsigned int code)
 {
-       u16 keycode;
-
-       if (code > 0x4500 && code < 0x4520)
-               keycode = firesat_irtable[code - 0x4501];
-       else if (code > 0x453f && code < 0x4543)
-               keycode = firesat_irtable[code - 0x4521];
+       if (code >= 0x0300 && code <= 0x031f)
+               code = keytable[code - 0x0300];
+       else if (code >= 0x0340 && code <= 0x0354)
+               code = keytable[code - 0x0320];
+       else if (code >= 0x4501 && code <= 0x451f)
+               code = oldtable[code - 0x4501];
+       else if (code >= 0x4540 && code <= 0x4542)
+               code = oldtable[code - 0x4521];
        else {
-               printk(KERN_DEBUG "%s: invalid key code 0x%04x\n", __func__,
-                      code);
-               return -EINVAL;
+               printk(KERN_DEBUG "firedtv: invalid key code 0x%04x "
+                      "from remote control\n", code);
+               return;
        }
 
-       input_report_key(&firesat_idev, keycode, 1);
-       input_report_key(&firesat_idev, keycode, 0);
-
-       return 0;
+       input_report_key(idev, code, 1);
+       input_report_key(idev, code, 0);
 }
 
-#ifndef __FIRESAT_LIRC_H
-#define __FIRESAT_LIRC_H
+#ifndef _FIREDTV_RC_H
+#define _FIREDTV_RC_H
 
-extern int firesat_register_rc(void);
-extern int firesat_unregister_rc(void);
-extern int firesat_got_remotecontrolcode(u16 code);
-
-#endif
+int firesat_register_rc(void);
+void firesat_unregister_rc(void);
+void firesat_handle_rc(unsigned int code);
 
+#endif /* _FIREDTV_RC_H */
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) ?
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#ifndef __FIRESAT_H
-#define __FIRESAT_H
+#ifndef _FIREDTV_H
+#define _FIREDTV_H
 
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-
-#include <linux/version.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
-#include <linux/semaphore.h>
-#endif
-#include <linux/dvb/frontend.h>
 #include <linux/dvb/dmx.h>
-#include <iso.h>
+#include <linux/dvb/frontend.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+
+#include <demux.h>
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvb_net.h>
+#include <dvbdev.h>
 
+#include <linux/version.h>
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
 #define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v)
 #else
 
 
 enum model_type {
-       FireSAT_DVB_S = 1,
-       FireSAT_DVB_C = 2,
-       FireSAT_DVB_T = 3,
-       FireSAT_DVB_S2 = 4
+       FireSAT_UNKNOWN = 0,
+       FireSAT_DVB_S   = 1,
+       FireSAT_DVB_C   = 2,
+       FireSAT_DVB_T   = 3,
+       FireSAT_DVB_S2  = 4,
 };
 
+struct hpsb_host;
+struct hpsb_iso;
+struct node_entry;
+
 struct firesat {
        struct dvb_demux dvb_demux;
-       char *model_name;
 
        /* DVB bits */
        struct dvb_adapter              *adapter;
        int                             ca_last_command;
        int                             ca_time_interval;
 
-       struct semaphore                avc_sem;
+       struct mutex                    avc_mutex;
        wait_queue_head_t               avc_wait;
        atomic_t                        avc_reply_received;
-
-       atomic_t                        reschedule_remotecontrol;
+       struct work_struct              remote_ctrl_work;
 
        struct firesat_channel {
                struct firesat *firesat;
                int pid;
                int type;       /* 1 - TS, 2 - Filter */
        } channel[16];
-       struct semaphore                demux_sem;
+       struct mutex                    demux_mutex;
 
        /* needed by avc_api */
        void *respfrm;
        };
 };
 
+extern const char *firedtv_model_names[];
 extern struct list_head firesat_list;
 extern spinlock_t firesat_list_lock;
 
+struct device;
+
 /* firesat_dvb.c */
-extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
-extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
-extern int firesat_dvbdev_init(struct firesat *firesat,
-                              struct device *dev,
-                              struct dvb_frontend *fe);
+int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
+int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
+int firesat_dvbdev_init(struct firesat *firesat, struct device *dev,
+               struct dvb_frontend *fe);
 
 /* firesat_fe.c */
-extern int firesat_frontend_attach(struct firesat *firesat,
-                                  struct dvb_frontend *fe);
+int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe);
 
 /* firesat_iso.c */
-extern int setup_iso_channel(struct firesat *firesat);
-extern void tear_down_iso_channel(struct firesat *firesat);
+int setup_iso_channel(struct firesat *firesat);
+void tear_down_iso_channel(struct firesat *firesat);
 
-#endif
+#endif /* _FIREDTV_H */
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
- * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com>
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/time.h>
+#include <linux/device.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <ieee1394_hotplug.h>
-#include <nodemgr.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/atomic.h>
+
+#include <dmxdev.h>
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
+#include <dvbdev.h>
+
+#include <csr1212.h>
 #include <highlevel.h>
-#include <ohci1394.h>
 #include <hosts.h>
-#include <dvbdev.h>
+#include <ieee1394_hotplug.h>
+#include <nodemgr.h>
 
-#include "firesat.h"
 #include "avc_api.h"
 #include "cmp.h"
-#include "firesat-rc.h"
+#include "firesat.h"
 #include "firesat-ci.h"
+#include "firesat-rc.h"
 
 #define FIRESAT_Vendor_ID   0x001287
 
 LIST_HEAD(firesat_list);
 spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED;
 
-static void firesat_add_host(struct hpsb_host *host);
-static void firesat_remove_host(struct hpsb_host *host);
-static void firesat_host_reset(struct hpsb_host *host);
-
-static void fcp_request(struct hpsb_host *host,
-                       int nodeid,
-                       int direction,
-                       int cts,
-                       u8 *data,
-                       size_t length);
-
-static struct hpsb_highlevel firesat_highlevel = {
-       .name           = "FireSAT",
-       .add_host       = firesat_add_host,
-       .remove_host    = firesat_remove_host,
-       .host_reset     = firesat_host_reset,
-       .fcp_request    = fcp_request,
-};
-
-static void firesat_add_host (struct hpsb_host *host)
-{
-       struct ti_ohci *ohci = (struct ti_ohci *)host->hostdata;
-
-       /* We only work with the OHCI-1394 driver */
-       if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME))
-               return;
-
-       if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) {
-               printk(KERN_ERR "Cannot allocate hostinfo\n");
-               return;
-       }
-
-       hpsb_set_hostinfo(&firesat_highlevel, host, ohci);
-       hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id);
-}
-
-static void firesat_remove_host (struct hpsb_host *host)
-{
-
-}
-
-static void firesat_host_reset(struct hpsb_host *host)
-{
-    printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
-}
-
 static void fcp_request(struct hpsb_host *host,
                        int nodeid,
                        int direction,
          printk("%s: received invalid fcp request, ignored\n", __func__);
 }
 
+const char *firedtv_model_names[] = {
+       [FireSAT_UNKNOWN] = "unknown type",
+       [FireSAT_DVB_S]   = "FireDTV S/CI",
+       [FireSAT_DVB_C]   = "FireDTV C/CI",
+       [FireSAT_DVB_T]   = "FireDTV T/CI",
+       [FireSAT_DVB_S2]  = "FireDTV S2  ",
+};
+
 static int firesat_probe(struct device *dev)
 {
        struct unit_directory *ud = container_of(dev, struct unit_directory, device);
        unsigned char subunitcount = 0xff, subunit;
        struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
        int kv_len;
+       int i;
        char *kv_buf;
 
        if (!firesats) {
                        return -ENOMEM;
                }
 
-               sema_init(&firesat->avc_sem, 1);
+               mutex_init(&firesat->avc_mutex);
                init_waitqueue_head(&firesat->avc_wait);
                atomic_set(&firesat->avc_reply_received, 1);
-               sema_init(&firesat->demux_sem, 1);
-               atomic_set(&firesat->reschedule_remotecontrol, 0);
+               mutex_init(&firesat->demux_mutex);
+               INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work);
 
                spin_lock_irqsave(&firesat_list_lock, flags);
                INIT_LIST_HEAD(&firesat->list);
                while ((kv_buf + kv_len - 1) == '\0') kv_len--;
                kv_buf[kv_len++] = '\0';
 
-               /* Determining the device model */
-               if (strcmp(kv_buf, "FireDTV S/CI") == 0) {
-                       printk(KERN_INFO "%s: found DVB/S\n", __func__);
-                       firesat->type = 1;
-               } else if (strcmp(kv_buf, "FireDTV C/CI") == 0) {
-                       printk(KERN_INFO "%s: found DVB/C\n", __func__);
-                       firesat->type = 2;
-               } else if (strcmp(kv_buf, "FireDTV T/CI") == 0) {
-                       printk(KERN_INFO "%s: found DVB/T\n", __func__);
-                       firesat->type = 3;
-               } else if (strcmp(kv_buf, "FireDTV S2  ") == 0) {
-                       printk(KERN_INFO "%s: found DVB/S2\n", __func__);
-                       firesat->type = 4;
-               }
+               for (i = ARRAY_SIZE(firedtv_model_names); --i;)
+                       if (strcmp(kv_buf, firedtv_model_names[i]) == 0)
+                               break;
+               firesat->type = i;
                kfree(kv_buf);
 
-               if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) {
+               if (AVCIdentifySubunit(firesat)) {
                        printk("%s: cannot identify subunit %d\n", __func__, subunit);
                        spin_lock_irqsave(&firesat_list_lock, flags);
                        list_del(&firesat->list);
                }
 
 // ----
+               /* FIXME: check for error return */
                firesat_dvbdev_init(firesat, dev, fe);
 // ----
                firesats[subunit] = firesat;
        } // loop for all tuners
 
-       //beta ;-) Disable remote control stuff to avoid crashing
-       //if(firesats[0])
-       //      AVCRegisterRemoteControl(firesats[0]);
+       if (firesats[0])
+               AVCRegisterRemoteControl(firesats[0]);
 
     return 0;
 }
                                list_del(&firesats[k]->list);
                                spin_unlock_irqrestore(&firesat_list_lock, flags);
 
+                               cancel_work_sync(&firesats[k]->remote_ctrl_work);
+
                                kfree(firesats[k]->fe);
                                kfree(firesats[k]->adapter);
                                kfree(firesats[k]->respfrm);
 
 static struct hpsb_protocol_driver firesat_driver = {
 
-       .name           = "FireSAT",
+       .name           = "firedtv",
        .id_table       = firesat_id_table,
        .update         = firesat_update,
 
        },
 };
 
+static struct hpsb_highlevel firesat_highlevel = {
+       .name           = "firedtv",
+       .fcp_request    = fcp_request,
+};
+
 static int __init firesat_init(void)
 {
        int ret;
 
-       printk(KERN_INFO "FireSAT loaded\n");
        hpsb_register_highlevel(&firesat_highlevel);
        ret = hpsb_register_protocol(&firesat_driver);
        if (ret) {
-               printk(KERN_ERR "FireSAT: failed to register protocol\n");
-               hpsb_unregister_highlevel(&firesat_highlevel);
-               return ret;
+               printk(KERN_ERR "firedtv: failed to register protocol\n");
+               goto fail;
        }
 
-       //Crash in this function, just disable RC for the time being...
-       //Don't forget to uncomment in firesat_exit and firesat_probe when you enable this.
-       /*if((ret=firesat_register_rc()))
-               printk("%s: firesat_register_rc return error code %d (ignored)\n", __func__, ret);*/
+       ret = firesat_register_rc();
+       if (ret) {
+               printk(KERN_ERR "firedtv: failed to register input device\n");
+               goto fail_rc;
+       }
 
        return 0;
+fail_rc:
+       hpsb_unregister_protocol(&firesat_driver);
+fail:
+       hpsb_unregister_highlevel(&firesat_highlevel);
+       return ret;
 }
 
 static void __exit firesat_exit(void)
 {
+       firesat_unregister_rc();
        hpsb_unregister_protocol(&firesat_driver);
        hpsb_unregister_highlevel(&firesat_highlevel);
-       printk(KERN_INFO "FireSAT quit\n");
 }
 
 module_init(firesat_init);
 
 MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
 MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
-MODULE_DESCRIPTION("FireSAT DVB Driver");
+MODULE_DESCRIPTION("FireDTV DVB Driver");
 MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("FireSAT DVB");
+MODULE_SUPPORTED_DEVICE("FireDTV DVB");
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) ?
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/time.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <ieee1394_hotplug.h>
-#include <nodemgr.h>
-#include <highlevel.h>
-#include <ohci1394.h>
-#include <hosts.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
 #include <dvbdev.h>
 
-#include "firesat.h"
 #include "avc_api.h"
-#include "cmp.h"
-#include "firesat-rc.h"
+#include "firesat.h"
 #include "firesat-ci.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
 {
+       struct firesat_channel *c = NULL;
        int k;
 
-       //printk(KERN_INFO "%s\n", __func__);
-
-       if (down_interruptible(&firesat->demux_sem))
+       if (mutex_lock_interruptible(&firesat->demux_mutex))
                return NULL;
 
-       for (k = 0; k < 16; k++) {
-               //printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid);
-
+       for (k = 0; k < 16; k++)
                if (firesat->channel[k].active == 0) {
                        firesat->channel[k].active = 1;
-                       up(&firesat->demux_sem);
-                       return &firesat->channel[k];
+                       c = &firesat->channel[k];
+                       break;
                }
-       }
 
-       up(&firesat->demux_sem);
-       return NULL; // no more channels available
+       mutex_unlock(&firesat->demux_mutex);
+       return c;
 }
 
 static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[])
 {
        int k, l = 0;
 
-       if (down_interruptible(&firesat->demux_sem))
+       if (mutex_lock_interruptible(&firesat->demux_mutex))
                return -EINTR;
 
        for (k = 0; k < 16; k++)
                if (firesat->channel[k].active == 1)
                        pid[l++] = firesat->channel[k].pid;
 
-       up(&firesat->demux_sem);
+       mutex_unlock(&firesat->demux_mutex);
 
        *pidc = l;
 
 static int firesat_channel_release(struct firesat *firesat,
                                   struct firesat_channel *channel)
 {
-       if (down_interruptible(&firesat->demux_sem))
+       if (mutex_lock_interruptible(&firesat->demux_mutex))
                return -EINTR;
 
        channel->active = 0;
 
-       up(&firesat->demux_sem);
+       mutex_unlock(&firesat->demux_mutex);
        return 0;
 }
 
 {
        struct dvb_demux *demux = dvbdmxfeed->demux;
        struct firesat *firesat = (struct firesat*)demux->priv;
-       int k, l = 0;
+       struct firesat_channel *c = dvbdmxfeed->priv;
+       int k, l;
        u16 pids[16];
 
        //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
                        return 0;
        }
 
-       if (down_interruptible(&firesat->demux_sem))
+       if (mutex_lock_interruptible(&firesat->demux_mutex))
                return -EINTR;
 
-
-       // list except channel to be removed
-       for (k = 0; k < 16; k++)
+       /* list except channel to be removed */
+       for (k = 0, l = 0; k < 16; k++)
                if (firesat->channel[k].active == 1) {
-                       if (&firesat->channel[k] !=
-                               (struct firesat_channel *)dvbdmxfeed->priv)
+                       if (&firesat->channel[k] != c)
                                pids[l++] = firesat->channel[k].pid;
                        else
                                firesat->channel[k].active = 0;
                }
 
-       if ((k = AVCTuner_SetPIDs(firesat, l, pids))) {
-               up(&firesat->demux_sem);
-               return k;
-       }
+       k = AVCTuner_SetPIDs(firesat, l, pids);
+       if (!k)
+               c->active = 0;
 
-       ((struct firesat_channel *)dvbdmxfeed->priv)->active = 0;
-
-       up(&firesat->demux_sem);
-
-       return 0;
+       mutex_unlock(&firesat->demux_mutex);
+       return k;
 }
 
 int firesat_dvbdev_init(struct firesat *firesat,
 {
        int result;
 
-#if 0
-               switch (firesat->type) {
-               case FireSAT_DVB_S:
-                       firesat->model_name = "FireSAT DVB-S";
-                       firesat->frontend_info = &firesat_S_frontend_info;
-                       break;
-               case FireSAT_DVB_C:
-                       firesat->model_name = "FireSAT DVB-C";
-                       firesat->frontend_info = &firesat_C_frontend_info;
-                       break;
-               case FireSAT_DVB_T:
-                       firesat->model_name = "FireSAT DVB-T";
-                       firesat->frontend_info = &firesat_T_frontend_info;
-                       break;
-               default:
-                       printk("%s: unknown model type 0x%x on subunit %d!\n",
-                               __func__, firesat->type,subunit);
-                       firesat->model_name = "Unknown";
-                       firesat->frontend_info = NULL;
-               }
-#endif
-/* // ------- CRAP -----------
-               if (!firesat->frontend_info) {
-                       spin_lock_irqsave(&firesat_list_lock, flags);
-                       list_del(&firesat->list);
-                       spin_unlock_irqrestore(&firesat_list_lock, flags);
-                       kfree(firesat);
-                       continue;
-               }
-*/
-               //initialising firesat->adapter before calling dvb_register_adapter
-               if (!(firesat->adapter = kmalloc(sizeof (struct dvb_adapter), GFP_KERNEL))) {
-                       printk("%s: couldn't allocate memory.\n", __func__);
-                       kfree(firesat->adapter);
-                       kfree(firesat);
-                       return -ENOMEM;
-               }
-
-               if ((result = DVB_REGISTER_ADAPTER(firesat->adapter,
-                                                  firesat->model_name,
-                                                  THIS_MODULE,
-                                                  dev, adapter_nr)) < 0) {
-
-                       printk("%s: dvb_register_adapter failed: error %d\n", __func__, result);
-#if 0
-                       /* ### cleanup */
-                       spin_lock_irqsave(&firesat_list_lock, flags);
-                       list_del(&firesat->list);
-                       spin_unlock_irqrestore(&firesat_list_lock, flags);
-#endif
-                       kfree(firesat);
+       firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL);
+       if (!firesat->adapter) {
+               printk(KERN_ERR "firedtv: couldn't allocate memory\n");
+               return -ENOMEM;
+       }
 
-                       return result;
-               }
+       result = DVB_REGISTER_ADAPTER(firesat->adapter,
+                                     firedtv_model_names[firesat->type],
+                                     THIS_MODULE, dev, adapter_nr);
+       if (result < 0) {
+               printk(KERN_ERR "firedtv: dvb_register_adapter failed\n");
+               kfree(firesat->adapter);
+               return result;
+       }
 
                memset(&firesat->demux, 0, sizeof(struct dvb_demux));
                firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
 
 /*
- * FireSAT DVB driver
+ * FireDTV driver (formerly known as FireSAT)
  *
- * Copyright (c) ?
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/time.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <ieee1394_hotplug.h>
-#include <nodemgr.h>
-#include <highlevel.h>
-#include <ohci1394.h>
-#include <hosts.h>
-#include <dvbdev.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <dvb_frontend.h>
 
-#include "firesat.h"
 #include "avc_api.h"
 #include "cmp.h"
-#include "firesat-rc.h"
-#include "firesat-ci.h"
+#include "firesat.h"
 
 static int firesat_dvb_init(struct dvb_frontend *fe)
 {
 {
        switch (firesat->type) {
        case FireSAT_DVB_S:
-               firesat->model_name = "FireSAT DVB-S";
                firesat->frontend_info = &firesat_S_frontend_info;
                break;
        case FireSAT_DVB_C:
-               firesat->model_name = "FireSAT DVB-C";
                firesat->frontend_info = &firesat_C_frontend_info;
                break;
        case FireSAT_DVB_T:
-               firesat->model_name = "FireSAT DVB-T";
                firesat->frontend_info = &firesat_T_frontend_info;
                break;
        default:
-               printk("%s: unknown model type 0x%x !\n",
-                       __func__, firesat->type);
-               firesat->model_name = "Unknown";
+               printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n",
+                      firesat->type);
                firesat->frontend_info = NULL;
        }
        fe->ops = firesat_ops;
 
 static struct dvb_frontend_info firesat_S_frontend_info = {
 
-       .name                   = "FireSAT DVB-S Frontend",
+       .name                   = "FireDTV DVB-S Frontend",
        .type                   = FE_QPSK,
 
        .frequency_min          = 950000,
 
 static struct dvb_frontend_info firesat_C_frontend_info = {
 
-       .name                   = "FireSAT DVB-C Frontend",
+       .name                   = "FireDTV DVB-C Frontend",
        .type                   = FE_QAM,
 
        .frequency_min          = 47000000,
 
 static struct dvb_frontend_info firesat_T_frontend_info = {
 
-       .name                   = "FireSAT DVB-T Frontend",
+       .name                   = "FireDTV DVB-T Frontend",
        .type                   = FE_OFDM,
 
        .frequency_min          = 49000000,
 
 /*
  * FireSAT DVB driver
  *
- * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
+ * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
  *     the License, or (at your option) any later version.
  */
 
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+#include <dvb_demux.h>
+
+#include <dma.h>
+#include <iso.h>
+
 #include "firesat.h"
 
 static void rawiso_activity_cb(struct hpsb_iso *iso);