H A D | hil_mlc.c | 87 static void hil_mlc_clear_di_map(hil_mlc *mlc, int val) hil_mlc_clear_di_map() argument 92 mlc->di_map[j] = -1; hil_mlc_clear_di_map() 95 static void hil_mlc_clear_di_scratch(hil_mlc *mlc) hil_mlc_clear_di_scratch() argument 97 memset(&mlc->di_scratch, 0, sizeof(mlc->di_scratch)); hil_mlc_clear_di_scratch() 100 static void hil_mlc_copy_di_scratch(hil_mlc *mlc, int idx) hil_mlc_copy_di_scratch() argument 102 memcpy(&mlc->di[idx], &mlc->di_scratch, sizeof(mlc->di_scratch)); hil_mlc_copy_di_scratch() 105 static int hil_mlc_match_di_scratch(hil_mlc *mlc) hil_mlc_match_di_scratch() argument 114 if (mlc->di_map[j] == idx) hil_mlc_match_di_scratch() 120 if (!memcmp(mlc->di + idx, &mlc->di_scratch, hil_mlc_match_di_scratch() 121 sizeof(mlc->di_scratch))) hil_mlc_match_di_scratch() 127 static int hil_mlc_find_free_di(hil_mlc *mlc) hil_mlc_find_free_di() argument 138 if (mlc->di_map[j] == idx) hil_mlc_find_free_di() 148 static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) hil_mlc_clean_serio_map() argument 156 if (mlc->di_map[j] == idx) hil_mlc_clean_serio_map() 160 mlc->serio_map[idx].di_revmap = -1; hil_mlc_clean_serio_map() 164 static void hil_mlc_send_polls(hil_mlc *mlc) hil_mlc_send_polls() argument 171 did = (mlc->ipacket[0] & HIL_PKT_ADDR_MASK) >> 8; hil_mlc_send_polls() 172 serio = did ? mlc->serio[mlc->di_map[did - 1]] : NULL; hil_mlc_send_polls() 175 while (mlc->icount < 15 - i) { hil_mlc_send_polls() 178 p = mlc->ipacket[i]; hil_mlc_send_polls() 188 serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; hil_mlc_send_polls() 240 static int hilse_match(hil_mlc *mlc, int unused) hilse_match() argument 244 rc = hil_mlc_match_di_scratch(mlc); hilse_match() 246 rc = hil_mlc_find_free_di(mlc); hilse_match() 253 hil_mlc_copy_di_scratch(mlc, rc); hilse_match() 254 mlc->di_map[mlc->ddi] = rc; hilse_match() 255 mlc->serio_map[rc].di_revmap = mlc->ddi; hilse_match() 256 hil_mlc_clean_serio_map(mlc); hilse_match() 257 serio_rescan(mlc->serio[rc]); hilse_match() 261 mlc->di_map[mlc->ddi] = rc; hilse_match() 265 mlc->serio_map[rc].di_revmap = mlc->ddi; hilse_match() 266 hil_mlc_clean_serio_map(mlc); hilse_match() 275 static int hilse_init_lcv(hil_mlc *mlc, int unused) hilse_init_lcv() argument 281 if (mlc->lcv && (tv.tv_sec - mlc->lcv_tv.tv_sec) < 5) hilse_init_lcv() 284 mlc->lcv_tv = tv; hilse_init_lcv() 285 mlc->lcv = 0; hilse_init_lcv() 290 static int hilse_inc_lcv(hil_mlc *mlc, int lim) hilse_inc_lcv() argument 292 return mlc->lcv++ >= lim ? -1 : 0; hilse_inc_lcv() 296 static int hilse_set_lcv(hil_mlc *mlc, int val) 298 mlc->lcv = val; 305 static int hilse_set_ddi(hil_mlc *mlc, int val) hilse_set_ddi() argument 307 mlc->ddi = val; hilse_set_ddi() 308 hil_mlc_clear_di_map(mlc, val + 1); hilse_set_ddi() 313 static int hilse_dec_ddi(hil_mlc *mlc, int unused) hilse_dec_ddi() argument 315 mlc->ddi--; hilse_dec_ddi() 316 if (mlc->ddi <= -1) { hilse_dec_ddi() 317 mlc->ddi = -1; hilse_dec_ddi() 318 hil_mlc_clear_di_map(mlc, 0); hilse_dec_ddi() 321 hil_mlc_clear_di_map(mlc, mlc->ddi + 1); hilse_dec_ddi() 326 static int hilse_inc_ddi(hil_mlc *mlc, int unused) hilse_inc_ddi() argument 328 BUG_ON(mlc->ddi >= 6); hilse_inc_ddi() 329 mlc->ddi++; hilse_inc_ddi() 334 static int hilse_take_idd(hil_mlc *mlc, int unused) hilse_take_idd() argument 343 if (mlc->ipacket[0] & HIL_PKT_CMD) hilse_take_idd() 348 if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == hilse_take_idd() 349 (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && hilse_take_idd() 350 (mlc->ipacket[i] & HIL_PKT_CMD) && hilse_take_idd() 351 ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) hilse_take_idd() 359 if (mlc->ipacket[i]) hilse_take_idd() 366 mlc->di_scratch.idd[i] = hilse_take_idd() 367 mlc->ipacket[i] & HIL_PKT_DATA_MASK; hilse_take_idd() 370 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) hilse_take_idd() 373 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) hilse_take_idd() 379 mlc->ddi--; hilse_take_idd() 384 static int hilse_take_rsc(hil_mlc *mlc, int unused) hilse_take_rsc() argument 389 mlc->di_scratch.rsc[i] = hilse_take_rsc() 390 mlc->ipacket[i] & HIL_PKT_DATA_MASK; hilse_take_rsc() 393 if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) hilse_take_rsc() 399 static int hilse_take_exd(hil_mlc *mlc, int unused) hilse_take_exd() argument 404 mlc->di_scratch.exd[i] = hilse_take_exd() 405 mlc->ipacket[i] & HIL_PKT_DATA_MASK; hilse_take_exd() 408 if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) hilse_take_exd() 414 static int hilse_take_rnm(hil_mlc *mlc, int unused) hilse_take_rnm() argument 419 mlc->di_scratch.rnm[i] = hilse_take_rnm() 420 mlc->ipacket[i] & HIL_PKT_DATA_MASK; hilse_take_rnm() 423 mlc->di_scratch.rnm); hilse_take_rnm() 428 static int hilse_operate(hil_mlc *mlc, int repoll) hilse_operate() argument 431 if (mlc->opercnt == 0) hilse_operate() 433 mlc->opercnt = 1; hilse_operate() 435 hil_mlc_send_polls(mlc); hilse_operate() 440 mlc->opercnt = 0; hilse_operate() 585 static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) hilse_setup_input() argument 590 mlc->imatch = node->object.packet; hilse_setup_input() 591 mlc->imatch |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); hilse_setup_input() 594 mlc->imatch = node->object.packet; hilse_setup_input() 595 mlc->imatch |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); hilse_setup_input() 598 mlc->imatch = node->object.packet; hilse_setup_input() 601 mlc->imatch = 0; hilse_setup_input() 606 mlc->istarted = 1; hilse_setup_input() 607 mlc->intimeout = node->arg; hilse_setup_input() 608 do_gettimeofday(&(mlc->instart)); hilse_setup_input() 609 mlc->icount = 15; hilse_setup_input() 610 memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); hilse_setup_input() 611 BUG_ON(down_trylock(&mlc->isem)); hilse_setup_input() 619 static int hilse_donode(hil_mlc *mlc) hilse_donode() argument 627 if (mlc->seidx && mlc->seidx != seidx && hilse_donode() 628 mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { hilse_donode() 629 printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); hilse_donode() 633 seidx = mlc->seidx; hilse_donode() 635 node = hil_mlc_se + mlc->seidx; hilse_donode() 643 rc = node->object.func(mlc, node->arg); hilse_donode() 655 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 656 rc = mlc->in(mlc, node->arg); hilse_donode() 660 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 669 mlc->istarted = 0; hilse_donode() 670 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 674 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 676 pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); hilse_donode() 680 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 682 pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); hilse_donode() 686 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 689 if (!mlc->istarted) { hilse_donode() 692 hilse_setup_input(mlc, node + 1); hilse_donode() 695 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 697 if (down_trylock(&mlc->osem)) { hilse_donode() 701 up(&mlc->osem); hilse_donode() 703 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 704 if (!mlc->ostarted) { hilse_donode() 705 mlc->ostarted = 1; hilse_donode() 706 mlc->opacket = pack; hilse_donode() 707 mlc->out(mlc); hilse_donode() 709 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 712 mlc->ostarted = 0; hilse_donode() 713 do_gettimeofday(&(mlc->instart)); hilse_donode() 714 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 719 write_lock_irqsave(&mlc->lock, flags); hilse_donode() 720 nextidx = mlc->cts(mlc) ? node->bad : node->good; hilse_donode() 721 write_unlock_irqrestore(&mlc->lock, flags); hilse_donode() 740 tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); hilse_donode() 741 tv.tv_usec -= mlc->instart.tv_usec; hilse_donode() 742 if (tv.tv_usec >= mlc->intimeout) goto sched; hilse_donode() 743 tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC; hilse_donode() 753 mlc->seidx += nextidx & HILSEN_MASK; hilse_donode() 755 mlc->seidx -= nextidx & HILSEN_MASK; hilse_donode() 757 mlc->seidx = nextidx & HILSEN_MASK; hilse_donode() 772 struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); hil_mlcs_process() local 773 while (hilse_donode(mlc) == 0) { hil_mlcs_process() 775 if (mlc->seidx != 41 && hil_mlcs_process() 776 mlc->seidx != 42 && hil_mlcs_process() 777 mlc->seidx != 43) hil_mlcs_process() 801 struct hil_mlc *mlc; hil_mlc_serio_write() local 808 mlc = map->mlc; hil_mlc_serio_write() 809 BUG_ON(mlc == NULL); hil_mlc_serio_write() 811 mlc->serio_opacket[map->didx] |= hil_mlc_serio_write() 812 ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); hil_mlc_serio_write() 814 if (mlc->serio_oidx[map->didx] >= 3) { hil_mlc_serio_write() 816 if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) hil_mlc_serio_write() 818 switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { hil_mlc_serio_write() 820 idx = mlc->di[map->didx].idd; hil_mlc_serio_write() 823 idx = mlc->di[map->didx].rsc; hil_mlc_serio_write() 826 idx = mlc->di[map->didx].exd; hil_mlc_serio_write() 829 idx = mlc->di[map->didx].rnm; hil_mlc_serio_write() 834 mlc->serio_oidx[map->didx] = 0; hil_mlc_serio_write() 835 mlc->serio_opacket[map->didx] = 0; hil_mlc_serio_write() 838 mlc->serio_oidx[map->didx]++; hil_mlc_serio_write() 860 mlc->serio_oidx[map->didx] = 0; hil_mlc_serio_write() 861 mlc->serio_opacket[map->didx] = 0; hil_mlc_serio_write() 869 struct hil_mlc *mlc; hil_mlc_serio_open() local 877 mlc = map->mlc; hil_mlc_serio_open() 878 BUG_ON(mlc == NULL); hil_mlc_serio_open() 886 struct hil_mlc *mlc; hil_mlc_serio_close() local 891 mlc = map->mlc; hil_mlc_serio_close() 892 BUG_ON(mlc == NULL); hil_mlc_serio_close() 906 int hil_mlc_register(hil_mlc *mlc) hil_mlc_register() argument 911 BUG_ON(mlc == NULL); hil_mlc_register() 913 mlc->istarted = 0; hil_mlc_register() 914 mlc->ostarted = 0; hil_mlc_register() 916 rwlock_init(&mlc->lock); hil_mlc_register() 917 sema_init(&mlc->osem, 1); hil_mlc_register() 919 sema_init(&mlc->isem, 1); hil_mlc_register() 920 mlc->icount = -1; hil_mlc_register() 921 mlc->imatch = 0; hil_mlc_register() 923 mlc->opercnt = 0; hil_mlc_register() 925 sema_init(&(mlc->csem), 0); hil_mlc_register() 927 hil_mlc_clear_di_scratch(mlc); hil_mlc_register() 928 hil_mlc_clear_di_map(mlc, 0); hil_mlc_register() 931 hil_mlc_copy_di_scratch(mlc, i); hil_mlc_register() 933 mlc->serio[i] = mlc_serio; hil_mlc_register() 934 if (!mlc->serio[i]) { hil_mlc_register() 936 kfree(mlc->serio[i]); hil_mlc_register() 946 mlc_serio->port_data = &(mlc->serio_map[i]); hil_mlc_register() 947 mlc->serio_map[i].mlc = mlc; hil_mlc_register() 948 mlc->serio_map[i].didx = i; hil_mlc_register() 949 mlc->serio_map[i].di_revmap = -1; hil_mlc_register() 950 mlc->serio_opacket[i] = 0; hil_mlc_register() 951 mlc->serio_oidx[i] = 0; hil_mlc_register() 955 mlc->tasklet = &hil_mlcs_tasklet; hil_mlc_register() 958 list_add_tail(&mlc->list, &hil_mlcs); hil_mlc_register() 959 mlc->seidx = HILSEN_START; hil_mlc_register() 966 int hil_mlc_unregister(hil_mlc *mlc) hil_mlc_unregister() argument 972 BUG_ON(mlc == NULL); hil_mlc_unregister() 976 if (list_entry(tmp, hil_mlc, list) == mlc) hil_mlc_unregister() 989 serio_unregister_port(mlc->serio[i]); hil_mlc_unregister() 990 mlc->serio[i] = NULL; hil_mlc_unregister()
|