1 /* $Id: um_idi.c,v 1.14 2004/03/21 17:54:37 armin Exp $ */
14 #define DIVAS_MAX_XDI_ADAPTERS 64
16 /* --------------------------------------------------------------------------
18 -------------------------------------------------------------------------- */
19 extern void diva_os_wakeup_read(void *os_context
);
20 extern void diva_os_wakeup_close(void *os_context
);
21 /* --------------------------------------------------------------------------
23 -------------------------------------------------------------------------- */
24 static LIST_HEAD(adapter_q
);
25 static diva_os_spin_lock_t adapter_lock
;
27 static diva_um_idi_adapter_t
*diva_um_idi_find_adapter(dword nr
);
28 static void cleanup_adapter(diva_um_idi_adapter_t
*a
);
29 static void cleanup_entity(divas_um_idi_entity_t
*e
);
30 static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t
*a
,
31 diva_um_idi_adapter_features_t
33 static int process_idi_request(divas_um_idi_entity_t
*e
,
34 const diva_um_idi_req_hdr_t
*req
);
35 static int process_idi_rc(divas_um_idi_entity_t
*e
, byte rc
);
36 static int process_idi_ind(divas_um_idi_entity_t
*e
, byte ind
);
37 static int write_return_code(divas_um_idi_entity_t
*e
, byte rc
);
39 /* --------------------------------------------------------------------------
41 -------------------------------------------------------------------------- */
42 int diva_user_mode_idi_init(void)
44 diva_os_initialize_spin_lock(&adapter_lock
, "adapter");
48 /* --------------------------------------------------------------------------
49 Copy adapter features to user supplied buffer
50 -------------------------------------------------------------------------- */
52 diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t
*a
,
53 diva_um_idi_adapter_features_t
*
56 IDI_SYNC_REQ sync_req
;
58 if ((a
) && (a
->d
.request
)) {
59 features
->type
= a
->d
.type
;
60 features
->features
= a
->d
.features
;
61 features
->channels
= a
->d
.channels
;
62 memset(features
->name
, 0, sizeof(features
->name
));
64 sync_req
.GetName
.Req
= 0;
65 sync_req
.GetName
.Rc
= IDI_SYNC_REQ_GET_NAME
;
66 (*(a
->d
.request
)) ((ENTITY
*)&sync_req
);
67 strlcpy(features
->name
, sync_req
.GetName
.name
,
68 sizeof(features
->name
));
70 sync_req
.GetSerial
.Req
= 0;
71 sync_req
.GetSerial
.Rc
= IDI_SYNC_REQ_GET_SERIAL
;
72 sync_req
.GetSerial
.serial
= 0;
73 (*(a
->d
.request
))((ENTITY
*)&sync_req
);
74 features
->serial_number
= sync_req
.GetSerial
.serial
;
77 return ((a
) ? 0 : -1);
80 /* --------------------------------------------------------------------------
82 -------------------------------------------------------------------------- */
83 void diva_user_mode_idi_remove_adapter(int adapter_nr
)
85 struct list_head
*tmp
;
86 diva_um_idi_adapter_t
*a
;
88 list_for_each(tmp
, &adapter_q
) {
89 a
= list_entry(tmp
, diva_um_idi_adapter_t
, link
);
90 if (a
->adapter_nr
== adapter_nr
) {
93 DBG_LOG(("DIDD: del adapter(%d)", a
->adapter_nr
));
100 /* --------------------------------------------------------------------------
101 CALLED ON DRIVER EXIT (UNLOAD)
102 -------------------------------------------------------------------------- */
103 void diva_user_mode_idi_finit(void)
105 struct list_head
*tmp
, *safe
;
106 diva_um_idi_adapter_t
*a
;
108 list_for_each_safe(tmp
, safe
, &adapter_q
) {
109 a
= list_entry(tmp
, diva_um_idi_adapter_t
, link
);
112 DBG_LOG(("DIDD: del adapter(%d)", a
->adapter_nr
));
115 diva_os_destroy_spin_lock(&adapter_lock
, "adapter");
118 /* -------------------------------------------------------------------------
119 CREATE AND INIT IDI ADAPTER
120 ------------------------------------------------------------------------- */
121 int diva_user_mode_idi_create_adapter(const DESCRIPTOR
*d
, int adapter_nr
)
123 diva_os_spin_lock_magic_t old_irql
;
124 diva_um_idi_adapter_t
*a
=
125 (diva_um_idi_adapter_t
*) diva_os_malloc(0,
127 (diva_um_idi_adapter_t
));
132 memset(a
, 0x00, sizeof(*a
));
133 INIT_LIST_HEAD(&a
->entity_q
);
136 a
->adapter_nr
= adapter_nr
;
138 DBG_LOG(("DIDD_ADD A(%d), type:%02x, features:%04x, channels:%d",
139 adapter_nr
, a
->d
.type
, a
->d
.features
, a
->d
.channels
));
141 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "create_adapter");
142 list_add_tail(&a
->link
, &adapter_q
);
143 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "create_adapter");
147 /* ------------------------------------------------------------------------
148 Find adapter by Adapter number
149 ------------------------------------------------------------------------ */
150 static diva_um_idi_adapter_t
*diva_um_idi_find_adapter(dword nr
)
152 diva_um_idi_adapter_t
*a
= NULL
;
153 struct list_head
*tmp
;
155 list_for_each(tmp
, &adapter_q
) {
156 a
= list_entry(tmp
, diva_um_idi_adapter_t
, link
);
157 DBG_TRC(("find_adapter: (%d)-(%d)", nr
, a
->adapter_nr
));
158 if (a
->adapter_nr
== (int)nr
)
165 /* ------------------------------------------------------------------------
166 Cleanup this adapter and cleanup/delete all entities assigned
168 ------------------------------------------------------------------------ */
169 static void cleanup_adapter(diva_um_idi_adapter_t
*a
)
171 struct list_head
*tmp
, *safe
;
172 divas_um_idi_entity_t
*e
;
174 list_for_each_safe(tmp
, safe
, &a
->entity_q
) {
175 e
= list_entry(tmp
, divas_um_idi_entity_t
, link
);
179 diva_os_wakeup_read(e
->os_context
);
180 diva_os_wakeup_close(e
->os_context
);
183 memset(&a
->d
, 0x00, sizeof(DESCRIPTOR
));
186 /* ------------------------------------------------------------------------
187 Cleanup, but NOT delete this entity
188 ------------------------------------------------------------------------ */
189 static void cleanup_entity(divas_um_idi_entity_t
*e
)
197 e
->status
|= DIVA_UM_IDI_REMOVED
;
198 e
->status
|= DIVA_UM_IDI_REMOVE_PENDING
;
200 diva_data_q_finit(&e
->data
);
201 diva_data_q_finit(&e
->rc
);
205 /* ------------------------------------------------------------------------
206 Create ENTITY, link it to the adapter and remove pointer to entity
207 ------------------------------------------------------------------------ */
208 void *divas_um_idi_create_entity(dword adapter_nr
, void *file
)
210 divas_um_idi_entity_t
*e
;
211 diva_um_idi_adapter_t
*a
;
212 diva_os_spin_lock_magic_t old_irql
;
214 if ((e
= (divas_um_idi_entity_t
*) diva_os_malloc(0, sizeof(*e
)))) {
215 memset(e
, 0x00, sizeof(*e
));
218 diva_os_malloc(0, diva_os_get_context_size()))) {
219 DBG_LOG(("E(%08x) no memory for os context", e
));
223 memset(e
->os_context
, 0x00, diva_os_get_context_size());
225 if ((diva_data_q_init(&e
->data
, 2048 + 512, 16))) {
226 diva_os_free(0, e
->os_context
);
230 if ((diva_data_q_init(&e
->rc
, sizeof(diva_um_idi_ind_hdr_t
), 2))) {
231 diva_data_q_finit(&e
->data
);
232 diva_os_free(0, e
->os_context
);
237 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "create_entity");
239 Look for Adapter requested
241 if (!(a
= diva_um_idi_find_adapter(adapter_nr
))) {
243 No adapter was found, or this adapter was removed
245 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "create_entity");
247 DBG_LOG(("A: no adapter(%ld)", adapter_nr
));
250 diva_os_free(0, e
->os_context
);
256 e
->os_ref
= file
; /* link to os handle */
257 e
->adapter
= a
; /* link to adapter */
259 list_add_tail(&e
->link
, &a
->entity_q
); /* link from adapter */
261 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "create_entity");
263 DBG_LOG(("A(%ld), create E(%08x)", adapter_nr
, e
));
269 /* ------------------------------------------------------------------------
270 Unlink entity and free memory
271 ------------------------------------------------------------------------ */
272 int divas_um_idi_delete_entity(int adapter_nr
, void *entity
)
274 divas_um_idi_entity_t
*e
;
275 diva_um_idi_adapter_t
*a
;
276 diva_os_spin_lock_magic_t old_irql
;
278 if (!(e
= (divas_um_idi_entity_t
*) entity
))
281 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "delete_entity");
282 if ((a
= e
->adapter
)) {
285 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "delete_entity");
287 diva_um_idi_stop_wdog(entity
);
289 diva_os_free(0, e
->os_context
);
290 memset(e
, 0x00, sizeof(*e
));
292 DBG_LOG(("A(%d) remove E:%08x", adapter_nr
, e
));
298 /* --------------------------------------------------------------------------
299 Called by application to read data from IDI
300 -------------------------------------------------------------------------- */
301 int diva_um_idi_read(void *entity
,
304 int max_length
, divas_um_idi_copy_to_user_fn_t cp_fn
)
306 divas_um_idi_entity_t
*e
;
307 diva_um_idi_adapter_t
*a
;
310 diva_um_idi_data_queue_t
*q
;
311 diva_os_spin_lock_magic_t old_irql
;
313 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "read");
315 e
= (divas_um_idi_entity_t
*) entity
;
316 if (!e
|| (!(a
= e
->adapter
)) ||
317 (e
->status
& DIVA_UM_IDI_REMOVE_PENDING
) ||
318 (e
->status
& DIVA_UM_IDI_REMOVED
) ||
319 (a
->status
& DIVA_UM_IDI_ADAPTER_REMOVED
)) {
320 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "read");
321 DBG_ERR(("E(%08x) read failed - adapter removed", e
))
325 DBG_TRC(("A(%d) E(%08x) read(%d)", a
->adapter_nr
, e
, max_length
));
328 Try to read return code first
330 data
= diva_data_q_get_segment4read(&e
->rc
);
334 No return codes available, read indications now
337 if (!(e
->status
& DIVA_UM_IDI_RC_PENDING
)) {
338 DBG_TRC(("A(%d) E(%08x) read data", a
->adapter_nr
, e
));
339 data
= diva_data_q_get_segment4read(&e
->data
);
343 e
->status
&= ~DIVA_UM_IDI_RC_PENDING
;
344 DBG_TRC(("A(%d) E(%08x) read rc", a
->adapter_nr
, e
));
348 if ((length
= diva_data_q_get_segment_length(q
)) >
351 Not enough space to read message
353 DBG_ERR(("A: A(%d) E(%08x) read small buffer",
354 a
->adapter_nr
, e
, ret
));
355 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
,
360 Copy it to user, this function does access ONLY locked an verified
361 memory, also we can access it witch spin lock held
364 if ((ret
= (*cp_fn
) (os_handle
, dst
, data
, length
)) >= 0) {
366 Acknowledge only if read was successful
368 diva_data_q_ack_segment4read(q
);
373 DBG_TRC(("A(%d) E(%08x) read=%d", a
->adapter_nr
, e
, ret
));
375 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "read");
381 int diva_um_idi_write(void *entity
,
384 int length
, divas_um_idi_copy_from_user_fn_t cp_fn
)
386 divas_um_idi_entity_t
*e
;
387 diva_um_idi_adapter_t
*a
;
388 diva_um_idi_req_hdr_t
*req
;
391 diva_os_spin_lock_magic_t old_irql
;
393 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "write");
395 e
= (divas_um_idi_entity_t
*) entity
;
396 if (!e
|| (!(a
= e
->adapter
)) ||
397 (e
->status
& DIVA_UM_IDI_REMOVE_PENDING
) ||
398 (e
->status
& DIVA_UM_IDI_REMOVED
) ||
399 (a
->status
& DIVA_UM_IDI_ADAPTER_REMOVED
)) {
400 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
401 DBG_ERR(("E(%08x) write failed - adapter removed", e
))
405 DBG_TRC(("A(%d) E(%08x) write(%d)", a
->adapter_nr
, e
, length
));
407 if ((length
< sizeof(*req
)) || (length
> sizeof(e
->buffer
))) {
408 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
412 if (e
->status
& DIVA_UM_IDI_RC_PENDING
) {
413 DBG_ERR(("A: A(%d) E(%08x) rc pending", a
->adapter_nr
, e
));
414 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
415 return (-1); /* should wait for RC code first */
419 Copy function does access only locked verified memory,
420 also it can be called with spin lock held
422 if ((ret
= (*cp_fn
) (os_handle
, e
->buffer
, src
, length
)) < 0) {
423 DBG_TRC(("A: A(%d) E(%08x) write error=%d", a
->adapter_nr
,
425 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
429 req
= (diva_um_idi_req_hdr_t
*)&e
->buffer
[0];
432 case DIVA_UM_IDI_GET_FEATURES
:{
433 DBG_LOG(("A(%d) get_features", a
->adapter_nr
));
435 diva_data_q_get_segment4write(&e
->data
))) {
436 DBG_ERR(("A(%d) get_features, no free buffer",
438 diva_os_leave_spin_lock(&adapter_lock
,
443 diva_user_mode_idi_adapter_features(a
, &(((diva_um_idi_ind_hdr_t
444 *) data
)->hdr
.features
));
445 ((diva_um_idi_ind_hdr_t
*) data
)->type
=
446 DIVA_UM_IDI_IND_FEATURES
;
447 ((diva_um_idi_ind_hdr_t
*) data
)->data_length
= 0;
448 diva_data_q_ack_segment4write(&e
->data
,
449 sizeof(diva_um_idi_ind_hdr_t
));
451 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
453 diva_os_wakeup_read(e
->os_context
);
457 case DIVA_UM_IDI_REQ
:
458 case DIVA_UM_IDI_REQ_MAN
:
459 case DIVA_UM_IDI_REQ_SIG
:
460 case DIVA_UM_IDI_REQ_NET
:
461 DBG_TRC(("A(%d) REQ(%02d)-(%02d)-(%08x)", a
->adapter_nr
,
462 req
->Req
, req
->ReqCh
,
463 req
->type
& DIVA_UM_IDI_REQ_TYPE_MASK
));
464 switch (process_idi_request(e
, req
)) {
466 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
469 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
470 diva_os_wakeup_read(e
->os_context
);
473 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
479 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "write");
483 DBG_TRC(("A(%d) E(%08x) write=%d", a
->adapter_nr
, e
, ret
));
488 /* --------------------------------------------------------------------------
490 -------------------------------------------------------------------------- */
491 static void diva_um_idi_xdi_callback(ENTITY
*entity
)
493 divas_um_idi_entity_t
*e
= DIVAS_CONTAINING_RECORD(entity
,
494 divas_um_idi_entity_t
,
496 diva_os_spin_lock_magic_t old_irql
;
499 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "xdi_callback");
501 if (e
->e
.complete
== 255) {
502 if (!(e
->status
& DIVA_UM_IDI_REMOVE_PENDING
)) {
503 diva_um_idi_stop_wdog(e
);
505 if ((call_wakeup
= process_idi_rc(e
, e
->e
.Rc
))) {
511 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "xdi_callback");
514 diva_os_wakeup_read(e
->os_context
);
515 diva_os_wakeup_close(e
->os_context
);
518 if (e
->status
& DIVA_UM_IDI_REMOVE_PENDING
) {
522 call_wakeup
= process_idi_ind(e
, e
->e
.Ind
);
525 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "xdi_callback");
527 diva_os_wakeup_read(e
->os_context
);
532 static int process_idi_request(divas_um_idi_entity_t
*e
,
533 const diva_um_idi_req_hdr_t
*req
)
536 byte Req
= (byte
) req
->Req
;
537 dword type
= req
->type
& DIVA_UM_IDI_REQ_TYPE_MASK
;
539 if (!e
->e
.Id
|| !e
->e
.callback
) { /* not assigned */
541 DBG_ERR(("A: A(%d) E(%08x) not assigned",
542 e
->adapter
->adapter_nr
, e
));
543 return (-1); /* NOT ASSIGNED */
546 case DIVA_UM_IDI_REQ_TYPE_MAN
:
548 DBG_TRC(("A(%d) E(%08x) assign MAN",
549 e
->adapter
->adapter_nr
, e
));
552 case DIVA_UM_IDI_REQ_TYPE_SIG
:
554 DBG_TRC(("A(%d) E(%08x) assign SIG",
555 e
->adapter
->adapter_nr
, e
));
558 case DIVA_UM_IDI_REQ_TYPE_NET
:
560 DBG_TRC(("A(%d) E(%08x) assign NET",
561 e
->adapter
->adapter_nr
, e
));
565 DBG_ERR(("A: A(%d) E(%08x) unknown type=%08x",
566 e
->adapter
->adapter_nr
, e
,
573 e
->e
.callback
= diva_um_idi_xdi_callback
;
578 e
->status
|= DIVA_UM_IDI_RC_PENDING
;
580 e
->e
.ReqCh
= (byte
) req
->ReqCh
;
581 e
->e
.X
->PLength
= (word
) req
->data_length
;
582 e
->e
.X
->P
= (byte
*)&req
[1]; /* Our buffer is safe */
584 DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",
585 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, e
->e
.Req
,
586 e
->e
.ReqCh
, e
->e
.X
->PLength
));
590 if (e
->adapter
&& e
->adapter
->d
.request
) {
591 diva_um_idi_start_wdog(e
);
592 (*(e
->adapter
->d
.request
)) (&e
->e
);
596 if (e
->e
.Rc
== OUT_OF_RESOURCES
) {
598 XDI has no entities more, call was not forwarded to the card,
599 no callback will be scheduled
601 DBG_ERR(("A: A(%d) E(%08x) XDI out of entities",
602 e
->adapter
->adapter_nr
, e
));
611 e
->e
.callback
= NULL
;
614 write_return_code(e
, ASSIGN_RC
| OUT_OF_RESOURCES
);
617 e
->status
|= DIVA_UM_IDI_ASSIGN_PENDING
;
624 static int process_idi_rc(divas_um_idi_entity_t
*e
, byte rc
)
626 DBG_TRC(("A(%d) E(%08x) rc(%02x-%02x-%02x)",
627 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, rc
, e
->e
.RcCh
));
629 if (e
->status
& DIVA_UM_IDI_ASSIGN_PENDING
) {
630 e
->status
&= ~DIVA_UM_IDI_ASSIGN_PENDING
;
631 if (rc
!= ASSIGN_OK
) {
632 DBG_ERR(("A: A(%d) E(%08x) ASSIGN failed",
633 e
->adapter
->adapter_nr
, e
));
634 e
->e
.callback
= NULL
;
648 if ((e
->e
.Req
== REMOVE
) && e
->e
.Id
&& (rc
== 0xff)) {
649 DBG_ERR(("A: A(%d) E(%08x) discard OK in REMOVE",
650 e
->adapter
->adapter_nr
, e
));
651 return (0); /* let us do it in the driver */
653 if ((e
->e
.Req
== REMOVE
) && (!e
->e
.Id
)) { /* REMOVE COMPLETE */
654 e
->e
.callback
= NULL
;
668 if ((e
->e
.Req
== REMOVE
) && (rc
!= 0xff)) { /* REMOVE FAILED */
669 DBG_ERR(("A: A(%d) E(%08x) REMOVE FAILED",
670 e
->adapter
->adapter_nr
, e
));
672 write_return_code(e
, rc
);
677 static int process_idi_ind(divas_um_idi_entity_t
*e
, byte ind
)
681 if (e
->e
.complete
!= 0x02) {
682 diva_um_idi_ind_hdr_t
*pind
=
683 (diva_um_idi_ind_hdr_t
*)
684 diva_data_q_get_segment4write(&e
->data
);
687 e
->e
.R
->P
= (byte
*)&pind
[1];
689 (word
) (diva_data_q_get_max_length(&e
->data
) -
691 DBG_TRC(("A(%d) E(%08x) ind_1(%02x-%02x-%02x)-[%d-%d]",
692 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, ind
,
693 e
->e
.IndCh
, e
->e
.RLength
,
697 DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-RNR",
698 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, ind
,
705 diva_um_idi_ind_hdr_t
*pind
=
706 (diva_um_idi_ind_hdr_t
*) (e
->e
.R
->P
);
708 DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-[%d]",
709 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, ind
,
710 e
->e
.IndCh
, e
->e
.R
->PLength
));
713 pind
->type
= DIVA_UM_IDI_IND
;
714 pind
->hdr
.ind
.Ind
= ind
;
715 pind
->hdr
.ind
.IndCh
= e
->e
.IndCh
;
716 pind
->data_length
= e
->e
.R
->PLength
;
717 diva_data_q_ack_segment4write(&e
->data
,
718 (int) (sizeof(*pind
) +
723 if ((e
->status
& DIVA_UM_IDI_RC_PENDING
) && !e
->rc
.count
) {
730 /* --------------------------------------------------------------------------
731 Write return code to the return code queue of entity
732 -------------------------------------------------------------------------- */
733 static int write_return_code(divas_um_idi_entity_t
*e
, byte rc
)
735 diva_um_idi_ind_hdr_t
*prc
;
738 (diva_um_idi_ind_hdr_t
*) diva_data_q_get_segment4write(&e
->rc
)))
740 DBG_ERR(("A: A(%d) E(%08x) rc(%02x) lost",
741 e
->adapter
->adapter_nr
, e
, rc
));
742 e
->status
&= ~DIVA_UM_IDI_RC_PENDING
;
746 prc
->type
= DIVA_UM_IDI_IND_RC
;
748 prc
->hdr
.rc
.RcCh
= e
->e
.RcCh
;
749 prc
->data_length
= 0;
750 diva_data_q_ack_segment4write(&e
->rc
, sizeof(*prc
));
755 /* --------------------------------------------------------------------------
756 Return amount of entries that can be bead from this entity or
757 -1 if adapter was removed
758 -------------------------------------------------------------------------- */
759 int diva_user_mode_idi_ind_ready(void *entity
, void *os_handle
)
761 divas_um_idi_entity_t
*e
;
762 diva_um_idi_adapter_t
*a
;
763 diva_os_spin_lock_magic_t old_irql
;
768 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "ind_ready");
769 e
= (divas_um_idi_entity_t
*) entity
;
772 if ((!a
) || (a
->status
& DIVA_UM_IDI_ADAPTER_REMOVED
)) {
776 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "ind_ready");
777 return (-1); /* adapter was removed */
779 if (e
->status
& DIVA_UM_IDI_REMOVED
) {
781 entity was removed as result of adapter removal
782 user should assign this entity again
784 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "ind_ready");
788 ret
= e
->rc
.count
+ e
->data
.count
;
790 if ((e
->status
& DIVA_UM_IDI_RC_PENDING
) && !e
->rc
.count
) {
794 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "ind_ready");
799 void *diva_um_id_get_os_context(void *entity
)
801 return (((divas_um_idi_entity_t
*) entity
)->os_context
);
804 int divas_um_idi_entity_assigned(void *entity
)
806 divas_um_idi_entity_t
*e
;
807 diva_um_idi_adapter_t
*a
;
809 diva_os_spin_lock_magic_t old_irql
;
811 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "assigned?");
814 e
= (divas_um_idi_entity_t
*) entity
;
815 if (!e
|| (!(a
= e
->adapter
)) ||
816 (e
->status
& DIVA_UM_IDI_REMOVED
) ||
817 (a
->status
& DIVA_UM_IDI_ADAPTER_REMOVED
)) {
818 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "assigned?");
822 e
->status
|= DIVA_UM_IDI_REMOVE_PENDING
;
824 ret
= (e
->e
.Id
|| e
->rc_count
825 || (e
->status
& DIVA_UM_IDI_ASSIGN_PENDING
));
827 DBG_TRC(("Id:%02x, rc_count:%d, status:%08x", e
->e
.Id
, e
->rc_count
,
830 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "assigned?");
835 int divas_um_idi_entity_start_remove(void *entity
)
837 divas_um_idi_entity_t
*e
;
838 diva_um_idi_adapter_t
*a
;
839 diva_os_spin_lock_magic_t old_irql
;
841 diva_os_enter_spin_lock(&adapter_lock
, &old_irql
, "start_remove");
843 e
= (divas_um_idi_entity_t
*) entity
;
844 if (!e
|| (!(a
= e
->adapter
)) ||
845 (e
->status
& DIVA_UM_IDI_REMOVED
) ||
846 (a
->status
& DIVA_UM_IDI_ADAPTER_REMOVED
)) {
847 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "start_remove");
855 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "start_remove");
861 Remove request was already pending, and arrived now
863 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "start_remove");
864 return (0); /* REMOVE was pending */
868 Now send remove request
875 DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",
876 e
->adapter
->adapter_nr
, e
, e
->e
.Id
, e
->e
.Req
,
877 e
->e
.ReqCh
, e
->e
.X
->PLength
));
880 (*(a
->d
.request
)) (&e
->e
);
882 diva_os_leave_spin_lock(&adapter_lock
, &old_irql
, "start_remove");