1 #include <l4/dde/fbsd/dde.h>
2 #include <l4/dde/fbsd/bsd_dde.h>
3 #include <l4/dde/fbsd/ata.h>
4 #include <l4/bddf/timebase.h>
5 #include <l4/log/l4log.h>
7 #include <l4/rt_mon/histogram.h>
15 * Helper function for registering a new physical device at bddf.
16 * Called after bddf disk initialization and before reading the partition
17 * tables. Should release the request loop running.
19 int l4ata_start_request_loop(device_handle_t device, void *arg) {
20 dad_disk_t *dsk = (dad_disk_t*) arg;
21 l4ata_disk_info_t *di = dad_l4ata_di(dsk);
23 // initialize l4ata_disk structure part 2
24 di->bddf_device = device;
26 // now request loop can start running
27 l4semaphore_up(&di->reqloop_start);
33 * Request loop function waiting for and handling bddf requests.
35 void l4ata_request_loop(void *arg) {
36 dad_disk_t *dsk = (dad_disk_t *)arg;
37 l4ata_disk_info_t *di = dad_l4ata_di(dsk);
40 struct ds_list_element *ds;
43 bsd_dde_prepare_thread("reqloop");
45 // wait until start_request_loop is called
46 l4semaphore_down(&di->reqloop_start);
52 LOGd(dbg_this, "requesting next disk i/o task");
54 req = bus_get_next_req(di->bddf_device);
62 case REQ_TYPE_BARRIER:
70 // mark request handling start time for bddf
71 req->start_time = bddf_get_timestamp();
74 rt_mon_hist_start(rtm_request_setup_cpu);
75 rt_mon_hist_start(rtm_request_setup_wall);
78 // reject invalid requests
79 if (req->start_sect < 0) {
80 LOG("error: invalid request (start_sect=%d) for %s", req->start_sect, dsk->name);
81 req->end_time = bddf_get_timestamp();
82 bus_completed_req(di->bddf_device, req, 1);
85 if ( (req->type!=REQ_TYPE_READ) && (req->type!=REQ_TYPE_WRITE) ) {
86 LOG("error: unknown request type (type=%d) for %s", req->type, dsk->name);
87 req->end_time = bddf_get_timestamp();
88 bus_completed_req(di->bddf_device, req, 1);
92 // test if sum(buffers) is big enough
94 ds = (struct ds_list_element *)req->ds_list;
95 for (dsi = req->ds_list_count; dsi; dsi--, ds++)
96 bufsize += ds->ds_size;
97 if (bufsize < req->sect_num*dsk->sectsize) {
98 LOG("error: buffer too small (%d)\nfor request (%d=%d sects of %d bytes) for %s",
99 bufsize, req->sect_num*dsk->sectsize, req->sect_num, dsk->sectsize, dsk->name);
100 req->end_time = bddf_get_timestamp();
101 bus_completed_req(di->bddf_device, req, 1);
106 l4ata_handle_request(dsk, req);
109 rt_mon_hist_end(rtm_request_setup_cpu);
110 rt_mon_hist_end(rtm_request_setup_wall);