2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify,
8 * merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 #include <KernelExport.h>
34 #include "dvb_interface.h"
52 int32 api_version
= B_CUR_DRIVER_API_VERSION
;
53 pci_module_info
* gPci
;
54 static char * sDevNameList
[MAX_CARDS
+ 1];
55 static pci_info
* sDevList
[MAX_CARDS
];
56 static int32 sOpenMask
;
58 static card_info sCardTable
[] =
60 { 0x14f1, 0x8802, 0x0070, 0x9002, "Hauppauge WinTV-NOVA-T model 928" },
73 identify_device(const card_info
*cards
, const pci_info
*info
)
75 for (; cards
->name
; cards
++) {
76 if (cards
->vendor
>= 0 && cards
->vendor
!= info
->vendor_id
)
78 if (cards
->device
>= 0 && cards
->device
!= info
->device_id
)
80 if ((info
->header_type
& PCI_header_type_mask
) != PCI_header_type_generic
)
82 if (cards
->subvendor
>= 0 && cards
->subvendor
!= info
->u
.h0
.subsystem_vendor_id
)
84 if (cards
->subdevice
>= 0 && cards
->subdevice
!= info
->u
.h0
.subsystem_id
)
99 TRACE("cx23882: init_hardware()\n");
101 if (get_module(B_PCI_MODULE_NAME
, (module_info
**)&gPci
) < B_OK
)
103 for (res
= B_ERROR
, i
= 0; gPci
->get_nth_pci_info(i
, &info
) == B_OK
; i
++) {
104 if (identify_device(sCardTable
, &info
)) {
109 put_module(B_PCI_MODULE_NAME
);
119 struct pci_info
*item
;
123 #if defined(DEBUG) && !defined(__HAIKU__)
124 set_dprintf_enabled(true);
125 load_driver_symbols("cx23882");
130 item
= (pci_info
*)malloc(sizeof(pci_info
));
134 if (get_module(B_PCI_MODULE_NAME
, (module_info
**)&gPci
) < B_OK
) {
139 for (cards
= 0, index
= 0; gPci
->get_nth_pci_info(index
++, item
) == B_OK
; ) {
140 const char *info
= identify_device(sCardTable
, item
);
143 sprintf(name
, "dvb/cx23882/%d", cards
+ 1);
144 dprintf("cx23882: /dev/%s is a %s\n", name
, info
);
145 sDevList
[cards
] = item
;
146 sDevNameList
[cards
] = strdup(name
);
147 sDevNameList
[cards
+ 1] = NULL
;
149 item
= (pci_info
*)malloc(sizeof(pci_info
));
152 if (cards
== MAX_CARDS
)
165 TRACE("cx23882: err_outofmem\n");
166 for (index
= 0; index
< cards
; index
++) {
167 free(sDevList
[index
]);
168 free(sDevNameList
[index
]);
171 put_module(B_PCI_MODULE_NAME
);
181 TRACE("cx23882: uninit_driver\n");
183 for (i
= 0; sDevNameList
[i
] != NULL
; i
++) {
185 free(sDevNameList
[i
]);
188 put_module(B_PCI_MODULE_NAME
);
193 driver_open(const char *name
, uint32 flags
, void** _cookie
)
195 interface_cookie
*cookie
;
201 TRACE("cx23882: driver open\n");
203 for (dev_id
= 0; (deviceName
= sDevNameList
[dev_id
]) != NULL
; dev_id
++) {
204 if (!strcmp(name
, deviceName
))
207 if (deviceName
== NULL
) {
208 TRACE("cx23882: invalid device name\n");
212 // allow only one concurrent access
214 if (atomic_or(&sOpenMask
, mask
) & mask
)
217 cookie
= (interface_cookie
*)malloc(sizeof(interface_cookie
));
221 cookie
->dev_id
= dev_id
;
222 status
= interface_attach(&cookie
->cookie
, sDevList
[dev_id
]);
223 if (status
!= B_OK
) {
225 atomic_and(&sOpenMask
, ~(1 << dev_id
));
235 driver_close(void* cookie
)
237 TRACE("cx23882: driver close enter\n");
238 interface_detach(((interface_cookie
*)cookie
)->cookie
);
239 TRACE("cx23882: driver close leave\n");
245 driver_free(void* cookie
)
247 TRACE("cx23882: driver free\n");
248 atomic_and(&sOpenMask
, ~(1 << ((interface_cookie
*)cookie
)->dev_id
));
255 driver_read(void* cookie
, off_t position
, void *buf
, size_t* num_bytes
)
257 TRACE("cx23882: driver read\n");
258 *num_bytes
= 0; // required by design for read hook!
264 driver_write(void* cookie
, off_t position
, const void* buffer
, size_t* num_bytes
)
266 TRACE("cx23882: driver write\n");
267 *num_bytes
= 0; // not sure if required for write hook
273 driver_control(void *cookie
, uint32 op
, void *arg
, size_t len
)
275 // TRACE("cx23882: driver control\n");
276 return interface_ioctl(((interface_cookie
*)cookie
)->cookie
, op
, arg
, len
);
292 publish_devices(void)
294 return (const char**)sDevNameList
;
299 find_device(const char* name
)
301 return &sDeviceHooks
;