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:
@@ -5,63 +5,61 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef _FW_MODULE_H
|
#ifndef _FW_MODULE_H
|
||||||
#define _FW_MODULE_H
|
#define _FW_MODULE_H
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <bus_manager.h>
|
#include <bus_manager.h>
|
||||||
|
|
||||||
#include "firewire.h"
|
#include "firewire.h"
|
||||||
#include "firewirereg.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define FIREWIRE_MODULE_NAME "bus_managers/firewire/v1"
|
#define FIREWIRE_MODULE_NAME "bus_managers/firewire/v1"
|
||||||
#define MAX_CARDS 4
|
|
||||||
struct fw_module_info{
|
struct fw_module_info{
|
||||||
|
|
||||||
bus_manager_info binfo;
|
bus_manager_info binfo;
|
||||||
|
|
||||||
struct fw_device * (*fw_noderesolve_nodeid)(struct firewire_comm *fc, int dst);
|
struct fw_device * (*fw_noderesolve_nodeid)(struct firewire_comm *fc, int dst);
|
||||||
|
|
||||||
struct fw_device * (*fw_noderesolve_eui64)(struct firewire_comm *fc, struct fw_eui64 *eui);
|
struct fw_device * (*fw_noderesolve_eui64)(struct firewire_comm *fc, struct fw_eui64 *eui);
|
||||||
|
|
||||||
int (*fw_asyreq)(struct firewire_comm *fc, int sub, struct fw_xfer *xfer);
|
int (*fw_asyreq)(struct firewire_comm *fc, int sub, struct fw_xfer *xfer);
|
||||||
|
|
||||||
void (*fw_xferwake)(struct fw_xfer *xfer);
|
void (*fw_xferwake)(struct fw_xfer *xfer);
|
||||||
int (*fw_xferwait)(struct fw_xfer *xfer);
|
int (*fw_xferwait)(struct fw_xfer *xfer);
|
||||||
|
|
||||||
struct fw_bind * (*fw_bindlookup)(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo);
|
struct fw_bind * (*fw_bindlookup)(struct firewire_comm *fc, uint16_t dest_hi, uint32_t dest_lo);
|
||||||
|
|
||||||
int (*fw_bindadd)(struct firewire_comm *fc, struct fw_bind *fwb);
|
int (*fw_bindadd)(struct firewire_comm *fc, struct fw_bind *fwb);
|
||||||
|
|
||||||
int (*fw_bindremove)(struct firewire_comm *fc, struct fw_bind *fwb);
|
int (*fw_bindremove)(struct firewire_comm *fc, struct fw_bind *fwb);
|
||||||
|
|
||||||
int (*fw_xferlist_add)(struct fw_xferlist *q,
|
int (*fw_xferlist_add)(struct fw_xferlist *q,
|
||||||
int slen, int rlen, int n,
|
int slen, int rlen, int n,
|
||||||
struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *));
|
struct firewire_comm *fc, void *sc, void (*hand)(struct fw_xfer *));
|
||||||
|
|
||||||
void (*fw_xferlist_remove)(struct fw_xferlist *q);
|
void (*fw_xferlist_remove)(struct fw_xferlist *q);
|
||||||
|
|
||||||
struct fw_xfer * (*fw_xfer_alloc)();
|
struct fw_xfer * (*fw_xfer_alloc)();
|
||||||
|
|
||||||
struct fw_xfer * (*fw_xfer_alloc_buf)(int send_len, int recv_len);
|
struct fw_xfer * (*fw_xfer_alloc_buf)(int send_len, int recv_len);
|
||||||
|
|
||||||
void (*fw_xfer_done)(struct fw_xfer *xfer);
|
void (*fw_xfer_done)(struct fw_xfer *xfer);
|
||||||
|
|
||||||
void (*fw_xfer_unload)(struct fw_xfer* xfer);
|
void (*fw_xfer_unload)(struct fw_xfer* xfer);
|
||||||
|
|
||||||
void (*fw_xfer_free_buf)( struct fw_xfer* xfer);
|
void (*fw_xfer_free_buf)( struct fw_xfer* xfer);
|
||||||
|
|
||||||
void (*fw_xfer_free)( struct fw_xfer* xfer);
|
void (*fw_xfer_free)( struct fw_xfer* xfer);
|
||||||
|
|
||||||
void (*fw_asy_callback_free)(struct fw_xfer *xfer);
|
void (*fw_asy_callback_free)(struct fw_xfer *xfer);
|
||||||
|
|
||||||
int (*fw_open_isodma)(struct firewire_comm *fc, int tx);
|
int (*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,
|
struct fwdma_alloc_multi * (*fwdma_malloc_multiseg)(int alignment,
|
||||||
int esize, int n);
|
int esize, int n);
|
||||||
|
|
||||||
void (*fwdma_free_multiseg)(struct fwdma_alloc_multi *);
|
void (*fwdma_free_multiseg)(struct fwdma_alloc_multi *);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,7 +36,9 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef _FIREWIREREG_H
|
#ifndef _FIREWIREREG_H
|
||||||
#define _FIREWIREREG_H
|
#define _FIREWIREREG_H
|
||||||
#ifndef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
|
#include <OS.h>
|
||||||
|
#else
|
||||||
#ifdef __DragonFly__
|
#ifdef __DragonFly__
|
||||||
typedef d_thread_t fw_proc;
|
typedef d_thread_t fw_proc;
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
@@ -55,11 +57,15 @@ typedef struct proc fw_proc;
|
|||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/taskqueue.h>
|
#include <sys/taskqueue.h>
|
||||||
#define splfw splimp
|
#define splfw splimp
|
||||||
#else
|
#else
|
||||||
#define splfw disable_interrupts
|
#include <lock.h>
|
||||||
#define splx restore_interrupts
|
#include <dpc.h>
|
||||||
|
#include "fwglue.h"
|
||||||
|
#include "timer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_REQCOUNT 0xffff
|
||||||
|
|
||||||
STAILQ_HEAD(fw_xferlist, fw_xfer);
|
STAILQ_HEAD(fw_xferlist, fw_xfer);
|
||||||
|
|
||||||
struct fw_device{
|
struct fw_device{
|
||||||
@@ -119,8 +125,20 @@ struct crom_src_buf {
|
|||||||
struct crom_chunk root;
|
struct crom_chunk root;
|
||||||
struct crom_chunk vendor;
|
struct crom_chunk vendor;
|
||||||
struct crom_chunk hw;
|
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{
|
struct firewire_comm{
|
||||||
#ifndef __HAIKU__
|
#ifndef __HAIKU__
|
||||||
@@ -171,12 +189,12 @@ struct firewire_comm{
|
|||||||
struct callout busprobe_callout;
|
struct callout busprobe_callout;
|
||||||
struct callout bmr_callout;
|
struct callout bmr_callout;
|
||||||
struct callout timeout_callout;
|
struct callout timeout_callout;
|
||||||
|
struct task task_timeout;
|
||||||
#else
|
#else
|
||||||
//timer_id busprobe_callout;
|
timer_id busprobe_callout;
|
||||||
//timer_id bmr_callout;
|
timer_id bmr_callout;
|
||||||
//timer_id timeout_callout;
|
timer_id timeout_callout;
|
||||||
#endif
|
#endif
|
||||||
//struct task task_timeout;
|
|
||||||
uint32_t (*cyctimer) (struct firewire_comm *);
|
uint32_t (*cyctimer) (struct firewire_comm *);
|
||||||
void (*ibr) (struct firewire_comm *);
|
void (*ibr) (struct firewire_comm *);
|
||||||
uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
|
uint32_t (*set_bmr) (struct firewire_comm *, uint32_t);
|
||||||
@@ -199,29 +217,28 @@ struct firewire_comm{
|
|||||||
bus_dma_tag_t dmat;
|
bus_dma_tag_t dmat;
|
||||||
struct mtx mtx;
|
struct mtx mtx;
|
||||||
struct mtx wait_lock;
|
struct mtx wait_lock;
|
||||||
#else
|
struct taskqueue *taskqueue;
|
||||||
sem_id mtx;
|
|
||||||
sem_id wait_lock;
|
|
||||||
#endif
|
|
||||||
// struct taskqueue *taskqueue;//to be completed
|
|
||||||
#ifndef __HAIKU__
|
|
||||||
struct proc *probe_thread;
|
struct proc *probe_thread;
|
||||||
#else
|
#else
|
||||||
|
benaphore mtx;
|
||||||
|
benaphore wait_lock;
|
||||||
|
void *taskqueue;
|
||||||
thread_id probe_thread;
|
thread_id probe_thread;
|
||||||
|
sem_id Sem;
|
||||||
|
area_id crom_sid_Area;
|
||||||
|
struct firewire_child_info *childList;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
|
#define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4])
|
||||||
|
|
||||||
#ifndef __HAIKU__
|
|
||||||
#define FW_GMTX(fc) (&(fc)->mtx)
|
#define FW_GMTX(fc) (&(fc)->mtx)
|
||||||
#define FW_GLOCK(fc) mtx_lock(FW_GMTX(fc))
|
#define FW_GLOCK(fc) mtx_lock(FW_GMTX(fc))
|
||||||
#define FW_GUNLOCK(fc) mtx_unlock(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)
|
#define FW_GLOCK_ASSERT(fc) mtx_assert(FW_GMTX(fc), MA_OWNED)
|
||||||
#endif
|
#else
|
||||||
#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))
|
|
||||||
#define FW_GLOCK_ASSERT(fc)
|
#define FW_GLOCK_ASSERT(fc)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct fw_xferq {
|
struct fw_xferq {
|
||||||
int flag;
|
int flag;
|
||||||
@@ -252,15 +269,15 @@ struct fw_xferq {
|
|||||||
STAILQ_HEAD(, fw_bulkxfer) stdma;
|
STAILQ_HEAD(, fw_bulkxfer) stdma;
|
||||||
struct fw_bulkxfer *stproc;
|
struct fw_bulkxfer *stproc;
|
||||||
// struct selinfo rsel;
|
// struct selinfo rsel;
|
||||||
spinlock Spinlock;
|
|
||||||
sem_id Sem;
|
|
||||||
caddr_t sc;
|
caddr_t sc;
|
||||||
void (*hand) (struct fw_xferq *);
|
void (*hand) (struct fw_xferq *);
|
||||||
|
spinlock Spinlock;
|
||||||
|
sem_id Sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fw_bulkxfer{
|
struct fw_bulkxfer{
|
||||||
int poffset;
|
int poffset;
|
||||||
// struct mbuf *mbuf;//to be completed
|
// struct mbuf *mbuf;
|
||||||
STAILQ_ENTRY(fw_bulkxfer) link;
|
STAILQ_ENTRY(fw_bulkxfer) link;
|
||||||
caddr_t start;
|
caddr_t start;
|
||||||
caddr_t end;
|
caddr_t end;
|
||||||
@@ -280,8 +297,10 @@ struct fw_xfer{
|
|||||||
caddr_t sc;
|
caddr_t sc;
|
||||||
struct firewire_comm *fc;
|
struct firewire_comm *fc;
|
||||||
struct fw_xferq *q;
|
struct fw_xferq *q;
|
||||||
// struct timeval tv;//to be completed
|
// struct timeval tv;
|
||||||
int8_t resp;
|
bigtime_t tv;
|
||||||
|
|
||||||
|
int32_t resp;
|
||||||
#define FWXF_INIT 0x00
|
#define FWXF_INIT 0x00
|
||||||
#define FWXF_INQ 0x01
|
#define FWXF_INQ 0x01
|
||||||
#define FWXF_START 0x02
|
#define FWXF_START 0x02
|
||||||
@@ -294,16 +313,19 @@ struct fw_xfer{
|
|||||||
uint8_t flag;
|
uint8_t flag;
|
||||||
int8_t tl;
|
int8_t tl;
|
||||||
void (*hand) (struct fw_xfer *);
|
void (*hand) (struct fw_xfer *);
|
||||||
struct {
|
struct send_recv{
|
||||||
struct fw_pkt hdr;
|
struct fw_pkt hdr;
|
||||||
uint32_t *payload;
|
uint32_t *payload;
|
||||||
|
area_id payArea;
|
||||||
|
bus_addr_t bus_addr;
|
||||||
uint16_t pay_len;
|
uint16_t pay_len;
|
||||||
uint8_t spd;
|
uint8_t spd;
|
||||||
} send, recv;
|
} send, recv;
|
||||||
// struct mbuf *mbuf;//to be completed
|
// struct mbuf *mbuf;
|
||||||
STAILQ_ENTRY(fw_xfer) link;
|
STAILQ_ENTRY(fw_xfer) link;
|
||||||
STAILQ_ENTRY(fw_xfer) tlabel;
|
STAILQ_ENTRY(fw_xfer) tlabel;
|
||||||
struct malloc_type *malloc;
|
// struct malloc_type *malloc;
|
||||||
|
sem_id Sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fw_rcv_buf {
|
struct fw_rcv_buf {
|
||||||
@@ -313,20 +335,20 @@ struct fw_rcv_buf {
|
|||||||
u_int nvec;
|
u_int nvec;
|
||||||
uint8_t spd;
|
uint8_t spd;
|
||||||
};
|
};
|
||||||
#ifndef __HAIKU__
|
//#ifndef __HAIKU__
|
||||||
void fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
|
void fw_sidrcv (struct firewire_comm *, uint32_t *, u_int);
|
||||||
void fw_rcv (struct fw_rcv_buf *);
|
void fw_rcv (struct fw_rcv_buf *);
|
||||||
void fw_xfer_unload ( struct fw_xfer*);
|
void fw_xfer_unload ( struct fw_xfer*);
|
||||||
void fw_xfer_free_buf ( struct fw_xfer*);
|
void fw_xfer_free_buf ( struct fw_xfer*);
|
||||||
void fw_xfer_free ( 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 ();
|
||||||
struct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int);
|
struct fw_xfer *fw_xfer_alloc_buf (int, int);
|
||||||
void fw_init (struct firewire_comm *);
|
void fw_init (struct firewire_comm *);
|
||||||
int fw_tbuf_update (struct firewire_comm *, int, int);
|
int fw_tbuf_update (struct firewire_comm *, int, int);
|
||||||
int fw_rbuf_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_bindadd (struct firewire_comm *, struct fw_bind *);
|
||||||
int fw_bindremove (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 *));
|
struct firewire_comm *, void *, void (*)(struct fw_xfer *));
|
||||||
void fw_xferlist_remove (struct fw_xferlist *);
|
void fw_xferlist_remove (struct fw_xferlist *);
|
||||||
int fw_asyreq (struct firewire_comm *, int, struct fw_xfer*);
|
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_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
|
||||||
struct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
|
struct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t);
|
||||||
void fw_drain_txq (struct firewire_comm *);
|
void fw_drain_txq (struct firewire_comm *);
|
||||||
int fwdev_makedev (struct firewire_softc *);
|
//int fwdev_makedev (struct firewire_softc *);
|
||||||
int fwdev_destroydev (struct firewire_softc *);
|
//int fwdev_destroydev (struct firewire_softc *);
|
||||||
void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
|
//void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **);
|
||||||
int fw_open_isodma(struct firewire_comm *, int);
|
int fw_open_isodma(struct firewire_comm *, int);
|
||||||
#endif
|
//#endif
|
||||||
extern int firewire_debug;
|
extern int firewire_debug;
|
||||||
#ifndef __HAIKU__
|
#ifndef __HAIKU__
|
||||||
extern devclass_t firewire_devclass;
|
extern devclass_t firewire_devclass;
|
||||||
|
|||||||
@@ -36,21 +36,13 @@
|
|||||||
#ifndef _FWDMA_H
|
#ifndef _FWDMA_H
|
||||||
#define _FWDMA_H
|
#define _FWDMA_H
|
||||||
|
|
||||||
#ifndef howmany
|
#include "fwglue.h"
|
||||||
#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;
|
|
||||||
|
|
||||||
struct fwdma_alloc {
|
struct fwdma_alloc {
|
||||||
// bus_dma_tag_t dma_tag;
|
// bus_dma_tag_t dma_tag;
|
||||||
// bus_dmamap_t dma_map;
|
// bus_dmamap_t dma_map;
|
||||||
area_id BufArea;
|
area_id Area;
|
||||||
void * v_addr;
|
void * v_addr;
|
||||||
bus_addr_t bus_addr;
|
bus_addr_t bus_addr;
|
||||||
};
|
};
|
||||||
@@ -67,7 +59,7 @@ struct fwdma_alloc_multi {
|
|||||||
bus_size_t esize;
|
bus_size_t esize;
|
||||||
int nseg;
|
int nseg;
|
||||||
// bus_dma_tag_t dma_tag;
|
// bus_dma_tag_t dma_tag;
|
||||||
area_id BufArea;
|
area_id Area;
|
||||||
|
|
||||||
struct fwdma_seg seg[0];
|
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);
|
bus_dmamap_sync(am->dma_tag, seg->dma_map, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *fwdma_malloc(int, bus_size_t, struct fwdma_alloc *, int);
|
void *fwdma_malloc(struct firewire_comm *, int, bus_size_t, struct fwdma_alloc *, int);
|
||||||
void fwdma_free(struct fwdma_alloc *);
|
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_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);
|
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 *,
|
struct fwdma_alloc_multi *fwdma_malloc_multiseg(struct firewire_comm *,
|
||||||
int, int, int, int);
|
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 /*__HAIKU__*/
|
||||||
|
|
||||||
#endif /* _FWDMA_H*/
|
#endif /* _FWDMA_H*/
|
||||||
|
|||||||
@@ -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*/
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/* Realtek RTL8169 Family Driver
|
||||||
|
* Copyright (C) 2004 Marcus Overhagen <[email protected]>. 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
|
||||||
@@ -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] <[email protected]> and
|
||||||
|
modified by Hidetoshi Shimokawa <[email protected]>.
|
||||||
|
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
|
||||||
|
[email protected]
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel bus_managers firewire ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||||
|
UsePrivateHeaders firewire kernel ;
|
||||||
|
|
||||||
|
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
|
||||||
|
|
||||||
|
KernelAddon firewire :
|
||||||
|
util.c
|
||||||
|
timer.c
|
||||||
|
firewire_module.c
|
||||||
|
firewire.c
|
||||||
|
fwdma.c
|
||||||
|
fwmem.c
|
||||||
|
fwohci.c
|
||||||
|
fwohci_pci.c
|
||||||
|
fwcrom.c
|
||||||
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles
|
||||||
|
fwcrom.c
|
||||||
|
] = [ FDirName $(HAIKU_TOP) src bin fwcontrol ] ;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
|
};
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (C) 2002-2003
|
||||||
|
* Hidetoshi Shimokawa. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
*
|
||||||
|
* This product includes software developed by Hidetoshi Shimokawa.
|
||||||
|
*
|
||||||
|
* 4. Neither the name of the author nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD: src/sys/dev/firewire/fwmem.h,v 1.8 2005/01/06 01:42:41 imp Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct fw_xfer *fwmem_read_quad(struct fw_device *, caddr_t, uint8_t,
|
||||||
|
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
|
||||||
|
struct fw_xfer *fwmem_write_quad(struct fw_device *, caddr_t, uint8_t,
|
||||||
|
uint16_t, uint32_t, void *, void (*)(struct fw_xfer *));
|
||||||
|
struct fw_xfer *fwmem_read_block(struct fw_device *, caddr_t, uint8_t,
|
||||||
|
uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
|
||||||
|
struct fw_xfer *fwmem_write_block(struct fw_device *, caddr_t, uint8_t,
|
||||||
|
uint16_t, uint32_t, int, void *, void (*)(struct fw_xfer *));
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
|
d_open_t fwmem_open;
|
||||||
|
d_close_t fwmem_close;
|
||||||
|
d_ioctl_t fwmem_ioctl;
|
||||||
|
d_read_t fwmem_read;
|
||||||
|
d_write_t fwmem_write;
|
||||||
|
d_poll_t fwmem_poll;
|
||||||
|
d_mmap_t fwmem_mmap;
|
||||||
|
d_strategy_t fwmem_strategy;
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 ;
|
SubDir HAIKU_TOP src add-ons kernel drivers bus firewire ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||||
UsePrivateHeaders firewire ;
|
UsePrivateHeaders firewire kernel ;
|
||||||
|
|
||||||
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
|
SubDirCcFlags [ FDefines _KERNEL=1 ] ;
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,9 @@
|
|||||||
//#include "fwmem.h"
|
//#include "fwmem.h"
|
||||||
#include "iec68113.h"
|
#include "iec68113.h"
|
||||||
|
|
||||||
|
#define TRACE(x...)
|
||||||
|
//#define TRACE(x...) dprintf(x)
|
||||||
|
|
||||||
#include "firewire_module.h"
|
#include "firewire_module.h"
|
||||||
|
|
||||||
#define FWNODE_INVAL 0xffff
|
#define FWNODE_INVAL 0xffff
|
||||||
@@ -103,7 +106,7 @@ fwdev_allocbuf(struct fw_xferq *q,
|
|||||||
b->psize = roundup2(b->psize, sizeof(uint32_t));
|
b->psize = roundup2(b->psize, sizeof(uint32_t));
|
||||||
q->buf = gFirewire->fwdma_malloc_multiseg(sizeof(uint32_t),
|
q->buf = gFirewire->fwdma_malloc_multiseg(sizeof(uint32_t),
|
||||||
b->psize, b->nchunk * b->npacket);
|
b->psize, b->nchunk * b->npacket);
|
||||||
|
TRACE("fwdev_allocbuf %d\n", b->psize*b->nchunk*b->npacket);
|
||||||
if (q->buf == NULL) {
|
if (q->buf == NULL) {
|
||||||
free(q->bulkxfer);
|
free(q->bulkxfer);
|
||||||
q->bulkxfer = NULL;
|
q->bulkxfer = NULL;
|
||||||
@@ -169,7 +172,7 @@ fw_open (const char *name, uint32 flags, void **cookie)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gFirewire->get_handle(count, sc) != B_OK) {
|
if (gFirewire->get_handle(count, &sc) != B_OK) {
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +223,7 @@ fw_free(void *cookie)
|
|||||||
struct fw_xfer *xfer;
|
struct fw_xfer *xfer;
|
||||||
struct fw_bind *fwb;
|
struct fw_bind *fwb;
|
||||||
|
|
||||||
|
TRACE("fw_free\n");
|
||||||
d = (struct fw_drv1 *)cookie;
|
d = (struct fw_drv1 *)cookie;
|
||||||
delete_sem(d->rqSem);
|
delete_sem(d->rqSem);
|
||||||
fc = d->fc;
|
fc = d->fc;
|
||||||
@@ -979,11 +982,12 @@ init_driver()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((err = get_module(FIREWIRE_MODULE_NAME, (module_info **)&gFirewire)) != B_OK) {
|
if ((err = get_module(FIREWIRE_MODULE_NAME, (module_info **)&gFirewire)) != B_OK) {
|
||||||
|
dprintf("fw_raw: couldn't load "FIREWIRE_MODULE_NAME"\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
devices_count = 0;
|
devices_count = 0;
|
||||||
while (gFirewire->get_handle(devices_count, sc)==B_OK) {
|
while (gFirewire->get_handle(devices_count, &sc)==B_OK) {
|
||||||
devices_count++;
|
devices_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,6 +1001,7 @@ init_driver()
|
|||||||
}
|
}
|
||||||
devices[devices_count] = NULL;
|
devices[devices_count] = NULL;
|
||||||
|
|
||||||
|
TRACE("fw_raw init_driver returns OK\n");
|
||||||
return B_OK;
|
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__
|
#ifdef __HAIKU__
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <endian.h>
|
||||||
#include "eui64.h"
|
#include "eui64.h"
|
||||||
#include "firewire.h"
|
#include "firewire.h"
|
||||||
#include "iec13213.h"
|
#include "iec13213.h"
|
||||||
@@ -624,15 +625,21 @@ dump_phy_registers(int fd)
|
|||||||
static void
|
static void
|
||||||
open_dev(int *fd, char *devbase)
|
open_dev(int *fd, char *devbase)
|
||||||
{
|
{
|
||||||
|
#ifndef __HAIKU__
|
||||||
char name[256];
|
char name[256];
|
||||||
int i;
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*fd < 0) {
|
if (*fd < 0) {
|
||||||
|
#ifdef __HAIKU__
|
||||||
|
*fd = open(devbase, O_RDWR);
|
||||||
|
#else
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
snprintf(name, sizeof(name), "%s.%d", devbase, i);
|
snprintf(name, sizeof(name), "%s.%d", devbase, i);
|
||||||
if ((*fd = open(name, O_RDWR)) >= 0)
|
if ((*fd = open(name, O_RDWR)) >= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (*fd < 0)
|
if (*fd < 0)
|
||||||
err(1, "open");
|
err(1, "open");
|
||||||
|
|
||||||
@@ -665,7 +672,7 @@ detect_recv_fn(int fd, char ich)
|
|||||||
bufreq.tx.nchunk = 0;
|
bufreq.tx.nchunk = 0;
|
||||||
bufreq.tx.npacket = 0;
|
bufreq.tx.npacket = 0;
|
||||||
bufreq.tx.psize = 0;
|
bufreq.tx.psize = 0;
|
||||||
|
printf("detect dv format\n");
|
||||||
if (ioctl(fd, FW_SSTBUF, &bufreq) < 0)
|
if (ioctl(fd, FW_SSTBUF, &bufreq) < 0)
|
||||||
err(1, "ioctl FW_SSTBUF");
|
err(1, "ioctl FW_SSTBUF");
|
||||||
|
|
||||||
@@ -701,7 +708,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
u_int32_t crom_buf[1024/4];
|
u_int32_t crom_buf[1024/4];
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
char devbase[1024] = "/dev/fw";
|
char devbase[1024] = "/dev/bus/fw/0";
|
||||||
#else
|
#else
|
||||||
char devbase[1024] = "/dev/fw0";
|
char devbase[1024] = "/dev/fw0";
|
||||||
#endif
|
#endif
|
||||||
@@ -788,7 +795,11 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
tmp = strtol(optarg, NULL, 0);
|
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);
|
snprintf(devbase, sizeof(devbase), "/dev/fw%ld", tmp);
|
||||||
|
#endif
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
fd = -1;
|
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__
|
#ifndef __HAIKU__
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
#else
|
||||||
|
#include <OS.h>
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "fwglue.h"
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <endian.h>
|
||||||
#include "firewire.h"
|
#include "firewire.h"
|
||||||
#include "iec68113.h"
|
#include "iec68113.h"
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <endian.h>
|
||||||
#include "firewire.h"
|
#include "firewire.h"
|
||||||
#include "iec68113.h"
|
#include "iec68113.h"
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user