Changeset 8 for trunk/src/ctxhook.c
- Timestamp:
- Sep 10, 2010, 11:30:39 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ctxhook.c
r4 r8 82 82 void restart_ctxhook(ULONG parm) 83 83 { 84 IORB_QUEUE done_queue; 84 85 AD_INFO *ai; 85 86 IORBH _far *problem_iorb; … … 92 93 int a; 93 94 int p; 94 int d;95 95 96 96 dprintf("restart_ctxhook() started\n"); 97 memset(&done_queue, 0x00, sizeof(done_queue)); 98 97 99 spin_lock(drv_lock); 98 100 … … 108 110 for (p = 0; p <= ai->port_max; p++) { 109 111 if (ports_to_restart[a] & (1UL << p)) { 112 ports_to_restart[a] &= ~(1UL << p); 110 113 111 114 /* restart this port */ 112 ports_to_restart[a] &= ~(1UL << p);113 115 port_mmio = port_base(ai, p); 114 116 problem_iorb = NULL; … … 124 126 if (aws->queued_hw) { 125 127 if (ai->ports[p].ncq_cmds != 0) { 128 /* NCQ commands active; force non-NCQ mode and trigger port reset */ 129 aws->no_ncq = 1; 126 130 need_reset = 1; 127 131 } else if (aws->cmd_slot == ccs) { … … 129 133 problem_iorb = iorb; 130 134 } 131 132 /* requeue this command with the 'no_ncq' flag set */ 133 aws_free(aws); 134 memset(&iorb->ADDWorkSpace, sizeof(iorb->ADDWorkSpace), 0x00); 135 aws->no_ncq = 1; 135 iorb_requeue(iorb); 136 136 137 137 /* remove requeued command from the issued command bitmaps */ … … 166 166 ai->busy = 0; 167 167 168 /* reset port status */ 169 ai->ports[p].cmd_slot = 0; 168 /* reset internal port status */ 170 169 ai->ports[p].ncq_cmds = 0; 171 170 ai->ports[p].reg_cmds = 0; 172 173 if (!need_reset && problem_iorb != NULL) { 174 /* request sense data for the failing command in cmd slot #0 */ 175 ADD_WORKSPACE _far *aws = add_workspace(problem_iorb); 176 aws->processing = 1; 177 aws->queued_hw = 1; 178 d = iorb_unit_device(problem_iorb); 179 if (ai->ports[p].devs[d].atapi) { 180 atapi_req_sense(problem_iorb, 0); 171 ai->ports[p].cmd_slot = 0; 172 173 if (problem_iorb != NULL) { 174 /* get details about the error that caused this IORB to fail */ 175 if (need_reset) { 176 /* no way to retrieve error details after a reset */ 177 iorb_seterr(problem_iorb, IOERR_DEVICE_NONSPECIFIC); 178 iorb_queue_del(&ai->ports[p].iorb_queue, problem_iorb); 179 iorb_queue_add(&done_queue, problem_iorb); 180 181 181 } else { 182 ata_req_sense(problem_iorb, 0); 182 /* get sense information */ 183 ADD_WORKSPACE _far *aws = add_workspace(problem_iorb); 184 int d = iorb_unit_device(problem_iorb); 185 int (*req_sense)(IORBH _far *, int) = 186 (ai->ports[p].devs[d].atapi) ? atapi_req_sense : ata_req_sense; 187 188 aws->processing = 1; 189 aws->queued_hw = 1; 190 191 if (req_sense(problem_iorb, 0) == 0) { 192 /* execute request sense on slot #0 before anything else comes along */ 193 ai->ports[p].reg_cmds = 1; 194 writel(port_mmio + PORT_CMD_ISSUE, 1); 195 readl(port_mmio); /* flush */ 196 197 } else { 198 /* IORB is expected to contain the error code; just move to done queue */ 199 iorb_queue_del(&ai->ports[p].iorb_queue, problem_iorb); 200 iorb_queue_add(&done_queue, problem_iorb); 201 } 183 202 } 184 ai->ports[p].reg_cmds = 1;185 writel(port_mmio + PORT_CMD_ISSUE, 1);186 readl(port_mmio); /* flush */187 203 } 188 204 } … … 190 206 } 191 207 208 spin_unlock(drv_lock); 209 210 /* call notification routine on all IORBs which have completed */ 211 for (iorb = done_queue.root; iorb != NULL; iorb = next) { 212 next = iorb->pNxtIORB; 213 if (iorb->RequestControl & IORB_ASYNC_POST) { 214 iorb->NotifyAddress(iorb); 215 } 216 } 217 192 218 /* restart engine to resume IORB processing */ 219 spin_lock(drv_lock); 193 220 trigger_engine(); 194 221 spin_unlock(drv_lock); … … 283 310 for (p = 0; p <= ai->port_max; p++) { 284 311 if (ports_to_reset[a] & (1UL << p)) { 312 ports_to_reset[a] &= ~(1UL << p); 313 285 314 /* Reset this port. Since this is a rather slow operation, we'll 286 315 * release the spinlock while doing so. The adapter is marked as … … 288 317 * interfering. 289 318 */ 290 ports_to_reset[a] &= ~(1UL << p);291 319 ai->busy = 1; 292 320 spin_unlock(drv_lock);
Note:
See TracChangeset
for help on using the changeset viewer.