work from JiSheng Zhang : firewire and ohci modules from FreeBSD current, update for fw_raw and fw_control. Thanks!

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22124 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2007-08-30 21:59:49 +00:00
parent 68f2081497
commit bb5ea4eb08
27 changed files with 7725 additions and 98 deletions

View File

@ -5,63 +5,61 @@
*/
#ifndef _FW_MODULE_H
#define _FW_MODULE_H
#include <KernelExport.h>
#include <module.h>
#include <bus_manager.h>
#include "firewire.h"
#include "firewirereg.h"
#define FIREWIRE_MODULE_NAME "bus_managers/firewire/v1"
#define MAX_CARDS 4
struct fw_module_info{
bus_manager_info binfo;
struct fw_device * (*fw_noderesolve_nodeid)(struct firewire_comm *fc, int dst);
struct fw_device * (*fw_noderesolve_nodeid)(struct firewire_comm *fc, int dst);
struct fw_device * (*fw_noderesolve_eui64)(struct firewire_comm *fc, struct fw_eui64 *eui);
struct fw_device * (*fw_noderesolve_eui64)(struct firewire_comm *fc, struct fw_eui64 *eui);
int (*fw_asyreq)(struct firewire_comm *fc, int sub, struct fw_xfer *xfer);
int (*fw_asyreq)(struct firewire_comm *fc, int sub, struct fw_xfer *xfer);
void (*fw_xferwake)(struct fw_xfer *xfer);
int (*fw_xferwait)(struct fw_xfer *xfer);
void (*fw_xferwake)(struct fw_xfer *xfer);
int (*fw_xferwait)(struct fw_xfer *xfer);
struct fw_bind * (*fw_bindlookup)(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo);
struct fw_bind * (*fw_bindlookup)(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo);
int (*fw_bindadd)(struct firewire_comm *fc, struct fw_bind *fwb);
int (*fw_bindremove)(struct firewire_comm *fc, struct fw_bind *fwb);
int (*fw_xferlist_add)(struct fw_xferlist *q,
int slen, int rlen, int n,
struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *));
void (*fw_xferlist_remove)(struct fw_xferlist *q);
struct fw_xfer * (*fw_xfer_alloc)();
struct fw_xfer * (*fw_xfer_alloc_buf)(int send_len, int recv_len);
void (*fw_xfer_done)(struct fw_xfer *xfer);
void (*fw_xfer_unload)(struct fw_xfer* xfer);
void (*fw_xfer_free_buf)( struct fw_xfer* xfer);
void (*fw_xfer_free)( struct fw_xfer* xfer);
void (*fw_asy_callback_free)(struct fw_xfer *xfer);
int (*fw_open_isodma)(struct firewire_comm *fc, int tx);
int (*get_handle)(int socket, struct firewire_softc *handle);
struct fwdma_alloc_multi * (*fwdma_malloc_multiseg)(int alignment,
int esize, int n);
void (*fwdma_free_multiseg)(struct fwdma_alloc_multi *);
int (*fw_bindadd)(struct firewire_comm *fc, struct fw_bind *fwb);
int (*fw_bindremove)(struct firewire_comm *fc, struct fw_bind *fwb);
int (*fw_xferlist_add)(struct fw_xferlist *q,
int slen, int rlen, int n,
struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *));
void (*fw_xferlist_remove)(struct fw_xferlist *q);
struct fw_xfer * (*fw_xfer_alloc)();
struct fw_xfer * (*fw_xfer_alloc_buf)(int send_len, int recv_len);
void (*fw_xfer_done)(struct fw_xfer *xfer);
void (*fw_xfer_unload)(struct fw_xfer* xfer);
void (*fw_xfer_free_buf)( struct fw_xfer* xfer);
void (*fw_xfer_free)( struct fw_xfer* xfer);
void (*fw_asy_callback_free)(struct fw_xfer *xfer);
int (*fw_open_isodma)(struct firewire_comm *fc, int tx);
int (*get_handle)(int socket, struct firewire_softc **handle);
struct fwdma_alloc_multi * (*fwdma_malloc_multiseg)(int alignment,
int esize, int n);
void (*fwdma_free_multiseg)(struct fwdma_alloc_multi *);
};
#endif

View File

@ -36,7 +36,9 @@
*/
#ifndef _FIREWIREREG_H
#define _FIREWIREREG_H
#ifndef __HAIKU__
#ifdef __HAIKU__
#include <OS.h>
#else
#ifdef __DragonFly__
typedef d_thread_t fw_proc;
#include <sys/select.h>
@ -55,11 +57,15 @@ typedef struct proc fw_proc;
#include <sys/mutex.h>
#include <sys/taskqueue.h>
#define splfw splimp
#else
#define splfw disable_interrupts
#define splx restore_interrupts
#else
#include <lock.h>
#include <dpc.h>
#include "fwglue.h"
#include "timer.h"
#endif
#define MAX_REQCOUNT 0xffff
STAILQ_HEAD(fw_xferlist, fw_xfer);
struct fw_device{
@ -119,8 +125,20 @@ struct crom_src_buf {
struct crom_chunk root;
struct crom_chunk vendor;
struct crom_chunk hw;
};//move from firewire.c to here
struct firewire_notify_hooks {
status_t (*device_attach)(struct firewire_softc *sc, void **cookie);
status_t (*device_detach)(struct firewire_softc *sc, void *cookie);
};
#endif //move from firewire.c to firewirereg.h
struct firewire_child_info {
const char *child_name;
void *cookie;
struct firewire_notify_hooks notify_hooks;
struct firewire_child_info *link;
};
#endif
struct firewire_comm{
#ifndef __HAIKU__
@ -171,12 +189,12 @@ struct firewire_comm{
struct callout busprobe_callout;
struct callout bmr_callout;
struct callout timeout_callout;
struct task task_timeout;
#else
//timer_id busprobe_callout;
//timer_id bmr_callout;
//timer_id timeout_callout;
timer_id busprobe_callout;
timer_id bmr_callout;
timer_id timeout_callout;
#endif
//struct task task_timeout;
uint32_t (*cyctimer) (struct firewire_comm *);
void (*ibr) (struct firewire_comm *);
uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
@ -199,29 +217,28 @@ struct firewire_comm{
bus_dma_tag_t dmat;
struct mtx mtx;
struct mtx wait_lock;
#else
sem_id mtx;
sem_id wait_lock;
#endif
// struct taskqueue *taskqueue;//to be completed
#ifndef __HAIKU__
struct taskqueue *taskqueue;
struct proc *probe_thread;
#else
benaphore mtx;
benaphore wait_lock;
void *taskqueue;
thread_id probe_thread;
sem_id Sem;
area_id crom_sid_Area;
struct firewire_child_info *childList;
#endif
};
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
#ifndef __HAIKU__
#define FW_GMTX(fc) (&(fc)->mtx)
#define FW_GLOCK(fc) mtx_lock(FW_GMTX(fc))
#define FW_GUNLOCK(fc) mtx_unlock(FW_GMTX(fc))
#ifndef __HAIKU__
#define FW_GLOCK_ASSERT(fc) mtx_assert(FW_GMTX(fc), MA_OWNED)
#endif
#define FW_GMTX(fc) ((fc)->mtx)
#define FW_GLOCK(fc) acquire_sem_etc(FW_GMTX(fc), 1, B_CAN_INTERRUPT | B_TIMEOUT, 0)
#define FW_GUNLOCK(fc) release_sem(FW_GMTX(fc))
#else
#define FW_GLOCK_ASSERT(fc)
#endif
struct fw_xferq {
int flag;
@ -252,15 +269,15 @@ struct fw_xferq {
STAILQ_HEAD(, fw_bulkxfer) stdma;
struct fw_bulkxfer *stproc;
// struct selinfo rsel;
spinlock Spinlock;
sem_id Sem;
caddr_t sc;
void (*hand) (struct fw_xferq *);
spinlock Spinlock;
sem_id Sem;
};
struct fw_bulkxfer{
int poffset;
// struct mbuf *mbuf;//to be completed
// struct mbuf *mbuf;
STAILQ_ENTRY(fw_bulkxfer) link;
caddr_t start;
caddr_t end;
@ -280,8 +297,10 @@ struct fw_xfer{
caddr_t sc;
struct firewire_comm *fc;
struct fw_xferq *q;
// struct timeval tv;//to be completed
int8_t resp;
// struct timeval tv;
bigtime_t tv;
int32_t resp;
#define FWXF_INIT 0x00
#define FWXF_INQ 0x01
#define FWXF_START 0x02
@ -294,16 +313,19 @@ struct fw_xfer{
uint8_t flag;
int8_t tl;
void (*hand) (struct fw_xfer *);
struct {
struct send_recv{
struct fw_pkt hdr;
uint32_t *payload;
area_id payArea;
bus_addr_t bus_addr;
uint16_t pay_len;
uint8_t spd;
} send, recv;
// struct mbuf *mbuf;//to be completed
// struct mbuf *mbuf;
STAILQ_ENTRY(fw_xfer) link;
STAILQ_ENTRY(fw_xfer) tlabel;
struct malloc_type *malloc;
// struct malloc_type *malloc;
sem_id Sem;
};
struct fw_rcv_buf {
@ -313,20 +335,20 @@ struct fw_rcv_buf {
u_int nvec;
uint8_t spd;
};
#ifndef __HAIKU__
//#ifndef __HAIKU__
void fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
void fw_rcv (struct fw_rcv_buf *);
void fw_xfer_unload ( struct fw_xfer*);
void fw_xfer_free_buf ( struct fw_xfer*);
void fw_xfer_free ( struct fw_xfer*);
struct fw_xfer *fw_xfer_alloc (struct malloc_type *);
struct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int);
struct fw_xfer *fw_xfer_alloc ();
struct fw_xfer *fw_xfer_alloc_buf (int, int);
void fw_init (struct firewire_comm *);
int fw_tbuf_update (struct firewire_comm *, int, int);
int fw_rbuf_update (struct firewire_comm *, int, int);
int fw_bindadd (struct firewire_comm *, struct fw_bind *);
int fw_bindremove (struct firewire_comm *, struct fw_bind *);
int fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int,
int fw_xferlist_add (struct fw_xferlist *, int, int, int,
struct firewire_comm *, void *, void (*)(struct fw_xfer *));
void fw_xferlist_remove (struct fw_xferlist *);
int fw_asyreq (struct firewire_comm *, int, struct fw_xfer*);
@ -341,11 +363,11 @@ struct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
struct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
struct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
void fw_drain_txq (struct firewire_comm *);
int fwdev_makedev (struct firewire_softc *);
int fwdev_destroydev (struct firewire_softc *);
void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
//int fwdev_makedev (struct firewire_softc *);
//int fwdev_destroydev (struct firewire_softc *);
//void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
int fw_open_isodma(struct firewire_comm *, int);
#endif
//#endif
extern int firewire_debug;
#ifndef __HAIKU__
extern devclass_t firewire_devclass;

View File

@ -36,21 +36,13 @@
#ifndef _FWDMA_H
#define _FWDMA_H
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y)) // x/y的上界
#endif
#define rounddown(x, y) (((x)/(y))*(y)) // 比x小y的最大的倍数
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ // 比x大y的最小倍数
#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
#define powerof2(x) ((((x)-1)&(x))==0) // 是否是2的次方
#include "fwglue.h"
typedef uint32_t bus_addr_t;
typedef uint32_t bus_size_t;
struct fwdma_alloc {
// bus_dma_tag_t dma_tag;
// bus_dmamap_t dma_map;
area_id BufArea;
area_id Area;
void * v_addr;
bus_addr_t bus_addr;
};
@ -67,7 +59,7 @@ struct fwdma_alloc_multi {
bus_size_t esize;
int nseg;
// bus_dma_tag_t dma_tag;
area_id BufArea;
area_id Area;
struct fwdma_seg seg[0];
};
@ -119,12 +111,16 @@ fwdma_sync_multiseg_all(struct fwdma_alloc_multi *am, bus_dmasync_op_t op)
bus_dmamap_sync(am->dma_tag, seg->dma_map, op);
}
void *fwdma_malloc(int, bus_size_t, struct fwdma_alloc *, int);
void fwdma_free(struct fwdma_alloc *);
void *fwdma_malloc(struct firewire_comm *, int, bus_size_t, struct fwdma_alloc *, int);
void fwdma_free(struct firewire_comm *, struct fwdma_alloc *);
void *fwdma_malloc_size(bus_dma_tag_t, bus_dmamap_t *, bus_size_t, bus_addr_t *, int);
void fwdma_free_size(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t);
struct fwdma_alloc_multi *fwdma_malloc_multiseg(struct firewire_comm *,
int, int, int, int);
#else
struct fwdma_alloc_multi *fwdma_malloc_multiseg(int, int, int);
void fwdma_free_multiseg(struct fwdma_alloc_multi *);
#endif /*__HAIKU__*/
#endif /* _FWDMA_H*/

View File

@ -0,0 +1,56 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* JiSheng Zhang
*/
#ifndef _FW_GLUE_H
#define _FW_GLUE_H
#include <stdint.h>
#include <dpc.h>
#define device_printf(dev, a...) dprintf("firewire:" a)
#define printf(a...) dprintf(a)
#define KASSERT(cond,msg) do { \
if (!cond) \
panic msg; \
} while(0)
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y)) // x/y的上界
#endif
#define rounddown(x, y) (((x)/(y))*(y)) // 比x小y的最大的倍数
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ // 比x大y的最小倍数
#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
#define powerof2(x) ((((x)-1)&(x))==0) // 是否是2的次方
typedef uint32_t bus_addr_t;
typedef uint32_t bus_size_t;
#define atomic_readandclear_int(a) atomic_set(a, 0)
#define atomic_set_int(addr, newvalue) atomic_set(addr, newvalue)
#define mtx_lock benaphore_lock
#define mtx_unlock benaphore_unlock
#define mtx_destroy benaphore_destroy
#define mtx_init(lockaddr, name, type, opts) benaphore_init(lockaddr, name)
#define splfw() 0
#define splx(s)
#define hz 1000000LL
#define DELAY(n) snooze(n)
#define OWRITE(sc, offset, value) (*(volatile uint32 *)((char *)(sc->regAddr) + (offset)) = value)
#define OREAD(sc, offset) (*(volatile uint32 *)((char *)(sc->regAddr) + (offset)))
#define MAX_CARDS 4
extern dpc_module_info *gDpc;
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
#endif /*_FW_GLUE_H*/

View File

@ -0,0 +1,44 @@
/* Realtek RTL8169 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies, and that both the
* copyright notice and this permission notice appear in supporting documentation.
*
* Marcus Overhagen makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __TIMER_H
#define __TIMER_H
#include <KernelExport.h>
// Since the BeOS kernel timers are executed in interrupt context,
// a new timer has been created. The timers are executed in thread
// context, and are passed a cookie.
typedef int32 timer_id;
typedef void (*timer_function)(void *cookie);
// create_timer() can be called from interrupt context.
// Only up to 8 concurrent timers are supported.
// Flags can be one of B_ONE_SHOT_ABSOLUTE_TIMER,
// B_ONE_SHOT_RELATIVE_TIMER or B_PERIODIC_TIMER.
timer_id create_timer(timer_function func, void *cookie, bigtime_t interval, uint32 flags);
status_t delete_timer(timer_id id);
status_t initialize_timer(void);
status_t terminate_timer(void);
#endif

View File

@ -0,0 +1,152 @@
$FreeBSD: src/sys/dev/firewire/00README,v 1.2 2005/10/01 18:56:16 glebius Exp $
IEEE 1394 support for FreeBSD-5.X and 4.X.
1. Introduction
This tarball contains IEEE1394(FireWire) driver which is first
written by Katsushi Kobayashi[1] <ikob@koganei.wide.ad.jp> and
modified by Hidetoshi Shimokawa <simokawa@freebsd.org>.
Please note this driver is still under development.
You can find latest snapshots under:
http://people.freebsd.org/~simokawa/
named firewire-2002XXXX.tar.gz
The driver consists of 6 parts:
- fwohci.c/fwohci_pci.c
OHCI[2] driver
- IEEE1394 link/phy chip control
- firewire.c
Chip independent driver
- CSR
- Transaction
- Character devices for userland
- fwmem.c
/dev/fwmem0: physical memory of a remote node.
- sbp.c
SBP-II[3] (a.k.a. SCSI over FireWire) driver
- if_fwe.c
NON-Standard implementation of Ethernet over FireWire.
- bus_mgm.c (userland)
Bus management function for user.
show topology map, change gap count, bus reset, etc.
2. Installation
Suppose you have kernel source at /sys.
- Extract tarball at root directory.
- cd /sys/dev/firewire
- make
- make install
- make load
For FreeBSD-4 user:
- ./MAKEDEV
3. SBP-II support (sbp)
- You need CAM(SCSI) support in your kernel.
If you are using FreeBSD-5 before 2002/03/23 or FreeBSD-4 before
2002/4/8, you need to apply CAM-patch in this archive
to handle HDD's(T_RBC or T_DIRECT which doesn't support READ_6).
- If you connect a few firewire devices only, try the following to
reduce gap overhead.
- ./bus_mgm -g 8
4. Ethernet over FireWire (if_fwe)
This is a sample driver for ethernet emulation. Please note this
does NOT conform to any standards like IP over FireWire(RFC2734[4]).
It just sends ethernet frames encapsulated in asynchronous stream
packets. It doesn't scale because it does something like unicast over multicast, but it's easy to be implemented and you can use any
facilities what ethernet can do. (ipv6, bridging, vlan etc.)
It also has DEVICE_POLLING[5] support. To enable it, edit your
kernel config file and Makefile.fwe then rebuild kernel and if_fwe.ko.
5. FireWire for Kernel Hackers
As you know, IEEE1394 is a bus and OHCI supports physical access
to the host memory. This means that you can access the remote
host over firewire without software support at the remote host.
In other words, you can investigate remote host's physical memory
whether its OS is alive or crashed or hangs up.
You need to apply KVMLIB-patch and rebuild libkvm then rebuild ps,
dmesg and gdb those are statically linked.
You may want to apply GDB-patch in this archive to get same behavior
as gdb with /dev/mem or want to insert savectx(&dumppcb) into panic(),
breakpoint() and so on to emulation crash dump.
You have to determine target node_id manually at this point.
(guess using bus_mgm -t or dmesg)
(Targets should be specified by EUI64 in the future)
# sysctl kern.firewire.fwmem_node=[node_id]
# ps -agx -M /dev/fwmem0 -N /sys/i386/compile/GENERIC/kernel
# dmesg -M /dev/fwmem0 -N /sys/i386/compile/GENERIC/kernel
# gdb -k -c /dev/fwmem0 /sys/i386/compile/GENERIC/kernel.debug
# dd if=/dev/fwmem0 of=vmcore bs=1m count=[phys. memory in MB]
remote gdb at 400,000,000 bps :-)
6. DV
I have not tested yet.
7. Tested HW
OS
- FreeBSD-4/i386
- FreeBSD-4/alpha
- FreeBSD-5/i386
* Not tested on SMP.
* Not tested on big-endian machine...
OHCI
- Texas Instruments TSB12LV26 (PCI)
- Texas Instruments TSB43AA22 (PCI/Cardbus)
* There might be phy probing problem but most of the OHCI
chips should work.
* Tested with multiple firewire buses.
SBP-II
- HDD: Logitec USB/FireWire LHD-P30FU
- HDD: Yano A-dish 120GB
- HDD: Yano B-Max 320GB
The repository of cvsup2.jp.freebsd.org is on this device.
- HDD: Personal Storage 3000XT 160GB
The last sector of this drive cannot be accessed..
- DVD-RAM: Panasonic LF-D340JD
- SCSI-FireWire converter: Yano FWSCSI-01
We can recognize only 1 device/lun at this point
- HDD: iPod, PowerBook G4 (target mode)
Reported by ikob
- Scanner: Epson GT-9700F
Now works!!
Sane-backend needs a patch(SANE-patch in this archive).
if_fwe
- IPv4, IPv6, bridging, vlan.
- You need at least two FreeBSD machines with this driver to use.
References:
[1] ftp://ftp.uec.ac.jp/pub/firewire/beta/
[2] http://developer.intel.com/technology/1394/download/ohci_11.htm
[3] http://www.t10.org/scsi-3.htm
[4] http://www.faqs.org/rfcs/rfc2734.html
[5] http://info.iet.unipi.it/~luigi/polling/
Hidetoshi Shimokawa
simokawa@freebsd.org

View File

@ -0,0 +1,22 @@
SubDir HAIKU_TOP src add-ons kernel bus_managers firewire ;
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
UsePrivateHeaders firewire kernel ;
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
KernelAddon firewire :
util.c
timer.c
firewire_module.c
firewire.c
fwdma.c
fwmem.c
fwohci.c
fwohci_pci.c
fwcrom.c
;
SEARCH on [ FGristFiles
fwcrom.c
] = [ FDirName $(HAIKU_TOP) src bin fwcontrol ] ;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
/*
* Copyright (C) 2007 JiSheng Zhang <jszhang3@gmail.com>. All rights reserved
* Distributed under the terms of the MIT license.
*
* Kernel driver for firewire
*/
#include <OS.h>
#include <KernelExport.h>
#include <SupportDefs.h>
#include <PCI.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <dpc.h>
#include "fwdebug.h"
#include "queue.h"
#include "fwglue.h"
#include "firewire.h"
#include "iec13213.h"
#include "firewirereg.h"
#include "fwdma.h"
#include "fwohcireg.h"
#include "fwohcivar.h"
#include "firewire_module.h"
status_t fwohci_pci_attach(int index);
status_t fwohci_pci_detach(int index);
pci_info *pciInfo[MAX_CARDS];
fwohci_softc_t *gFwohci_softc[MAX_CARDS];
struct firewire_softc *gFirewire_softc[MAX_CARDS];
pci_module_info *pci;
dpc_module_info *gDpc;
struct supported_device{
uint16 vendor_id;
uint32 device_id;
char *name;
};
struct supported_device supported_devices[] = {
{FW_VENDORID_NATSEMI, FW_DEVICE_CS4210, "National Semiconductor CS4210"},
{FW_VENDORID_NEC, FW_DEVICE_UPD861, "NEC uPD72861"},
{FW_VENDORID_NEC, FW_DEVICE_UPD871, "NEC uPD72871/2"},
{FW_VENDORID_NEC, FW_DEVICE_UPD72870, "NEC uPD72870"},
{FW_VENDORID_NEC, FW_DEVICE_UPD72873, "NEC uPD72873"},
{FW_VENDORID_NEC, FW_DEVICE_UPD72874, "NEC uPD72874"},
{FW_VENDORID_SIS, FW_DEVICE_7007, "SiS 7007"},
{FW_VENDORID_TI, FW_DEVICE_TITSB22, "Texas Instruments TSB12LV22"},
{FW_VENDORID_TI, FW_DEVICE_TITSB23, "Texas Instruments TSB12LV23"},
{FW_VENDORID_TI, FW_DEVICE_TITSB26, "Texas Instruments TSB12LV26"},
{FW_VENDORID_TI, FW_DEVICE_TITSB43, "Texas Instruments TSB43AA22"},
{FW_VENDORID_TI, FW_DEVICE_TITSB43A, "Texas Instruments TSB43AB22/A"},
{FW_VENDORID_TI, FW_DEVICE_TITSB43AB21, "Texas Instruments TSB43AB21/A/AI/A-EP"},
{FW_VENDORID_TI, FW_DEVICE_TITSB43AB23, "Texas Instruments TSB43AB23"},
{FW_VENDORID_TI, FW_DEVICE_TITSB82AA2, "Texas Instruments TSB82AA2"},
{FW_VENDORID_TI, FW_DEVICE_TIPCI4450, "Texas Instruments PCI4450"},
{FW_VENDORID_TI, FW_DEVICE_TIPCI4410A, "Texas Instruments PCI4410A"},
{FW_VENDORID_TI, FW_DEVICE_TIPCI4451, "Texas Instruments PCI4451"},
{FW_VENDORID_VIA, FW_DEVICE_VT6306, "VIA Fire II (VT6306)"},
{FW_VENDORID_RICOH, FW_DEVICE_R5C551, "Ricoh R5C551"},
{FW_VENDORID_RICOH, FW_DEVICE_R5C552, "Ricoh R5C552"},
{FW_VENDORID_APPLE, FW_DEVICE_PANGEA, "Apple Pangea"},
{FW_VENDORID_APPLE, FW_DEVICE_UNINORTH, "Apple UniNorth"},
{FW_VENDORID_LUCENT, FW_DEVICE_FW322, "Lucent FW322/323"},
{FW_VENDORID_INTEL, FW_DEVICE_82372FB, "Intel 82372FB"},
{FW_VENDORID_ADAPTEC, FW_DEVICE_AIC5800, "Adaptec AHA-894x/AIC-5800"},
{FW_VENDORID_SUN, FW_DEVICE_PCIO2FW, "Sun PCIO-2"},
{FW_VENDORID_SONY, FW_DEVICE_CXD3222, "Sony i.LINK (CXD3222)"},
{0, 0, NULL}
};
static int find_device_name(pci_info *info)
{
struct supported_device *device;
for (device = supported_devices; device->name; device++) {
if (info->vendor_id == device->vendor_id
&& info->device_id == device->device_id >> 16) {
dprintf("%s\n", device->name);
return 1;
}
}
return 0;
}
static status_t
fw_add_child(const char *childname,
const struct firewire_notify_hooks *hooks)
{
status_t status;
int i;
TRACE("add child %s\n", childname);
for (i = 0; gFirewire_softc[i] != NULL; i++) {
status = firewire_add_child(gFirewire_softc[i], childname, hooks);
if (status != B_OK)
return status;
}
return B_OK;
}
static status_t
fw_remove_child(const char *childname)
{
status_t status;
int i;
TRACE("remove child %s\n", childname);
for (i = 0; gFirewire_softc[i] != NULL; i++) {
status = firewire_remove_child(gFirewire_softc[i], childname);
if (status != B_OK)
return status;
}
return B_OK;
}
static int
fw_get_handle(int socket, struct firewire_softc **handle)
{
if (handle == NULL)
return B_BAD_VALUE;
if (socket >= 0 && socket < MAX_CARDS && gFirewire_softc[socket]) {
*handle = gFirewire_softc[socket];
return B_OK;
}
*handle = NULL;
return ENODEV;
}
static status_t
fw_module_init(void)
{
status_t status;
pci_info *info = NULL;
int i, found;
fwohci_softc_t *fwohci_sc;
struct firewire_softc *fw_sc;
info = malloc(sizeof(pci_info));
if (!info)
return B_NO_MEMORY;
if ((status = get_module(B_PCI_MODULE_NAME,(module_info **)&pci)) != B_OK) {
TRACE("pci module unavailable\n");
free(info);
return status;
}
if ((status = get_module(B_DPC_MODULE_NAME,(module_info **)&gDpc)) != B_OK) {
TRACE("pci module unavailable\n");
free(info);
put_module(B_PCI_MODULE_NAME);
return status;
}
memset(gFwohci_softc, 0, sizeof(gFwohci_softc));
// find devices
for (i = 0, found = 0; (status = pci->get_nth_pci_info(i, info)) == B_OK; i++) {
if (find_device_name(info)
|| ((info->class_base == PCI_serial_bus)
&& (info->class_sub == PCI_firewire)
&& (info->class_api == PCI_INTERFACE_OHCI))) {
dprintf( "vendor=%x, device=%x, revision = %x\n", info->vendor_id, info->device_id, info->revision);
pciInfo[found] = info;
fwohci_sc = malloc(sizeof(fwohci_softc_t));
if (!fwohci_sc) {
free(info);
goto err_outofmem;
}
memset(fwohci_sc, 0, sizeof(fwohci_softc_t));
gFwohci_softc[found] = fwohci_sc;
fw_sc = malloc(sizeof(struct firewire_softc));
if (!fw_sc) {
free(info);
free(fwohci_sc);
goto err_outofmem;
}
memset(fw_sc, 0, sizeof(struct firewire_softc));
gFirewire_softc[found] = fw_sc;
gFirewire_softc[found+1] = NULL;
found++;
info = malloc(sizeof(pci_info));
if (!info)
goto err_outofmem;
if (found == MAX_CARDS)
break;
}
}
TRACE("found %d cards\n", found);
free(info);
// if (!found)
// goto err_found;
if ((status = initialize_timer()) != B_OK) {
ERROR("timer init failed\n");
goto err_timer;
}
for (i = 0; i < found; i++) {
if (fwohci_pci_attach(i) != B_OK) {
ERROR("fwohci_pci_attach failed\n");
goto err_pci;
}
}
return B_OK;
err_pci:
terminate_timer();
err_timer:
err_found:
err_outofmem:
for (i = 0; i < found; i++) {
free(gFirewire_softc[i]);
free(gFwohci_softc[i]);
free(pciInfo[i]);
}
put_module(B_PCI_MODULE_NAME);
put_module(B_DPC_MODULE_NAME);
return B_ERROR;
}
static status_t
fw_module_uninit(void)
{
int i;
terminate_timer();
for (i = 0; gFirewire_softc[i] != NULL; i++) {
fwohci_pci_detach(i);
free(gFirewire_softc[i]);
free(gFwohci_softc[i]);
free(pciInfo[i]);
}
put_module(B_PCI_MODULE_NAME);
put_module(B_DPC_MODULE_NAME);
return B_OK;
}
static status_t
fw_module_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
TRACE("fw_module_init\n");
return fw_module_init();
case B_MODULE_UNINIT:
TRACE("fw_module_uninit\n");
return fw_module_uninit();
}
return B_BAD_VALUE;
}
static struct fw_module_info gModuleInfo = {
{
{
FIREWIRE_MODULE_NAME,
0,
fw_module_std_ops
},
NULL
},
fw_noderesolve_nodeid,
fw_noderesolve_eui64,
fw_asyreq,
fw_xferwake,
fw_xferwait,
fw_bindlookup,
fw_bindadd,
fw_bindremove,
fw_xferlist_add,
fw_xferlist_remove,
fw_xfer_alloc,
fw_xfer_alloc_buf,
fw_xfer_done,
fw_xfer_unload,
fw_xfer_free_buf,
fw_xfer_free,
fw_asy_callback_free,
fw_open_isodma,
fw_get_handle,
fwdma_malloc_multiseg,
fwdma_free_multiseg
};
module_info *modules[] = {
(module_info *)&gModuleInfo,
NULL
};

View File

@ -0,0 +1,85 @@
/*-
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the acknowledgement as bellow:
*
* This product includes software developed by K. Kobayashi and H. Shimokawa
*
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/firewire/firewire_phy.h,v 1.3 2005/01/06 01:42:41 imp Exp $
*
*/
#define FW_PHY_PHYSID_REG 0x00
#define FW_PHY_PHYSID (63<<2)
#define FW_PHY_ROOT_REG 0x00
#define FW_PHY_ROOT (1<<1)
#define FW_PHY_CPS_REG 0x00
#define FW_PHY_CPS (1<<0)
#define FW_PHY_RHB_REG 0x01
#define FW_PHY_RHB (1<<7)
#define FW_PHY_IBR_REG 0x01
#define FW_PHY_IBR (1<<6)
#define FW_PHY_ISBR_REG 0x05
#define FW_PHY_ISBR (1<<6)
#define FW_PHY_GC_REG 0x01
#define FW_PHY_SPD_REG 0x02
#define FW_PHY_SPD (3<<6)
#define FW_PHY_REV_REG 0x02
#define FW_PHY_REV (3<<4)
#define FW_PHY_NP_REG 0x02
#define FW_PHY_NP (15<<0)
#define FW_PHY_P1_REG 0x03
#define FW_PHY_P2_REG 0x04
#define FW_PHY_P3_REG 0x05
#define FW_PHY_P_ASTAT (3<<6)
#define FW_PHY_P_BSTAT (3<<4)
#define FW_PHY_P_CH (1<<3)
#define FW_PHY_P_CON (1<<2)
#define FW_PHY_LOOPINT_REG 0x06
#define FW_PHY_LOOPINT (1<<7)
#define FW_PHY_CPSINT_REG 0x06
#define FW_PHY_CPSNT (1<<6)
/*
#define FW_PHY_CPS_REG 0x06
#define FW_PHY_CPS (1<<5)
*/
#define FW_PHY_IR_REG 0x06
#define FW_PHY_IR (1<<4)
#define FW_PHY_C_REG 0x06
#define FW_PHY_C (1<<0)
#define FW_PHY_ESPD_REG 0x03
#define FW_PHY_ESPD (7<<5)
#define FW_PHY_EDEL_REG 0x03
#define FW_PHY_EDEL 15<<0

View File

@ -0,0 +1,21 @@
/* Kernel driver for firewire
*
* Copyright (C) 2007 JiSheng Zhang <jszhang3@gmail.com>. All rights reserved
* Distributed under the terms of the MIT license.
*/
#ifndef __FWDEBUG_H
#define __FWDEBUG_H
#include <KernelExport.h>
#define DEBUG 1
#ifdef DEBUG
#define TRACE(a...) dprintf("firewire: " a)
#else
#define TRACE(a...)
#endif
#define ERROR(a...) dprintf("firewire: ERROR " a)
#endif

View File

@ -0,0 +1,233 @@
/*-
* Copyright (c) 2003
* Hidetoshi Shimokawa. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
*
* This product includes software developed by Hidetoshi Shimokawa.
*
* 4. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <OS.h>
#include <malloc.h>
#include "queue.h"
#include "fwglue.h"
#include "firewire.h"
#include "iec13213.h"
#include "firewirereg.h"
#include "fwdma.h"
#include "util.h"
#if 0
static void
fwdma_map_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
bus_addr_t *baddr;
if (error)
printf("fwdma_map_cb: error=%d\n", error);
baddr = (bus_addr_t *)arg;
*baddr = segs->ds_addr;
}
void *
fwdma_malloc(struct firewire_comm *fc, int alignment, bus_size_t size,
struct fwdma_alloc *dma, int flag)
{
int err;
dma->v_addr = NULL;
err = bus_dma_tag_create(
/*parent*/ fc->dmat,
/*alignment*/ alignment,
/*boundary*/ 0,
/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
/*highaddr*/ BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/ size,
/*nsegments*/ 1,
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
/*flags*/ BUS_DMA_ALLOCNOW,
#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
/*lockfunc*/busdma_lock_mutex,
/*lockarg*/FW_GMTX(fc),
#endif
&dma->dma_tag);
if (err) {
printf("fwdma_malloc: failed(1)\n");
return(NULL);
}
err = bus_dmamem_alloc(dma->dma_tag, &dma->v_addr,
flag, &dma->dma_map);
if (err) {
printf("fwdma_malloc: failed(2)\n");
/* XXX destroy tag */
return(NULL);
}
bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->v_addr,
size, fwdma_map_cb, &dma->bus_addr, /*flags*/0);
return(dma->v_addr);
}
//=>alloc_mem(void **v_addr, bus_addr, uint32 protection, const char*name)
void
fwdma_free(struct firewire_comm *fc, struct fwdma_alloc *dma)
{
bus_dmamap_unload(dma->dma_tag, dma->dma_map);
bus_dmamem_free(dma->dma_tag, dma->v_addr, dma->dma_map);
bus_dma_tag_destroy(dma->dma_tag);
}
//=>delete_area(area_id area)
void *
fwdma_malloc_size(bus_dma_tag_t dmat, bus_dmamap_t *dmamap,
bus_size_t size, bus_addr_t *bus_addr, int flag)
{
void *v_addr;
if (bus_dmamem_alloc(dmat, &v_addr, flag, dmamap)) {
printf("fwdma_malloc_size: failed(1)\n");
return(NULL);
}
bus_dmamap_load(dmat, *dmamap, v_addr, size,
fwdma_map_cb, bus_addr, /*flags*/0);
return(v_addr);
}
//=>alloc_mem(void **v_addr, bus_addr, uint32 protection, const char*name)
void
fwdma_free_size(bus_dma_tag_t dmat, bus_dmamap_t dmamap,
void *vaddr, bus_size_t size)
{
bus_dmamap_unload(dmat, dmamap);
bus_dmamem_free(dmat, vaddr, dmamap);
}
//=>delete_area(area_id area)
#endif
/*
* Allocate multisegment dma buffers
* each segment size is eqaul to ssize except last segment.
*/
struct fwdma_alloc_multi *
fwdma_malloc_multiseg(int alignment,
int esize, int n)
{
struct fwdma_alloc_multi *am;
struct fwdma_seg *seg;
int ssize;
int nseg, i;
void *buf_virt, *buf_phy;
if (esize > B_PAGE_SIZE) {
/* round up to PAGE_SIZE */
esize = ssize = roundup2(esize, B_PAGE_SIZE);
nseg = n;
} else {
/* allocate PAGE_SIZE segment for small elements */
/*ssize = rounddown(PAGE_SIZE, esize);
nseg = howmany(n, ssize / esize);*/
esize = roundup2(esize, alignment);
ssize = rounddown(B_PAGE_SIZE, esize);
nseg = howmany(n, ssize / esize);
}
am = (struct fwdma_alloc_multi *)malloc(sizeof(struct fwdma_alloc_multi)
+ sizeof(struct fwdma_seg)*nseg);
if (am == NULL) {
dprintf("fwdma_malloc_multiseg: malloc failed\n");
return(NULL);
}
am->ssize = ssize;
am->esize = esize;
// am->nseg = 0;
am->nseg = nseg;
#if 0
if (bus_dma_tag_create(
/*parent*/ fc->dmat,
/*alignment*/ alignment,
/*boundary*/ 0,
/*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
/*highaddr*/ BUS_SPACE_MAXADDR,
/*filter*/NULL, /*filterarg*/NULL,
/*maxsize*/ ssize,
/*nsegments*/ 1,
/*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
/*flags*/ BUS_DMA_ALLOCNOW,
#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
/*lockfunc*/busdma_lock_mutex,
/*lockarg*/FW_GMTX(fc),
#endif
&am->dma_tag)) {
printf("fwdma_malloc_multiseg: tag_create failed\n");
free(am, M_FW);
return(NULL);
}
#endif
am->Area = alloc_mem(&buf_virt, &buf_phy, nseg*ssize, 0, "fw multi dma buf");
/* for (seg = &am->seg[0]; nseg --; seg ++) {
seg->v_addr = fwdma_malloc_size(am->dma_tag, &seg->dma_map,
ssize, &seg->bus_addr, flag);
if (seg->v_addr == NULL) {
printf("fwdma_malloc_multi: malloc_size failed %d\n",
am->nseg);
fwdma_free_multiseg(am);
return(NULL);
}
am->nseg++;
}*/
for(i = 0, seg=&am->seg[0]; i < nseg; i++){
seg->v_addr =(char *)buf_virt + (i * ssize);
seg->bus_addr = (bus_addr_t)((char *)buf_phy + (i * ssize));
seg++;
}
return(am);
}
void
fwdma_free_multiseg(struct fwdma_alloc_multi *am)
{
/* struct fwdma_seg *seg;
for (seg = &am->seg[0]; am->nseg --; seg ++) {
fwdma_free_size(am->dma_tag, seg->dma_map,
seg->v_addr, am->ssize);
}
bus_dma_tag_destroy(am->dma_tag);*/
delete_area(am->Area);
free(am);
}

View File

@ -0,0 +1,227 @@
/*-
* Copyright (c) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
*
* This product includes software developed by Hidetoshi Shimokawa.
*
* 4. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/param.h>
#include <sys/types.h>
#include <endian.h>
#include <sys/ioccom.h>
#include "queue.h"
#include "fwglue.h"
#include "firewire.h"
#include "iec13213.h"
#include "firewirereg.h"
#include "fwmem.h"
static int fwmem_debug=0;
static struct fw_xfer *
fwmem_xfer_req(
struct fw_device *fwdev,
caddr_t sc,
int spd,
int slen,
int rlen,
void *hand)
{
struct fw_xfer *xfer;
xfer = fw_xfer_alloc();
if (xfer == NULL)
return NULL;
xfer->fc = fwdev->fc;
xfer->send.hdr.mode.hdr.dst = FWLOCALBUS | fwdev->dst;
if (spd < 0)
xfer->send.spd = fwdev->speed;
else
xfer->send.spd = min(spd, fwdev->speed);
xfer->hand = hand;
xfer->sc = sc;
xfer->send.pay_len = slen;
xfer->recv.pay_len = rlen;
return xfer;
}
struct fw_xfer *
fwmem_read_quad(
struct fw_device *fwdev,
caddr_t sc,
uint8_t spd,
uint16_t dst_hi,
uint32_t dst_lo,
void *data,
void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
xfer = fwmem_xfer_req(fwdev, (void *)sc, spd, 0, 4, hand);
if (xfer == NULL) {
return NULL;
}
fp = &xfer->send.hdr;
fp->mode.rreqq.tcode = FWTCODE_RREQQ;
fp->mode.rreqq.dest_hi = dst_hi;
fp->mode.rreqq.dest_lo = dst_lo;
xfer->send.payload = NULL;
xfer->recv.payload = (uint32_t *)data;
if (fwmem_debug)
printf("fwmem_read_quad: %d %04x:%08x\n", fwdev->dst,
dst_hi, dst_lo);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
fw_xfer_free(xfer);
return NULL;
}
struct fw_xfer *
fwmem_write_quad(
struct fw_device *fwdev,
caddr_t sc,
uint8_t spd,
uint16_t dst_hi,
uint32_t dst_lo,
void *data,
void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
xfer = fwmem_xfer_req(fwdev, sc, spd, 0, 0, hand);
if (xfer == NULL)
return NULL;
fp = &xfer->send.hdr;
fp->mode.wreqq.tcode = FWTCODE_WREQQ;
fp->mode.wreqq.dest_hi = dst_hi;
fp->mode.wreqq.dest_lo = dst_lo;
fp->mode.wreqq.data = *(uint32_t *)data;
xfer->send.payload = xfer->recv.payload = NULL;
if (fwmem_debug)
printf("fwmem_write_quad: %d %04x:%08x %08x\n", fwdev->dst,
dst_hi, dst_lo, *(uint32_t *)data);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
fw_xfer_free(xfer);
return NULL;
}
struct fw_xfer *
fwmem_read_block(
struct fw_device *fwdev,
caddr_t sc,
uint8_t spd,
uint16_t dst_hi,
uint32_t dst_lo,
int len,
void *data,
void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
xfer = fwmem_xfer_req(fwdev, sc, spd, 0, roundup2(len, 4), hand);
if (xfer == NULL)
return NULL;
fp = &xfer->send.hdr;
fp->mode.rreqb.tcode = FWTCODE_RREQB;
fp->mode.rreqb.dest_hi = dst_hi;
fp->mode.rreqb.dest_lo = dst_lo;
fp->mode.rreqb.len = len;
fp->mode.rreqb.extcode = 0;
xfer->send.payload = NULL;
xfer->recv.payload = data;
if (fwmem_debug)
printf("fwmem_read_block: %d %04x:%08x %d\n", fwdev->dst,
dst_hi, dst_lo, len);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
fw_xfer_free(xfer);
return NULL;
}
struct fw_xfer *
fwmem_write_block(
struct fw_device *fwdev,
caddr_t sc,
uint8_t spd,
uint16_t dst_hi,
uint32_t dst_lo,
int len,
void *data,
void (*hand)(struct fw_xfer *))
{
struct fw_xfer *xfer;
struct fw_pkt *fp;
xfer = fwmem_xfer_req(fwdev, sc, spd, len, 0, hand);
if (xfer == NULL)
return NULL;
fp = &xfer->send.hdr;
fp->mode.wreqb.tcode = FWTCODE_WREQB;
fp->mode.wreqb.dest_hi = dst_hi;
fp->mode.wreqb.dest_lo = dst_lo;
fp->mode.wreqb.len = len;
fp->mode.wreqb.extcode = 0;
xfer->send.payload = data;
xfer->recv.payload = NULL;
if (fwmem_debug)
printf("fwmem_write_block: %d %04x:%08x %d\n", fwdev->dst,
dst_hi, dst_lo, len);
if (fw_asyreq(xfer->fc, -1, xfer) == 0)
return xfer;
fw_xfer_free(xfer);
return NULL;
}

View File

@ -0,0 +1,55 @@
/*-
* Copyright (C) 2002-2003
* Hidetoshi Shimokawa. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
*
* This product includes software developed by Hidetoshi Shimokawa.
*
* 4. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/firewire/fwmem.h,v 1.8 2005/01/06 01:42:41 imp Exp $
*/
struct fw_xfer *fwmem_read_quad(struct fw_device *, caddr_t, uint8_t,
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
struct fw_xfer *fwmem_write_quad(struct fw_device *, caddr_t, uint8_t,
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
struct fw_xfer *fwmem_read_block(struct fw_device *, caddr_t, uint8_t,
uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
struct fw_xfer *fwmem_write_block(struct fw_device *, caddr_t, uint8_t,
uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
#ifndef __HAIKU__
d_open_t fwmem_open;
d_close_t fwmem_close;
d_ioctl_t fwmem_ioctl;
d_read_t fwmem_read;
d_write_t fwmem_write;
d_poll_t fwmem_poll;
d_mmap_t fwmem_mmap;
d_strategy_t fwmem_strategy;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,223 @@
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the acknowledgement as bellow:
*
* This product includes software developed by K. Kobayashi and H. SHimokawa
*
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/firewire/fwohci_pci.c,v 1.60 2007/06/06 14:31:36 simokawa Exp $
*/
#include <OS.h>
#include <KernelExport.h>
#include <lock.h>
#include <SupportDefs.h>
#include <PCI.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "util.h"
#include "fwdebug.h"
#include "fwglue.h"
#include "queue.h"
#include "firewire.h"
#include "iec13213.h"
#include "firewirereg.h"
#include "fwdma.h"
#include "fwohcireg.h"
#include "fwohcivar.h"
#define PCIM_CMD_MEMEN 0x0002
#define PCIM_CMD_BUSMASTEREN 0x0004
#define PCIM_CMD_MWRICEN 0x0010
#define PCIM_CMD_IOS 0x0001
extern pci_module_info *pci;
extern pci_info *pciInfo[MAX_CARDS];
extern fwohci_softc_t *gFwohci_softc[MAX_CARDS];
extern struct firewire_softc *gFirewire_softc[MAX_CARDS];
status_t
fwohci_pci_detach(int index)
{
fwohci_softc_t *sc = gFwohci_softc[index];
int s;
s = splfw();
fwohci_stop(sc);
// bus_generic_detach(self);
firewire_detach(gFirewire_softc[index]);
/* if (sc->fc.bdev) {
device_delete_child(self, sc->fc.bdev);
sc->fc.bdev = NULL;
}*/
/* disable interrupts that might have been switched on */
OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_EN);
remove_io_interrupt_handler (sc->irq, fwohci_intr, sc);
delete_area(sc->regArea);
fwohci_detach(sc);
mtx_destroy(FW_GMTX(&sc->fc));
splx(s);
return B_OK;
}
static void
fwohci_pci_add_child(int index)
{
struct fwohci_softc *sc;
int err = 0;
sc = gFwohci_softc[index];
/* child = device_add_child(dev, name, unit);
if (child == NULL)
return (child);
sc->fc.bdev = child;
device_set_ivars(child, (void *)&sc->fc);*/
// err = device_probe_and_attach(child);
err = firewire_attach(&sc->fc, gFirewire_softc[index]);
if (err) {
device_printf(dev, "firewire_attach failed with err=%d\n",
err);
fwohci_pci_detach(index);
// device_delete_child(dev, child);
return;
}
/* XXX
* Clear the bus reset event flag to start transactions even when
* interrupt is disabled during the boot process.
*/
// if (cold) {
// int s;
// DELAY(250); /* 2 cycles */
// s = splfw();
// fwohci_poll((void *)sc, 0, -1);
// splx(s);
// }
}
status_t
fwohci_pci_attach(int index)
{
fwohci_softc_t *sc = gFwohci_softc[index];
pci_info *info = pciInfo[index];
uint32 olatency, latency, ocache_line, cache_line;
uint32 val;
mtx_init(FW_GMTX(&sc->fc), "firewire", NULL, MTX_DEF);
val = pci->read_pci_config(info->bus, info->device, info->function,
PCI_command, 2);
val |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
#if 1 /* for broken hardware */
val &= ~PCIM_CMD_MWRICEN;
#endif
pci->write_pci_config(info->bus, info->device, info->function,
PCI_command, 2, val);
/*
* Some Sun PCIO-2 FireWire controllers have their intpin register
* bogusly set to 0, although it should be 3. Correct that.
*/
if (info->vendor_id == FW_VENDORID_SUN && info->device_id == (FW_DEVICE_PCIO2FW >> 16) &&
info->u.h0.interrupt_pin == 0)
info->u.h0.interrupt_pin = 3;
latency = olatency = pci->read_pci_config(info->bus, info->device, info->function,
PCI_latency, 1);
#define DEF_LATENCY 0x20
if (olatency < DEF_LATENCY) {
latency = DEF_LATENCY;
pci->write_pci_config(info->bus, info->device, info->function,
PCI_latency, 1, latency);
}
cache_line = ocache_line = pci->read_pci_config(info->bus, info->device,
info->function, PCI_line_size, 1);
#define DEF_CACHE_LINE 8
if (ocache_line < DEF_CACHE_LINE) {
cache_line = DEF_CACHE_LINE;
pci->write_pci_config(info->bus, info->device, info->function,
PCI_line_size, 1, cache_line);
}
TRACE("latency timer %x -> %x.\n", olatency, latency);
TRACE("cache size %x -> %x.\n", ocache_line, cache_line);
// get IRQ
sc->irq = pci->read_pci_config(info->bus, info->device, info->function,
PCI_interrupt_line, 1);
if (sc->irq == 0 || sc->irq == 0xff) {
ERROR("no IRQ assigned\n");
goto err;
}
TRACE("IRQ %d\n", sc->irq);
// map registers into memory
// val = pci->read_pci_config(info->bus, info->device, info->function, 0x14, 4);
// val &= PCI_address_memory_32_mask;
// TRACE("hardware register address %p\n", (void *) val);
TRACE("hardware register address %x\n", info->u.h0.base_registers[0]);
sc->regArea = map_mem(&sc->regAddr, info->u.h0.base_registers[0], 0x800,
B_READ_AREA | B_WRITE_AREA, "fw ohci register");
if (sc->regArea < B_OK) {
ERROR("can't map hardware registers\n");
goto err;
}
TRACE("mapped registers to %p\n", sc->regAddr);
// setup interrupt handler
if (install_io_interrupt_handler(sc->irq, fwohci_intr, sc, 0) < B_OK) {
ERROR("can't install interrupt handler\n");
goto err;
}
if (fwohci_init(sc) < B_OK){
ERROR("fwohci_init failed");
goto err;
}
fwohci_pci_add_child(index);
return B_OK;
err:
delete_area(sc->regArea);
mtx_destroy(FW_GMTX(&sc->fc));
return B_ERROR;
}

View File

@ -0,0 +1,452 @@
/*-
* Copyright (c) 2003 Hidetoshi Shimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the acknowledgement as bellow:
*
* This product includes software developed by K. Kobayashi and H. Shimokawa
*
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/firewire/fwohcireg.h,v 1.23 2007/04/30 14:06:30 simokawa Exp $
*
*/
#define PCI_CBMEM PCIR_BAR(0)
#define FW_VENDORID_NATSEMI 0x100B
#define FW_VENDORID_NEC 0x1033
#define FW_VENDORID_SIS 0x1039
#define FW_VENDORID_TI 0x104c
#define FW_VENDORID_SONY 0x104d
#define FW_VENDORID_VIA 0x1106
#define FW_VENDORID_RICOH 0x1180
#define FW_VENDORID_APPLE 0x106b
#define FW_VENDORID_LUCENT 0x11c1
#define FW_VENDORID_INTEL 0x8086
#define FW_VENDORID_ADAPTEC 0x9004
#define FW_VENDORID_SUN 0x108e
#define FW_DEVICE_CS4210 (0x000f << 16)
#define FW_DEVICE_UPD861 (0x0063 << 16)
#define FW_DEVICE_UPD871 (0x00ce << 16)
#define FW_DEVICE_UPD72870 (0x00cd << 16)
#define FW_DEVICE_UPD72873 (0x00e7 << 16)
#define FW_DEVICE_UPD72874 (0x00f2 << 16)
#define FW_DEVICE_TITSB22 (0x8009 << 16)
#define FW_DEVICE_TITSB23 (0x8019 << 16)
#define FW_DEVICE_TITSB26 (0x8020 << 16)
#define FW_DEVICE_TITSB43 (0x8021 << 16)
#define FW_DEVICE_TITSB43A (0x8023 << 16)
#define FW_DEVICE_TITSB43AB23 (0x8024 << 16)
#define FW_DEVICE_TITSB82AA2 (0x8025 << 16)
#define FW_DEVICE_TITSB43AB21 (0x8026 << 16)
#define FW_DEVICE_TIPCI4410A (0x8017 << 16)
#define FW_DEVICE_TIPCI4450 (0x8011 << 16)
#define FW_DEVICE_TIPCI4451 (0x8027 << 16)
#define FW_DEVICE_CXD1947 (0x8009 << 16)
#define FW_DEVICE_CXD3222 (0x8039 << 16)
#define FW_DEVICE_VT6306 (0x3044 << 16)
#define FW_DEVICE_R5C551 (0x0551 << 16)
#define FW_DEVICE_R5C552 (0x0552 << 16)
#define FW_DEVICE_PANGEA (0x0030 << 16)
#define FW_DEVICE_UNINORTH (0x0031 << 16)
#define FW_DEVICE_AIC5800 (0x5800 << 16)
#define FW_DEVICE_FW322 (0x5811 << 16)
#define FW_DEVICE_7007 (0x7007 << 16)
#define FW_DEVICE_82372FB (0x7605 << 16)
#define FW_DEVICE_PCIO2FW (0x1102 << 16)
#define PCI_INTERFACE_OHCI 0x10
#define FW_OHCI_BASE_REG 0x10
#define OHCI_DMA_ITCH 0x20
#define OHCI_DMA_IRCH 0x20
#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH)
typedef uint32_t fwohcireg_t;
/* for PCI */
#if BYTE_ORDER == BIG_ENDIAN
#ifdef __HAIKU__
#define htole32(x) __swap_int32(x)
#endif
#define FWOHCI_DMA_WRITE(x, y) ((x) = htole32(y))
#define FWOHCI_DMA_READ(x) le32toh(x)
#define FWOHCI_DMA_SET(x, y) ((x) |= htole32(y))
#define FWOHCI_DMA_CLEAR(x, y) ((x) &= htole32(~(y)))
#else
#define FWOHCI_DMA_WRITE(x, y) ((x) = (y))
#define FWOHCI_DMA_READ(x) (x)
#define FWOHCI_DMA_SET(x, y) ((x) |= (y))
#define FWOHCI_DMA_CLEAR(x, y) ((x) &= ~(y))
#endif
struct fwohcidb {
union {
struct {
uint32_t cmd;
uint32_t addr;
uint32_t depend;
uint32_t res;
} desc;
uint32_t immed[4];
} db;
#define OHCI_STATUS_SHIFT 16
#define OHCI_COUNT_MASK 0xffff
#define OHCI_OUTPUT_MORE (0 << 28)
#define OHCI_OUTPUT_LAST (1 << 28)
#define OHCI_INPUT_MORE (2 << 28)
#define OHCI_INPUT_LAST (3 << 28)
#define OHCI_STORE_QUAD (4 << 28)
#define OHCI_LOAD_QUAD (5 << 28)
#define OHCI_NOP (6 << 28)
#define OHCI_STOP (7 << 28)
#define OHCI_STORE (8 << 28)
#define OHCI_CMD_MASK (0xf << 28)
#define OHCI_UPDATE (1 << 27)
#define OHCI_KEY_ST0 (0 << 24)
#define OHCI_KEY_ST1 (1 << 24)
#define OHCI_KEY_ST2 (2 << 24)
#define OHCI_KEY_ST3 (3 << 24)
#define OHCI_KEY_REGS (5 << 24)
#define OHCI_KEY_SYS (6 << 24)
#define OHCI_KEY_DEVICE (7 << 24)
#define OHCI_KEY_MASK (7 << 24)
#define OHCI_INTERRUPT_NEVER (0 << 20)
#define OHCI_INTERRUPT_TRUE (1 << 20)
#define OHCI_INTERRUPT_FALSE (2 << 20)
#define OHCI_INTERRUPT_ALWAYS (3 << 20)
#define OHCI_BRANCH_NEVER (0 << 18)
#define OHCI_BRANCH_TRUE (1 << 18)
#define OHCI_BRANCH_FALSE (2 << 18)
#define OHCI_BRANCH_ALWAYS (3 << 18)
#define OHCI_BRANCH_MASK (3 << 18)
#define OHCI_WAIT_NEVER (0 << 16)
#define OHCI_WAIT_TRUE (1 << 16)
#define OHCI_WAIT_FALSE (2 << 16)
#define OHCI_WAIT_ALWAYS (3 << 16)
};
#define OHCI_SPD_S100 0x4
#define OHCI_SPD_S200 0x1
#define OHCI_SPD_S400 0x2
#define FWOHCIEV_NOSTAT 0
#define FWOHCIEV_LONGP 2
#define FWOHCIEV_MISSACK 3
#define FWOHCIEV_UNDRRUN 4
#define FWOHCIEV_OVRRUN 5
#define FWOHCIEV_DESCERR 6
#define FWOHCIEV_DTRDERR 7
#define FWOHCIEV_DTWRERR 8
#define FWOHCIEV_BUSRST 9
#define FWOHCIEV_TIMEOUT 0xa
#define FWOHCIEV_TCODERR 0xb
#define FWOHCIEV_UNKNOWN 0xe
#define FWOHCIEV_FLUSHED 0xf
#define FWOHCIEV_ACKCOMPL 0x11
#define FWOHCIEV_ACKPEND 0x12
#define FWOHCIEV_ACKBSX 0x14
#define FWOHCIEV_ACKBSA 0x15
#define FWOHCIEV_ACKBSB 0x16
#define FWOHCIEV_ACKTARD 0x1b
#define FWOHCIEV_ACKDERR 0x1d
#define FWOHCIEV_ACKTERR 0x1e
#define FWOHCIEV_MASK 0x1f
struct ohci_dma{
fwohcireg_t cntl;
#define OHCI_CNTL_CYCMATCH_S (0x1 << 31)
#define OHCI_CNTL_BUFFIL (0x1 << 31)
#define OHCI_CNTL_ISOHDR (0x1 << 30)
#define OHCI_CNTL_CYCMATCH_R (0x1 << 29)
#define OHCI_CNTL_MULTICH (0x1 << 28)
#define OHCI_CNTL_DMA_RUN (0x1 << 15)
#define OHCI_CNTL_DMA_WAKE (0x1 << 12)
#define OHCI_CNTL_DMA_DEAD (0x1 << 11)
#define OHCI_CNTL_DMA_ACTIVE (0x1 << 10)
#define OHCI_CNTL_DMA_BT (0x1 << 8)
#define OHCI_CNTL_DMA_BAD (0x1 << 7)
#define OHCI_CNTL_DMA_STAT (0xff)
fwohcireg_t cntl_clr;
fwohcireg_t dummy0;
fwohcireg_t cmd;
fwohcireg_t match;
fwohcireg_t dummy1;
fwohcireg_t dummy2;
fwohcireg_t dummy3;
};
struct ohci_itdma{
fwohcireg_t cntl;
fwohcireg_t cntl_clr;
fwohcireg_t dummy0;
fwohcireg_t cmd;
};
struct ohci_registers {
fwohcireg_t ver; /* Version No. 0x0 */
fwohcireg_t guid; /* GUID_ROM No. 0x4 */
fwohcireg_t retry; /* AT retries 0x8 */
#define FWOHCI_RETRY 0x8
fwohcireg_t csr_data; /* CSR data 0xc */
fwohcireg_t csr_cmp; /* CSR compare 0x10 */
fwohcireg_t csr_cntl; /* CSR compare 0x14 */
fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */
fwohcireg_t bus_id; /* BUS_ID 0x1c */
fwohcireg_t bus_opt; /* BUS option 0x20 */
#define FWOHCIGUID_H 0x24
#define FWOHCIGUID_L 0x28
fwohcireg_t guid_hi; /* GUID hi 0x24 */
fwohcireg_t guid_lo; /* GUID lo 0x28 */
fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */
fwohcireg_t config_rom; /* config ROM map 0x34 */
fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */
fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */
fwohcireg_t vender; /* vender ID 0x40 */
fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */
fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */
fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */
#define OHCI_HCC_BIBIV (1 << 31) /* BIBimage Valid */
#define OHCI_HCC_BIGEND (1 << 30) /* noByteSwapData */
#define OHCI_HCC_PRPHY (1 << 23) /* programPhyEnable */
#define OHCI_HCC_PHYEN (1 << 22) /* aPhyEnhanceEnable */
#define OHCI_HCC_LPS (1 << 19) /* LPS */
#define OHCI_HCC_POSTWR (1 << 18) /* postedWriteEnable */
#define OHCI_HCC_LINKEN (1 << 17) /* linkEnable */
#define OHCI_HCC_RESET (1 << 16) /* softReset */
fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */
fwohcireg_t dummy3[1]; /* dummy 0x60 */
fwohcireg_t sid_buf; /* self id buffer 0x64 */
fwohcireg_t sid_cnt; /* self id count 0x68 */
fwohcireg_t dummy4[1]; /* dummy 0x6c */
fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */
fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */
fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */
fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */
#define FWOHCI_INTSTAT 0x80
#define FWOHCI_INTSTATCLR 0x84
#define FWOHCI_INTMASK 0x88
#define FWOHCI_INTMASKCLR 0x8c
fwohcireg_t int_stat; /* 0x80 */
fwohcireg_t int_clear; /* 0x84 */
fwohcireg_t int_mask; /* 0x88 */
fwohcireg_t int_mask_clear; /* 0x8c */
fwohcireg_t it_int_stat; /* 0x90 */
fwohcireg_t it_int_clear; /* 0x94 */
fwohcireg_t it_int_mask; /* 0x98 */
fwohcireg_t it_mask_clear; /* 0x9c */
fwohcireg_t ir_int_stat; /* 0xa0 */
fwohcireg_t ir_int_clear; /* 0xa4 */
fwohcireg_t ir_int_mask; /* 0xa8 */
fwohcireg_t ir_mask_clear; /* 0xac */
fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */
fwohcireg_t fairness; /* fairness control 0xdc */
fwohcireg_t link_cntl; /* Chip control 0xe0*/
fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/
#define FWOHCI_NODEID 0xe8
fwohcireg_t node; /* Node ID 0xe8 */
#define OHCI_NODE_VALID (1 << 31)
#define OHCI_NODE_ROOT (1 << 30)
#define OHCI_ASYSRCBUS 1
fwohcireg_t phy_access; /* PHY cntl 0xec */
#define PHYDEV_RDDONE (1<<31)
#define PHYDEV_RDCMD (1<<15)
#define PHYDEV_WRCMD (1<<14)
#define PHYDEV_REGADDR 8
#define PHYDEV_WRDATA 0
#define PHYDEV_RDADDR 24
#define PHYDEV_RDDATA 16
fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */
fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */
fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */
fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */
fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */
fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */
fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */
fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */
fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */
fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */
fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */
fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */
/* 0x180, 0x184, 0x188, 0x18c */
/* 0x190, 0x194, 0x198, 0x19c */
/* 0x1a0, 0x1a4, 0x1a8, 0x1ac */
/* 0x1b0, 0x1b4, 0x1b8, 0x1bc */
/* 0x1c0, 0x1c4, 0x1c8, 0x1cc */
/* 0x1d0, 0x1d4, 0x1d8, 0x1dc */
/* 0x1e0, 0x1e4, 0x1e8, 0x1ec */
/* 0x1f0, 0x1f4, 0x1f8, 0x1fc */
struct ohci_dma dma_ch[0x4];
/* 0x200, 0x204, 0x208, 0x20c */
/* 0x210, 0x204, 0x208, 0x20c */
struct ohci_itdma dma_itch[0x20];
/* 0x400, 0x404, 0x408, 0x40c */
/* 0x410, 0x404, 0x408, 0x40c */
struct ohci_dma dma_irch[0x20];
};
struct fwohcidb_tr{
STAILQ_ENTRY(fwohcidb_tr) link;
struct fw_xfer *xfer;
struct fwohcidb *db;
// bus_dmamap_t dma_map;
caddr_t buf;
bus_addr_t bus_addr;
int dbcnt;
area_id Area;
};
/*
* OHCI info structure.
*/
struct fwohci_txpkthdr{
union{
uint32_t ld[4];
struct {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t spd:16, /* XXX include reserved field */
:8,
tcode:4,
:4;
#else
uint32_t :4,
tcode:4,
:8,
spd:16; /* XXX include reserved fields */
#endif
}common;
struct {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t :8,
srcbus:1,
:4,
spd:3,
tlrt:8,
tcode:4,
:4;
#else
uint32_t :4,
tcode:4,
tlrt:8,
spd:3,
:4,
srcbus:1,
:8;
#endif
BIT16x2(dst, );
}asycomm;
struct {
#if BYTE_ORDER == BIG_ENDIAN
uint32_t :13,
spd:3,
chtag:8,
tcode:4,
sy:4;
#else
uint32_t sy:4,
tcode:4,
chtag:8,
spd:3,
:13;
#endif
BIT16x2(len, );
}stream;
}mode;
};
struct fwohci_trailer{
#if BYTE_ORDER == BIG_ENDIAN
uint32_t stat:16,
time:16;
#else
uint32_t time:16,
stat:16;
#endif
};
#define OHCI_CNTL_CYCSRC (0x1 << 22)
#define OHCI_CNTL_CYCMTR (0x1 << 21)
#define OHCI_CNTL_CYCTIMER (0x1 << 20)
#define OHCI_CNTL_PHYPKT (0x1 << 10)
#define OHCI_CNTL_SID (0x1 << 9)
#define OHCI_INT_DMA_ATRQ (0x1 << 0)
#define OHCI_INT_DMA_ATRS (0x1 << 1)
#define OHCI_INT_DMA_ARRQ (0x1 << 2)
#define OHCI_INT_DMA_ARRS (0x1 << 3)
#define OHCI_INT_DMA_PRRQ (0x1 << 4)
#define OHCI_INT_DMA_PRRS (0x1 << 5)
#define OHCI_INT_DMA_IT (0x1 << 6)
#define OHCI_INT_DMA_IR (0x1 << 7)
#define OHCI_INT_PW_ERR (0x1 << 8)
#define OHCI_INT_LR_ERR (0x1 << 9)
#define OHCI_INT_PHY_SID (0x1 << 16)
#define OHCI_INT_PHY_BUS_R (0x1 << 17)
#define OHCI_INT_REG_FAIL (0x1 << 18)
#define OHCI_INT_PHY_INT (0x1 << 19)
#define OHCI_INT_CYC_START (0x1 << 20)
#define OHCI_INT_CYC_64SECOND (0x1 << 21)
#define OHCI_INT_CYC_LOST (0x1 << 22)
#define OHCI_INT_CYC_ERR (0x1 << 23)
#define OHCI_INT_ERR (0x1 << 24)
#define OHCI_INT_CYC_LONG (0x1 << 25)
#define OHCI_INT_PHY_REG (0x1 << 26)
#define OHCI_INT_EN (0x1 << 31)
#define IP_CHANNELS 0x0234
#define FWOHCI_MAXREC 2048
#define OHCI_ISORA 0x02
#define OHCI_ISORB 0x04
#define FWOHCITCODE_PHY 0xe

View File

@ -0,0 +1,93 @@
/*-
* Copyright (c) 2003 Hidetoshi SHimokawa
* Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi SHimokawa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the acknowledgement as bellow:
*
* This product includes software developed by K. Kobayashi and H. Shimokawa
*
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/firewire/fwohcivar.h,v 1.16 2007/06/06 14:31:36 simokawa Exp $
*
*/
typedef struct fwohci_softc {
struct firewire_comm fc;
uint8 irq;
void *regAddr;
area_id regArea;
struct fwohci_dbch{
u_int ndb;
u_int ndesc;
STAILQ_HEAD(, fwohcidb_tr) db_trq;
struct fwohcidb_tr *top, *bottom, *pdb_tr;
struct fw_xferq xferq;
int flags;
#define FWOHCI_DBCH_INIT (1<<0)
#define FWOHCI_DBCH_FULL (1<<1)
/* used only in receive context */
int buf_offset; /* signed */
#define FWOHCI_DBCH_MAX_PAGES 32
/* Context programs buffer */
struct fwdma_alloc_multi *am;
#ifndef __HAIKU__
bus_dma_tag_t dmat;
#endif
} arrq, arrs, atrq, atrs, it[OHCI_DMA_ITCH], ir[OHCI_DMA_IRCH];
u_int maxrec;
uint32_t *sid_buf;
struct fwdma_alloc sid_dma;
struct fwdma_alloc crom_dma;
struct fwdma_alloc dummy_dma;
uint32_t intmask, irstat, itstat;
uint32_t intstat;
#ifndef __HAIKU__
struct task fwohci_task_busreset;
struct task fwohci_task_sid;
struct task fwohci_task_dma;
#endif
int cycle_lost;
} fwohci_softc_t;
#ifdef __HAIKU__
int32 fwohci_intr (void *arg);
int fwohci_init (struct fwohci_softc *);
void fwohci_poll (struct firewire_comm *, int, int);
void fwohci_reset (struct fwohci_softc *);
int fwohci_detach (struct fwohci_softc *);
int fwohci_stop (struct fwohci_softc *);
#else
void fwohci_intr (void *arg);
int fwohci_filt (void *arg);
int fwohci_init (struct fwohci_softc *, device_t);
void fwohci_poll (struct firewire_comm *, int, int);
void fwohci_reset (struct fwohci_softc *, device_t);
int fwohci_detach (struct fwohci_softc *, device_t);
int fwohci_resume (struct fwohci_softc *, device_t);
int fwohci_stop (struct fwohci_softc *, device_t dev);
#endif

View File

@ -0,0 +1,216 @@
/* Realtek RTL8169 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies, and that both the
* copyright notice and this permission notice appear in supporting documentation.
*
* Marcus Overhagen makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <Errors.h>
#include <OS.h>
#include <string.h>
#include "debug.h"
#include "fwdebug.h"
#include "timer.h"
#define MAX_TIMERS 8
struct timer_info
{
timer_id id;
timer_function func;
void * cookie;
bigtime_t next_event;
bigtime_t interval;
bool periodic;
};
static struct timer_info sTimerData[MAX_TIMERS];
static int sTimerCount;
static timer_id sTimerNextId;
static thread_id sTimerThread;
static sem_id sTimerSem;
static spinlock sTimerSpinlock;
static int32
timer_thread(void *cookie)
{
status_t status = 0;
do {
bigtime_t timeout;
bigtime_t now;
cpu_status cpu;
timer_function func;
void * cookie;
int i;
int index;
cpu = disable_interrupts();
acquire_spinlock(&sTimerSpinlock);
now = system_time();
cookie = 0;
func = 0;
// find timer with smallest event time
index = -1;
timeout = B_INFINITE_TIMEOUT;
for (i = 0; i < sTimerCount; i++) {
if (sTimerData[i].next_event < timeout) {
timeout = sTimerData[i].next_event;
index = i;
}
}
if (timeout < now) {
// timer is ready for execution, load func and cookie
ASSERT(index >= 0 && index < sTimerCount);
func = sTimerData[index].func;
cookie = sTimerData[index].cookie;
if (sTimerData[index].periodic) {
// periodic timer is ready, update the entry
sTimerData[index].next_event += sTimerData[index].interval;
} else {
// single shot timer is ready, delete the entry
if (index != (sTimerCount - 1) && sTimerCount != 1) {
memcpy(&sTimerData[index], &sTimerData[sTimerCount - 1], sizeof(struct timer_info));
}
sTimerCount--;
}
}
release_spinlock(&sTimerSpinlock);
restore_interrupts(cpu);
// execute timer hook
if (timeout < now) {
ASSERT(func);
func(cookie);
continue;
}
status = acquire_sem_etc(sTimerSem, 1, B_ABSOLUTE_TIMEOUT, timeout);
} while (status != B_BAD_SEM_ID);
return 0;
}
timer_id
create_timer(timer_function func, void *cookie, bigtime_t interval, uint32 flags)
{
cpu_status cpu;
timer_id id;
if (func == 0)
return -1;
// Attention: flags are not real flags, as B_PERIODIC_TIMER is 3
cpu = disable_interrupts();
acquire_spinlock(&sTimerSpinlock);
if (sTimerCount < MAX_TIMERS) {
id = sTimerNextId;
sTimerData[sTimerCount].id = id;
sTimerData[sTimerCount].func = func;
sTimerData[sTimerCount].cookie = cookie;
sTimerData[sTimerCount].next_event = (flags == B_ONE_SHOT_ABSOLUTE_TIMER) ? interval : system_time() + interval;
sTimerData[sTimerCount].interval = interval;
sTimerData[sTimerCount].periodic = flags == B_PERIODIC_TIMER;
sTimerNextId++;
sTimerCount++;
} else {
id = -1;
}
release_spinlock(&sTimerSpinlock);
restore_interrupts(cpu);
if (id != -1)
release_sem_etc(sTimerSem, 1, B_DO_NOT_RESCHEDULE);
return id;
}
status_t
delete_timer(timer_id id)
{
cpu_status cpu;
bool deleted;
int i;
deleted = false;
cpu = disable_interrupts();
acquire_spinlock(&sTimerSpinlock);
for (i = 0; i < sTimerCount; i++) {
if (sTimerData[i].id == id) {
if (i != (sTimerCount - 1) && sTimerCount != 1) {
memcpy(&sTimerData[i], &sTimerData[sTimerCount - 1], sizeof(struct timer_info));
}
sTimerCount--;
deleted = true;
break;
}
}
release_spinlock(&sTimerSpinlock);
restore_interrupts(cpu);
if (!deleted)
return B_ERROR;
release_sem_etc(sTimerSem, 1, B_DO_NOT_RESCHEDULE);
return B_OK;
}
status_t
initialize_timer(void)
{
sTimerCount = 0;
sTimerNextId = 1;
sTimerSpinlock = 0;
sTimerThread = spawn_kernel_thread(timer_thread, "firewire timer", 80, 0);
sTimerSem = create_sem(0, "firewire timer");
set_sem_owner(sTimerSem, B_SYSTEM_TEAM);
if (sTimerSem < 0 || sTimerThread < 0) {
delete_sem(sTimerSem);
kill_thread(sTimerThread);
return B_ERROR;
}
resume_thread(sTimerThread);
return B_OK;
}
status_t
terminate_timer(void)
{
status_t thread_return_value;
delete_sem(sTimerSem);
return wait_for_thread(sTimerThread, &thread_return_value);
}

View File

@ -0,0 +1,90 @@
/* Realtek RTL8169 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies, and that both the
* copyright notice and this permission notice appear in supporting documentation.
*
* Marcus Overhagen makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <Errors.h>
#include <OS.h>
#include <string.h>
//#define DEBUG
#include "fwdebug.h"
#include "util.h"
static inline uint32
round_to_pagesize(uint32 size)
{
return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
}
area_id
alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name)
{
physical_entry pe;
void * virtadr;
area_id areaid;
status_t rv;
TRACE("allocating %ld bytes for %s\n", size, name);
size = round_to_pagesize(size);
areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK | B_CONTIGUOUS, protection);
if (areaid < B_OK) {
ERROR("couldn't allocate area %s\n", name);
return B_ERROR;
}
rv = get_memory_map(virtadr, size, &pe, 1);
if (rv < B_OK) {
delete_area(areaid);
ERROR("couldn't get mapping for %s\n", name);
return B_ERROR;
}
memset(virtadr, 0, size);
if (virt)
*virt = virtadr;
if (phy)
*phy = pe.address;
TRACE("area = %ld, size = %ld, virt = %p, phy = %p\n", areaid, size, virtadr, pe.address);
return areaid;
}
area_id
map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name)
{
uint32 offset;
void *phyadr;
void *mapadr;
area_id area;
TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, name);
offset = (uint32)phy & (B_PAGE_SIZE - 1);
phyadr = (char *)phy - offset;
size = round_to_pagesize(size + offset);
area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr);
if (area < B_OK) {
ERROR("mapping '%s' failed, error 0x%lx (%s)\n", name, area, strerror(area));
return area;
}
*virt = (char *)mapadr + offset;
TRACE("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = %p, size = %ld, area = 0x%08lx\n",
phy, *virt, offset, phyadr, mapadr, size, area);
return area;
}

View File

@ -0,0 +1,27 @@
/* Realtek RTL8169 Family Driver
* Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies, and that both the
* copyright notice and this permission notice appear in supporting documentation.
*
* Marcus Overhagen makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
*
* MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
* OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __UTIL_H
#define __UTIL_H
#include <OS.h>
area_id alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name);
area_id map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name);
#endif

View File

@ -1,7 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers bus firewire ;
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
UsePrivateHeaders firewire ;
UsePrivateHeaders firewire kernel ;
SubDirCcFlags [ FDefines _KERNEL=1 ] ;

View File

@ -64,6 +64,9 @@
//#include "fwmem.h"
#include "iec68113.h"
#define TRACE(x...)
//#define TRACE(x...) dprintf(x)
#include "firewire_module.h"
#define FWNODE_INVAL 0xffff
@ -103,7 +106,7 @@ fwdev_allocbuf(struct fw_xferq *q,
b->psize = roundup2(b->psize, sizeof(uint32_t));
q->buf = gFirewire->fwdma_malloc_multiseg(sizeof(uint32_t),
b->psize, b->nchunk * b->npacket);
TRACE("fwdev_allocbuf %d\n", b->psize*b->nchunk*b->npacket);
if (q->buf == NULL) {
free(q->bulkxfer);
q->bulkxfer = NULL;
@ -169,7 +172,7 @@ fw_open (const char *name, uint32 flags, void **cookie)
return B_BAD_VALUE;
}
if (gFirewire->get_handle(count, sc) != B_OK) {
if (gFirewire->get_handle(count, &sc) != B_OK) {
return ENODEV;
}
@ -220,7 +223,7 @@ fw_free(void *cookie)
struct fw_xfer *xfer;
struct fw_bind *fwb;
TRACE("fw_free\n");
d = (struct fw_drv1 *)cookie;
delete_sem(d->rqSem);
fc = d->fc;
@ -979,11 +982,12 @@ init_driver()
#endif
if ((err = get_module(FIREWIRE_MODULE_NAME, (module_info **)&gFirewire)) != B_OK) {
dprintf("fw_raw: couldn't load "FIREWIRE_MODULE_NAME"\n");
return err;
}
devices_count = 0;
while (gFirewire->get_handle(devices_count, sc)==B_OK) {
while (gFirewire->get_handle(devices_count, &sc)==B_OK) {
devices_count++;
}
@ -997,6 +1001,7 @@ init_driver()
}
devices[devices_count] = NULL;
TRACE("fw_raw init_driver returns OK\n");
return B_OK;
}

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD: src/usr.sbin/fwcontrol/fwcontrol.c,v 1.23 2006/10/26 22:33:3
#ifdef __HAIKU__
#include <sys/param.h>
#include <sys/types.h>
#include <endian.h>
#include "eui64.h"
#include "firewire.h"
#include "iec13213.h"
@ -624,15 +625,21 @@ dump_phy_registers(int fd)
static void
open_dev(int *fd, char *devbase)
{
#ifndef __HAIKU__
char name[256];
int i;
#endif
if (*fd < 0) {
#ifdef __HAIKU__
*fd = open(devbase, O_RDWR);
#else
for (i = 0; i < 4; i++) {
snprintf(name, sizeof(name), "%s.%d", devbase, i);
if ((*fd = open(name, O_RDWR)) >= 0)
break;
}
#endif
if (*fd < 0)
err(1, "open");
@ -665,7 +672,7 @@ detect_recv_fn(int fd, char ich)
bufreq.tx.nchunk = 0;
bufreq.tx.npacket = 0;
bufreq.tx.psize = 0;
printf("detect dv format\n");
if (ioctl(fd, FW_SSTBUF, &bufreq) < 0)
err(1, "ioctl FW_SSTBUF");
@ -701,7 +708,7 @@ main(int argc, char **argv)
{
u_int32_t crom_buf[1024/4];
#ifdef __HAIKU__
char devbase[1024] = "/dev/fw";
char devbase[1024] = "/dev/bus/fw/0";
#else
char devbase[1024] = "/dev/fw0";
#endif
@ -788,7 +795,11 @@ main(int argc, char **argv)
break;
case 'u':
tmp = strtol(optarg, NULL, 0);
#ifdef __HAIKU__
snprintf(devbase, sizeof(devbase), "/dev/bus/fw/%ld", tmp);
#else
snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp);
#endif
if (fd > 0) {
close(fd);
fd = -1;

View File

@ -54,6 +54,12 @@ __FBSDID("$FreeBSD: src/sys/dev/firewire/fwcrom.c,v 1.14 2006/02/04 21:37:39 imp
#ifndef __HAIKU__
#include <sys/systm.h>
#include <sys/kernel.h>
#else
#include <OS.h>
#include <KernelExport.h>
#include <ByteOrder.h>
#include <string.h>
#include "fwglue.h"
#endif
#else
#include <netinet/in.h>

View File

@ -54,6 +54,7 @@
#include <string.h>
#ifdef __HAIKU__
#include <stdint.h>
#include <endian.h>
#include "firewire.h"
#include "iec68113.h"
#else

View File

@ -54,6 +54,7 @@
#include <string.h>
#ifdef __HAIKU__
#include <stdint.h>
#include <endian.h>
#include "firewire.h"
#include "iec68113.h"
#else