[PATCH] btt: seek additions
[blktrace.git] / btt / devs.c
1 /*
2  * blktrace output analysis: generate a timeline & gather statistics
3  *
4  * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21 #include <stdio.h>
22
23 #include "globals.h"
24
25 #define N_DEV_HASH      128
26 #define DEV_HASH(dev)   ((MAJOR(dev) ^ MINOR(dev)) & (N_DEV_HASH - 1))
27 struct list_head        *dev_heads = NULL;
28
29 static void init_dev_heads(void)
30 {
31         int i;
32
33         dev_heads = zmalloc(N_DEV_HASH * sizeof(struct list_head));
34         for (i = 0; i < N_DEV_HASH; i++)
35                 INIT_LIST_HEAD(&dev_heads[i]);
36 }
37
38 struct d_info *__dip_find(__u32 device)
39 {
40         struct list_head *p;
41         struct d_info *dip;
42
43         if (dev_heads == NULL) {
44                 init_dev_heads();
45                 return NULL;
46         }
47
48         __list_for_each(p, &dev_heads[DEV_HASH(device)]) {
49                 dip = list_entry(p, struct d_info, hash_head);
50                 if (device == dip->device)
51                         return dip;
52         }
53
54         return NULL;
55 }
56
57 struct d_info *dip_add(__u32 device, struct io *iop)
58 {
59         struct d_info *dip = __dip_find(device);
60
61         if (dip == NULL) {
62                 int i;
63
64                 dip = zmalloc(sizeof(*dip));
65                 dip->device = device;
66                 dip->last_q = (__u64)-1;
67                 for (i = 0; i < N_IOP_TYPES; i++)
68                         INIT_LIST_HEAD(&dip->iop_heads[i]);
69                 init_region(&dip->regions);
70                 dip->map = dev_map_find(device);
71                 dip->seek_handle = seeki_init(device);
72
73                 if (dev_heads == NULL) init_dev_heads();
74                 list_add_tail(&dip->hash_head, &dev_heads[DEV_HASH(device)]);
75
76                 list_add_tail(&dip->head, &all_devs);
77                 n_devs++;
78         }
79
80         list_add(&iop->dev_head, dip_get_head(dip, iop->type));
81
82         return dip;
83 }