void bcom_set_initiator(int task, int initiator) { int i; int num_descs; u32 *desc; int next_drd_has_initiator; bcom_set_tcr_initiator(task, initiator); /* Just setting tcr is apparently not enough due to some problem */ /* with it. So we just go thru all the microcode and replace in */ /* the DRD directly */ desc = bcom_task_desc(task); next_drd_has_initiator = 1; num_descs = bcom_task_num_descs(task); for (i=0; i<num_descs; i++, desc++) { if (!bcom_desc_is_drd(*desc)) continue; if (next_drd_has_initiator) if (bcom_desc_initiator(*desc) != BCOM_INITIATOR_ALWAYS) bcom_set_desc_initiator(desc, initiator); next_drd_has_initiator = !bcom_drd_is_extended(*desc); } }
/* This is an ugly hack, but at least it's only done once at initialization */ static u32 *self_modified_drd(int tasknum) { u32 *desc; int num_descs; int drd_count; int i; num_descs = bcom_task_num_descs(tasknum); desc = bcom_task_desc(tasknum) + num_descs - 1; drd_count = 0; for (i=0; i<num_descs; i++, desc--) if (bcom_desc_is_drd(*desc) && ++drd_count == 3) break; return desc; }