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:
parent
68f2081497
commit
bb5ea4eb08
@ -5,17 +5,15 @@
|
||||
*/
|
||||
#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;
|
||||
@ -57,7 +55,7 @@ struct fw_module_info{
|
||||
|
||||
int (*fw_open_isodma)(struct firewire_comm *fc, int tx);
|
||||
|
||||
int (*get_handle)(int socket, struct firewire_softc *handle);
|
||||
int (*get_handle)(int socket, struct firewire_softc **handle);
|
||||
|
||||
struct fwdma_alloc_multi * (*fwdma_malloc_multiseg)(int alignment,
|
||||
int esize, int n);
|
||||
|
@ -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>
|
||||
@ -56,10 +58,14 @@ typedef struct proc fw_proc;
|
||||
#include <sys/taskqueue.h>
|
||||
#define splfw splimp
|
||||
#else
|
||||
#define splfw disable_interrupts
|
||||
#define splx restore_interrupts
|
||||
#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;
|
||||
|
@ -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*/
|
||||
|
56
headers/private/firewire/fwglue.h
Normal file
56
headers/private/firewire/fwglue.h
Normal 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*/
|
44
headers/private/firewire/timer.h
Normal file
44
headers/private/firewire/timer.h
Normal 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
|
152
src/add-ons/kernel/bus_managers/firewire/00README
Normal file
152
src/add-ons/kernel/bus_managers/firewire/00README
Normal 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
|
22
src/add-ons/kernel/bus_managers/firewire/Jamfile
Normal file
22
src/add-ons/kernel/bus_managers/firewire/Jamfile
Normal 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 ] ;
|
2317
src/add-ons/kernel/bus_managers/firewire/firewire.c
Normal file
2317
src/add-ons/kernel/bus_managers/firewire/firewire.c
Normal file
File diff suppressed because it is too large
Load Diff
309
src/add-ons/kernel/bus_managers/firewire/firewire_module.c
Normal file
309
src/add-ons/kernel/bus_managers/firewire/firewire_module.c
Normal 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
|
||||
};
|
85
src/add-ons/kernel/bus_managers/firewire/firewire_phy.h
Normal file
85
src/add-ons/kernel/bus_managers/firewire/firewire_phy.h
Normal 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
|
21
src/add-ons/kernel/bus_managers/firewire/fwdebug.h
Normal file
21
src/add-ons/kernel/bus_managers/firewire/fwdebug.h
Normal 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
|
233
src/add-ons/kernel/bus_managers/firewire/fwdma.c
Normal file
233
src/add-ons/kernel/bus_managers/firewire/fwdma.c
Normal 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);
|
||||
}
|
227
src/add-ons/kernel/bus_managers/firewire/fwmem.c
Normal file
227
src/add-ons/kernel/bus_managers/firewire/fwmem.c
Normal 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;
|
||||
}
|
55
src/add-ons/kernel/bus_managers/firewire/fwmem.h
Normal file
55
src/add-ons/kernel/bus_managers/firewire/fwmem.h
Normal 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
|
2965
src/add-ons/kernel/bus_managers/firewire/fwohci.c
Normal file
2965
src/add-ons/kernel/bus_managers/firewire/fwohci.c
Normal file
File diff suppressed because it is too large
Load Diff
223
src/add-ons/kernel/bus_managers/firewire/fwohci_pci.c
Normal file
223
src/add-ons/kernel/bus_managers/firewire/fwohci_pci.c
Normal 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;
|
||||
}
|
452
src/add-ons/kernel/bus_managers/firewire/fwohcireg.h
Normal file
452
src/add-ons/kernel/bus_managers/firewire/fwohcireg.h
Normal 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
|
93
src/add-ons/kernel/bus_managers/firewire/fwohcivar.h
Normal file
93
src/add-ons/kernel/bus_managers/firewire/fwohcivar.h
Normal 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
|
216
src/add-ons/kernel/bus_managers/firewire/timer.c
Normal file
216
src/add-ons/kernel/bus_managers/firewire/timer.c
Normal 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);
|
||||
}
|
||||
|
90
src/add-ons/kernel/bus_managers/firewire/util.c
Normal file
90
src/add-ons/kernel/bus_managers/firewire/util.c
Normal 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;
|
||||
}
|
27
src/add-ons/kernel/bus_managers/firewire/util.h
Normal file
27
src/add-ons/kernel/bus_managers/firewire/util.h
Normal 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
|
@ -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 ] ;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <string.h>
|
||||
#ifdef __HAIKU__
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include "firewire.h"
|
||||
#include "iec68113.h"
|
||||
#else
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <string.h>
|
||||
#ifdef __HAIKU__
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include "firewire.h"
|
||||
#include "iec68113.h"
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user