📄 mediabay.c
字号:
feature_set(bay->dev_node, FEATURE_IDE1_enable); udelay(10); feature_set(bay->dev_node, FEATURE_IDE1_reset); } printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which); break; case MB_FD: case MB_FD1: feature_set(bay->dev_node, FEATURE_Mediabay_floppy_enable); feature_set(bay->dev_node, FEATURE_SWIM3_enable); printk(KERN_INFO "media bay %d contains a floppy disk drive\n", which); break; case MB_NO: break; default: printk(KERN_INFO "media bay %d contains an unknown device (%d)\n", which, id); break; }}int __pmaccheck_media_bay(struct device_node *which_bay, int what){#ifdef CONFIG_BLK_DEV_IDE int i; for (i=0; i<media_bay_count; i++) if (which_bay == media_bays[i].dev_node) { if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) return 0; media_bays[i].cd_index = -1; return -EINVAL; }#endif /* CONFIG_BLK_DEV_IDE */ return -ENODEV;}int __pmaccheck_media_bay_by_base(unsigned long base, int what){#ifdef CONFIG_BLK_DEV_IDE int i; for (i=0; i<media_bay_count; i++) if (base == media_bays[i].cd_base) { if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) return 0; media_bays[i].cd_index = -1; return -EINVAL; } #endif return -ENODEV;}int __pmacmedia_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, int irq, int index){#ifdef CONFIG_BLK_DEV_IDE int i; for (i=0; i<media_bay_count; i++) if (which_bay == media_bays[i].dev_node) { int timeout = 5000; media_bays[i].cd_base = base; media_bays[i].cd_irq = irq; if ((MB_CD != media_bays[i].content_id) || media_bays[i].state != mb_up) return 0; printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i); do { if (MB_IDE_READY(i)) { media_bays[i].cd_index = index; return 0; } mdelay(1); } while(--timeout); printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); return -ENODEV; } #endif return -ENODEV;}static void __pmacmedia_bay_step(int i){ volatile struct media_bay_info* bay = &media_bays[i]; /* We don't poll when powering down */ if (bay->state != mb_powering_down) poll_media_bay(i); /* If timer expired or polling IDE busy, run state machine */ if ((bay->state != mb_ide_waiting) && (bay->timer != 0) && ((--bay->timer) != 0)) return; switch(bay->state) { case mb_powering_up: set_media_bay(i, bay->last_value); bay->timer = MS_TO_HZ(MB_RESET_DELAY); bay->state = mb_enabling_bay; MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id); break; case mb_enabling_bay: feature_clear(bay->dev_node, FEATURE_Mediabay_reset); bay->timer = MS_TO_HZ(MB_SETUP_DELAY); bay->state = mb_resetting; MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id); break; case mb_resetting: if (bay->content_id != MB_CD) { MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); bay->state = mb_up; break; }#ifdef CONFIG_BLK_DEV_IDE MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); if (bay->pismo) feature_clear(bay->dev_node, FEATURE_IDE0_reset); else feature_clear(bay->dev_node, FEATURE_IDE1_reset); bay->timer = MS_TO_HZ(MB_IDE_WAIT); bay->state = mb_ide_resetting;#else printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i); set_mb_power(i, 0);#endif // #ifdef CONFIG_BLK_DEV_IDE break; #ifdef CONFIG_BLK_DEV_IDE case mb_ide_resetting: bay->timer = MS_TO_HZ(MB_IDE_TIMEOUT); bay->state = mb_ide_waiting; MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id); break; case mb_ide_waiting: if (bay->cd_base == 0) { bay->timer = 0; bay->state = mb_up; MBDBG("mediabay%d: up before IDE init\n", i); break; } else if (MB_IDE_READY(i)) { bay->timer = 0; bay->state = mb_up; if (bay->cd_index < 0) { pmu_suspend(); bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq); pmu_resume(); } if (bay->cd_index == -1) { /* We eventually do a retry */ bay->cd_retry++; printk("IDE register error\n"); set_mb_power(i, 0); } else { printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index); MBDBG("mediabay %d IDE ready\n", i); } break; } if (bay->timer == 0) { printk("\nIDE Timeout in bay %d !\n", i); MBDBG("mediabay%d: nIDE Timeout !\n", i); set_mb_power(i, 0); } break;#endif // #ifdef CONFIG_BLK_DEV_IDE case mb_powering_down: bay->state = mb_empty;#ifdef CONFIG_BLK_DEV_IDE if (bay->cd_index >= 0) { printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, bay->cd_index); ide_unregister(bay->cd_index); bay->cd_index = -1; } if (bay->cd_retry) { if (bay->cd_retry > MAX_CD_RETRIES) { /* Should add an error sound (sort of beep in dmasound) */ printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i); } else { /* Force a new power down/up sequence */ bay->content_id = MB_NO; } }#endif MBDBG("mediabay%d: end of power down\n", i); break; }}/* * This procedure runs as a kernel thread to poll the media bay * once each tick and register and unregister the IDE interface * with the IDE driver. It needs to be a thread because * ide_register can't be called from interrupt context. */int __pmacmedia_bay_task(void *x){ int i; strcpy(current->comm, "media-bay");#ifdef MB_IGNORE_SIGNALS sigfillset(¤t->blocked);#endif for (;;) { for (i = 0; i < media_bay_count; ++i) media_bay_step(i); current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); if (signal_pending(current)) return 0; }}void __pmacpoll_media_bay(int which){ volatile struct media_bay_info* bay = &media_bays[which]; int id = mb_content(bay); if (id == bay->last_value) { if (id != bay->content_id && ++bay->value_count >= MS_TO_HZ(MB_STABLE_DELAY)) { /* If the device type changes without going thru "MB_NO", we force a pass by "MB_NO" to make sure things are properly reset */ if ((id != MB_NO) && (bay->content_id != MB_NO)) { id = MB_NO; MBDBG("mediabay%d: forcing MB_NO\n", which); } MBDBG("mediabay%d: switching to %d\n", which, id); set_mb_power(which, id != MB_NO); bay->content_id = id; if (id == MB_NO) {#ifdef CONFIG_BLK_DEV_IDE bay->cd_retry = 0;#endif printk(KERN_INFO "media bay %d is empty\n", which); } } } else { bay->last_value = id; bay->value_count = 0; }}#ifdef CONFIG_PMAC_PBOOK/* * notify clients before sleep and reset bus afterwards */int __pmacmb_notify_sleep(struct pmu_sleep_notifier *self, int when){ volatile struct media_bay_info* bay; int i; switch (when) { case PBOOK_SLEEP_REQUEST: case PBOOK_SLEEP_REJECT: break; case PBOOK_SLEEP_NOW: for (i=0; i<media_bay_count; i++) { bay = &media_bays[i]; set_mb_power(i, 0); mdelay(10); } break; case PBOOK_WAKE: for (i=0; i<media_bay_count; i++) { bay = &media_bays[i]; /* We re-enable the bay using it's previous content only if it did not change. Note those bozo timings, they seem to help the 3400 get it right. */ /* Force MB power to 0 */ set_mb_power(i, 0); mdelay(MB_POWER_DELAY); if (!bay->pismo) out_8(&bay->addr->contents, 0x70); mdelay(MB_STABLE_DELAY); if (mb_content(bay) != bay->content_id) continue; set_mb_power(i, 1); bay->last_value = bay->content_id; bay->value_count = MS_TO_HZ(MB_STABLE_DELAY); bay->timer = MS_TO_HZ(MB_POWER_DELAY);#ifdef CONFIG_BLK_DEV_IDE bay->cd_retry = 0;#endif do { mdelay(1000/HZ); media_bay_step(i); } while((media_bays[i].state != mb_empty) && (media_bays[i].state != mb_up)); } break; } return PBOOK_SLEEP_OK;}#endif /* CONFIG_PMAC_PBOOK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -