static void ssd_reconnect_done (ioreq_event *curr) { ssd_t *currdisk; // fprintf (outputfile, "Entering ssd_reconnect_done for disk %d: %12.6f\n", curr->devno, simtime); currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); if (curr->flags & READ) { if (currdisk->neverdisconnect) { /* Just holding on to bus; data transfer will be initiated when */ /* media access is complete. */ addtoextraq((event *) curr); ssd_check_channel_activity (currdisk); } else { /* data transfer: curr->bcount, which is still set to original */ /* requested value, indicates how many blks to transfer. */ curr->type = DEVICE_DATA_TRANSFER_COMPLETE; ssd_send_event_up_path(curr, (double) 0.0); } } else { if (currdisk->reconnect_reason == DEVICE_ACCESS_COMPLETE) { ssd_request_complete (curr); } else { /* data transfer: curr->bcount, which is still set to original */ /* requested value, indicates how many blks to transfer. */ curr->type = DEVICE_DATA_TRANSFER_COMPLETE; ssd_send_event_up_path(curr, (double) 0.0); } } }
static void ssd_bustransfer_complete (ioreq_event *curr) { // fprintf (outputfile, "Entering ssd_bustransfer_complete for disk %d: %12.6f\n", curr->devno, simtime); if (curr->flags & READ) { ssd_request_complete (curr); } else { ssd_t *currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); ssd_media_access_request (curr); ssd_check_channel_activity (currdisk); } }
/* completion disconnect done */ static void ssd_completion_done (ioreq_event *curr) { ssd_t *currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); // fprintf (outputfile, "Entering ssd_completion for disk %d: %12.6f\n", currdisk->devno, simtime); addtoextraq((event *) curr); if (currdisk->busowned != -1) { bus_ownership_release(currdisk->busowned); currdisk->busowned = -1; } ssd_check_channel_activity (currdisk); }
/* * ssd_send_event_up_path() * * Acquires the bus (if not already acquired), then uses bus_delay to * send the event up the path. * * If the bus is already owned by this device or can be acquired * immediately (interleaved bus), the event is sent immediately. * Otherwise, ssd_bus_ownership_grant will later send the event. */ static void ssd_send_event_up_path (ioreq_event *curr, double delay) { ssd_t *currdisk; int busno; int slotno; // fprintf (outputfile, "ssd_send_event_up_path - devno %d, type %d, cause %d, blkno %d\n", curr->devno, curr->type, curr->cause, curr->blkno); currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); busno = ssd_get_busno(curr); slotno = currdisk->slotno[0]; /* Put new request at head of buswait queue */ curr->next = currdisk->buswait; currdisk->buswait = curr; curr->tempint1 = busno; curr->time = delay; if (currdisk->busowned == -1) { // fprintf (outputfile, "Must get ownership of the bus first\n"); if (curr->next) { //fprintf(stderr,"Multiple bus requestors detected in ssd_send_event_up_path\n"); /* This should be ok -- counting on the bus module to sequence 'em */ } if (bus_ownership_get(busno, slotno, curr) == FALSE) { /* Remember when we started waiting (only place this is written) */ currdisk->stat.requestedbus = simtime; } else { currdisk->busowned = busno; bus_delay(busno, DEVICE, curr->devno, delay, curr); /* Never for SCSI */ } } else if (currdisk->busowned == busno) { //fprintf (outputfile, "Already own bus - so send it on up\n"); bus_delay(busno, DEVICE, curr->devno, delay, curr); } else { fprintf(stderr, "Wrong bus owned for transfer desired\n"); exit(1); } }
/* * send completion up the line */ static void ssd_request_complete(ioreq_event *curr) { ssd_t *currdisk; ioreq_event *x; // fprintf (outputfile, "Entering ssd_request_complete: %12.6f\n", simtime); currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); if ((x = ioqueue_physical_access_done(currdisk->queue,curr)) == NULL) { fprintf(stderr, "ssd_request_complete: ioreq_event not found by ioqueue_physical_access_done call\n"); exit(1); } /* send completion interrupt */ curr->type = IO_INTERRUPT_ARRIVE; curr->cause = COMPLETION; ssd_send_event_up_path(curr, currdisk->bus_transaction_latency); }
void ssd_bus_delay_complete (int devno, ioreq_event *curr, int sentbusno) { ssd_t *currdisk; intchar slotno; intchar busno; int depth; currdisk = getssd (devno); ssd_assert_current_activity(currdisk, curr); // fprintf (outputfile, "Entered ssd_bus_delay_complete\n"); // EPW: I think the buswait logic doesn't do anything, is confusing, and risks // overusing the "next" field, although an item shouldn't currently be a queue. if (curr == currdisk->buswait) { currdisk->buswait = curr->next; } else { ioreq_event *tmp = currdisk->buswait; while ((tmp->next != NULL) && (tmp->next != curr)) { tmp = tmp->next; } if (tmp->next != curr) { // fixed a warning here //fprintf(stderr, "Bus delay complete for unknown ssd request - devno %d, busno %d\n", devno, busno.value); fprintf(stderr, "Bus delay complete for unknown ssd request - devno %d, busno %d\n", devno, curr->busno); exit(1); } tmp->next = curr->next; } busno.value = curr->busno; slotno.value = curr->slotno; depth = currdisk->depth[0]; slotno.byte[depth] = slotno.byte[depth] >> 4; curr->time = 0.0; if (depth == 0) { intr_request ((event *)curr); } else { bus_deliver_event(busno.byte[depth], slotno.byte[depth], curr); } }
static void ssd_bustransfer_complete (ioreq_event *curr) { // fprintf (outputfile, "Entering ssd_bustransfer_complete for disk %d: %12.6f\n", curr->devno, simtime); if (curr->flags & READ) { ssd_request_complete (curr); } else { ssd_t *currdisk = getssd (curr->devno); ssd_assert_current_activity(currdisk, curr); if (currdisk->neverdisconnect == FALSE) { /* disconnect from bus */ ioreq_event *tmp = ioreq_copy (curr); tmp->type = IO_INTERRUPT_ARRIVE; tmp->cause = DISCONNECT; ssd_send_event_up_path (tmp, currdisk->bus_transaction_latency); ssd_media_access_request (curr); } else { ssd_media_access_request (curr); ssd_check_channel_activity (currdisk); } } }
/* * ssd_bus_ownership_grant * Calls bus_delay to handle the event that the disk has been granted the bus. I believe * this is always initiated by a call to ssd_send_even_up_path. */ void ssd_bus_ownership_grant (int devno, ioreq_event *curr, int busno, double arbdelay) { ssd_t *currdisk; ioreq_event *tmp; currdisk = getssd (devno); ssd_assert_current_activity(currdisk, curr); tmp = currdisk->buswait; while ((tmp != NULL) && (tmp != curr)) { tmp = tmp->next; } if (tmp == NULL) { fprintf(stderr, "Bus ownership granted to unknown ssd request - devno %d, busno %d\n", devno, busno); exit(1); } currdisk->busowned = busno; currdisk->stat.waitingforbus += arbdelay; //ASSERT (arbdelay == (simtime - currdisk->stat.requestedbus)); currdisk->stat.numbuswaits++; bus_delay(busno, DEVICE, devno, tmp->time, tmp); }