Changeset 160 for trunk/src/os2ahci/apm.c
- Timestamp:
- May 31, 2013, 2:03:41 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/apm.c
r157 r160 77 77 if (evt->ulParm2 >> 16 != APM_PWRSTATEREADY) { 78 78 /* we're suspending */ 79 apm_suspend();79 suspend(); 80 80 } 81 81 break; … … 84 84 case APM_CRITRESUMEEVENT: 85 85 /* we're resuming */ 86 apm_resume();86 resume(); 87 87 break; 88 88 … … 96 96 97 97 /****************************************************************************** 98 * APM suspend handler. In a nutshell, it'll turn of interrupts and flush all98 * Suspend handler. In a nutshell, it'll turn off interrupts and flush all 99 99 * write caches. 100 100 */ 101 void apm_suspend(void)101 void suspend(void) 102 102 { 103 103 int a; … … 107 107 108 108 if (suspended) return; 109 dprintf(" apm_suspend()\n");109 dprintf("suspend()\n"); 110 110 111 111 /* restart all ports with interrupts disabled */ … … 132 132 } 133 133 } 134 135 /* AHCI spec rev1.1 section 8.3.3: 136 * Software must disable interrupts prior to requesting a transition of the HBA to D3 state. 137 */ 138 writel(ai->mmio + HOST_CTL, readl(ai->mmio + HOST_CTL) & ~HOST_IRQ_EN); 139 readl(ai->mmio + HOST_CTL); /* flush */ 134 140 } 135 141 … … 137 143 init_complete = 0; 138 144 145 #if 0 139 146 /* restore BIOS configuration for each adapter and release the adapter */ 140 147 for (a = 0; a < ad_info_cnt; a++) { 141 148 ahci_restore_bios_config(ad_infos + a); 142 unlock_adapter(ad_infos + a); 143 } 149 } 150 #endif 151 152 /* TODO: put the device into the D3 state */ 144 153 145 154 suspended = 1; 146 dprintf(" apm_suspend() finished\n");147 } 148 149 /****************************************************************************** 150 * APM resume handler. All ports are restarted with interrupts enabled using155 dprintf("suspend() finished\n"); 156 } 157 158 /****************************************************************************** 159 * Resume handler. All ports are restarted with interrupts enabled using 151 160 * the same function as the IOCM_COMPLETE_INIT handler does. 152 161 */ 153 void apm_resume(void)162 void resume(void) 154 163 { 155 164 int a; 156 165 157 166 if (!suspended) return; 158 dprintf("apm_resume()\n"); 167 dprintf("resume()\n"); 168 169 /* TODO: put the device into the D0 state */ 159 170 160 171 for (a = 0; a < ad_info_cnt; a++) { … … 165 176 * done to get the adapter and its ports up and running. 166 177 */ 167 lock_adapter(ai);168 178 ahci_complete_init(ai); 169 179 } … … 178 188 179 189 suspended = 0; 180 dprintf("apm_resume() finished\n"); 181 } 190 dprintf("resume() finished\n"); 191 } 192 193 /****************************************************************************** 194 * This is the kernel exit handler for panics and traps. 195 * Assume the system is trashed and do the absolute minimum necessary 196 * to put the adapters into a state so that the BIOS can operate the 197 * adapters. We never need to recover from this as the system will be rebooted. 198 */ 199 void shutdown_driver(void) 200 { 201 int a; 202 int p; 203 u16 i; 204 u32 tmp; 205 //int d; 206 207 dprintf("shutdown_driver() enter\n"); 208 209 for (a = 0; a < ad_info_cnt; a++) { 210 AD_INFO *ai = ad_infos + a; 211 212 /* Try to be nice. Wait 50ms for adapter to go not busy. 213 * If it doesn't go not busy in that time, too bad. Stop it anyway. 214 */ 215 for (i=0; i<50000 && ai->busy; i++) udelay(1000); 216 217 for (p = 0; p <= ai->port_max; p++) { 218 u8 _far *port_mmio = port_base(ai, p); 219 220 /* Wait up to 50ms for port to go not busy. Again stop it 221 * anyway if it doesn't go not busy in that time. 222 */ 223 for (i=0; i<50000 && ahci_port_busy(ai, p); i++) udelay(1000); 224 225 /* stop port */ 226 writel(port_mmio + PORT_IRQ_MASK, 0); /* disable port interrupts */ 227 writel(port_mmio + PORT_CMD, readl(port_mmio + PORT_CMD) & ~PORT_CMD_FIS_RX); /* disable FIS reception */ 228 while (readl(port_mmio + PORT_CMD) & PORT_CMD_FIS_ON); /* wait for it to stop */ 229 writel(port_mmio + PORT_CMD, readl(port_mmio + PORT_CMD) & ~PORT_CMD_START); /* set port to idle */ 230 while (readl(port_mmio + PORT_CMD) & PORT_CMD_LIST_ON); /* wait for it to stop */ 231 232 /* clear any pending port IRQs */ 233 tmp = readl(port_mmio + PORT_IRQ_STAT); 234 if (tmp) writel(port_mmio + PORT_IRQ_STAT, tmp); 235 writel(ai->mmio + HOST_IRQ_STAT, 1UL << p); 236 237 /* reset PxSACT register (tagged command queues, not reset by COMRESET) */ 238 writel(port_mmio + PORT_SCR_ACT, 0); 239 readl(port_mmio + PORT_SCR_ACT); /* flush */ 240 241 #if 0 242 ahci_start_port(ai, p, 0); 243 244 /* flush cache on all attached devices */ 245 for (d = 0; d <= ai->ports[p].dev_max; d++) { 246 if (ai->ports[p].devs[d].present) { 247 ahci_flush_cache(ai, p, d); 248 } 249 } 250 #endif 251 } 252 } 253 254 init_complete = 0; 255 256 /* restore BIOS configuration for each adapter */ 257 for (a = 0; a < ad_info_cnt; a++) { 258 ahci_restore_bios_config(ad_infos + a); 259 } 260 261 dprintf("shutdown_driver() finished\n"); 262 } 263
Note:
See TracChangeset
for help on using the changeset viewer.