diff -ruP -X ../ignorediff linux-2.4.8-ben0-benh20010814.pre/drivers/macintosh/mediabay.c linux-2.4.8-ben0-benh20010814-JPG1/drivers/macintosh/mediabay.c --- linux-2.4.8-ben0-benh20010814.pre/drivers/macintosh/mediabay.c Tue Aug 7 07:48:53 2001 +++ linux-2.4.8-ben0-benh20010814-JPG1/drivers/macintosh/mediabay.c Thu Aug 16 02:01:43 2001 @@ -599,6 +599,7 @@ bay = &media_bays[i]; set_mb_power(i, 0); mdelay(10); + feature_clear(bay->dev_node, FEATURE_IOBUS_enable); } break; case PBOOK_WAKE: @@ -609,6 +610,7 @@ they seem to help the 3400 get it right. */ /* Force MB power to 0 */ + feature_set(bay->dev_node, FEATURE_IOBUS_enable); set_mb_power(i, 0); mdelay(MB_POWER_DELAY); if (!bay->pismo) diff -ruP -X ../ignorediff linux-2.4.8-ben0-benh20010814.pre/drivers/scsi/mesh.c linux-2.4.8-ben0-benh20010814-JPG1/drivers/scsi/mesh.c --- linux-2.4.8-ben0-benh20010814.pre/drivers/scsi/mesh.c Sat Aug 11 05:35:40 2001 +++ linux-2.4.8-ben0-benh20010814-JPG1/drivers/scsi/mesh.c Thu Aug 16 02:41:33 2001 @@ -29,6 +29,10 @@ #include #include #include +#ifdef CONFIG_PMAC_PBOOK +#include +#include +#endif #include "scsi.h" #include "hosts.h" @@ -122,6 +126,14 @@ #endif }; +#ifdef CONFIG_PMAC_PBOOK +static int mesh_notify_sleep(struct pmu_sleep_notifier *self, int when); +static struct pmu_sleep_notifier mesh_sleep_notifier = { + mesh_notify_sleep, + SLEEP_LEVEL_BLOCK, +}; +#endif + struct mesh_state { volatile struct mesh_regs *mesh; int meshintr; @@ -151,6 +163,7 @@ struct mesh_target tgts[8]; void *dma_cmd_space; struct device_node *ofnode; + unsigned char *mio_base; #ifndef MESH_NEW_STYLE_EH Scsi_Cmnd *completed_q; Scsi_Cmnd *completed_qtail; @@ -210,6 +223,7 @@ static void halt_dma(struct mesh_state *); static int data_goes_out(Scsi_Cmnd *); static void do_abort(struct mesh_state *ms); +static void set_mesh_power(struct mesh_state *ms, int state); static struct notifier_block mesh_notifier = { mesh_notify_reboot, @@ -309,9 +323,25 @@ if (mesh_sync_period < minper) mesh_sync_period = minper; - feature_set(mesh, FEATURE_MESH_enable); - mdelay(200); - +#if 1 + { + struct device_node *mio; + ms->mio_base = 0; + for (mio = ms->ofnode->parent; mio; mio = mio->parent) + if (strcmp(mio->name, "mac-io") == 0 && mio->n_addrs > 0) + break; + if (mio) + ms->mio_base = (unsigned char *) + ioremap(mio->addrs[0].address, 0x40); + } + if(ms->mio_base) + set_mesh_power(ms, 1); + else +#endif + { + feature_set(mesh, FEATURE_MESH_enable); + mdelay(200); + } mesh_init(ms); if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) { @@ -321,8 +351,12 @@ ++nmeshes; } - if ((_machine == _MACH_Pmac) && (nmeshes > 0)) + if ((_machine == _MACH_Pmac) && (nmeshes > 0)){ +#ifdef CONFIG_PMAC_PBOOK + pmu_register_sleep_notifier(&mesh_sleep_notifier); +#endif /* CONFIG_PMAC_PBOOK */ register_reboot_notifier(&mesh_notifier); + } return nmeshes; } @@ -338,11 +372,70 @@ iounmap((void *) ms->mesh); if (ms->dma) iounmap((void *) ms->dma); + if (ms->mio_base) + iounmap((void *) ms->mio_base); kfree(ms->dma_cmd_space); free_irq(ms->meshintr, ms); feature_clear(ms->ofnode, FEATURE_MESH_enable); return 0; } + +static void +set_mesh_power(struct mesh_state *ms, int state) +{ + if (_machine != _MACH_Pmac || ms->mio_base == 0) + return; + + if (state) { + feature_set(ms->ofnode, FEATURE_MESH_enable); + /* This seems to enable the termination power. strangely + this doesn't fully agree with OF, but with MacOS */ + if (ms->mio_base) + out_8(ms->mio_base + 0x36, 0x70); + mdelay(200); + } else { + feature_clear(ms->ofnode, FEATURE_MESH_enable); + if (ms->mio_base) + out_8(ms->mio_base + 0x36, 0x34); + mdelay(10); + } +} + +#ifdef CONFIG_PMAC_PBOOK +/* + * notify clients before sleep and reset bus afterwards + */ +int +mesh_notify_sleep(struct pmu_sleep_notifier *self, int when) +{ + struct mesh_state *ms; + + switch (when) { + case PBOOK_SLEEP_REQUEST: + /* XXX We should wait for current transactions and queue + * new ones that would be posted beyond this point + */ + break; + case PBOOK_SLEEP_REJECT: + break; + + case PBOOK_SLEEP_NOW: + for (ms = all_meshes; ms != 0; ms = ms->next) { + disable_irq(ms->meshintr); + set_mesh_power(ms, 0); + } + break; + case PBOOK_WAKE: + for (ms = all_meshes; ms != 0; ms = ms->next) { + set_mesh_power(ms, 1); + mesh_init(ms); + enable_irq(ms->meshintr); + } + break; + } + return PBOOK_SLEEP_OK; +} +#endif /* CONFIG_PMAC_PBOOK */ int mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))