@@ 0,0 1,40 @@
+{{template "head" (printf "Devices with %s property: %s" .ObjectType .PropertyName)}}
+
+<h1>DRM database devices with {{.ObjectType}} property: {{.PropertyName}}</h1>
+
+<p><a href="/">Back to index</a></p>
+
+<table>
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Bus type</th>
+ <th>Vendor</th>
+ <th>Name</th>
+ <th>Driver</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{range .Devices}}
+ <tr>
+ <td class="pre">
+ <a href="/snapshots/{{.Key}}">{{.BusID}}</a>
+ </td>
+ <td>{{.BusType}}</td>
+ {{if .Vendor}}
+ <td>{{.Vendor}}</td>
+ {{else}}
+ <td class="status-unknown">?</td>
+ {{end}}
+ {{if .Name}}
+ <td>{{.Name}}</td>
+ {{else}}
+ <td class="status-unknown">?</td>
+ {{end}}
+ <td class="pre">
+ <a href="?driver={{.Driver}}" title="Only show {{.Driver}} devices">{{.Driver}}</a>
+ </td>
+ </tr>
+ {{end}}
+ </tbody>
+</table>
@@ 44,10 44,11 @@
<div>
{{if $ok}}
<span class="status-supported">✓</span>
+ <a href="/properties/{{printf "%d" $.ObjectType}}/{{$.Name}}/devices?driver={{$name}}" title="Show {{$name}} devices supporting this property">{{$name}}</a>
{{else}}
<span class="status-unsupported">✗</span>
- {{end}}
{{$name}}
+ {{end}}
</div>
{{end}}
</div>
@@ 460,6 460,75 @@ func New() *echo.Echo {
}{propertyName, &property, objectType, flags, spec, drivers, doc})
})
+ e.GET("/properties/:obj/:name/devices", func(c echo.Context) error {
+ var objectType drm.ObjectType
+ if i, err := strconv.Atoi(c.Param("obj")); err != nil {
+ return c.String(http.StatusBadRequest, "invalid object type")
+ } else {
+ objectType = drm.ObjectType(i)
+ }
+ propertyName := c.Param("name")
+ driverFilter := c.QueryParam("driver")
+
+ type deviceData struct {
+ Key string
+ BusID string
+ BusType drm.BusType
+ Vendor string
+ Name string
+ Driver string
+ }
+
+ var devices []deviceData
+ err := walkLatest(db, walkLatestDevice, func(k string, n *drmtree.Node) error {
+ if driverFilter != "" && n.Driver.Name != driverFilter {
+ return nil
+ }
+
+ found := false
+ err := walkNodeProps(n, func(obj drm.AnyID, name string, p *drmtree.Property) error {
+ if obj.Type() == objectType && name == propertyName {
+ found = true
+ }
+ return nil
+ })
+ if err != nil || !found {
+ return err
+ }
+
+ data := deviceData{
+ Key: k,
+ BusID: n.Device.BusID(),
+ BusType: n.Device.BusType,
+ Driver: n.Driver.Name,
+ }
+
+ switch dev := n.Device.DeviceData.(type) {
+ case *drmtree.DevicePCI:
+ data.Vendor = pciVendors[uint16(dev.Vendor)]
+ data.Name = pciDevices[dev.Vendor<<16|dev.Device]
+ case *drmtree.DevicePlatform:
+ // No-op
+ default:
+ return nil
+ }
+
+ devices = append(devices, data)
+ return nil
+ })
+ if err != nil {
+ return err
+ } else if len(devices) == 0 {
+ return c.String(http.StatusNotFound, "property not found")
+ }
+
+ return c.Render(http.StatusOK, "property-devices.html", struct {
+ ObjectType drm.ObjectType
+ PropertyName string
+ Devices []deviceData
+ }{objectType, propertyName, devices})
+ })
+
e.GET("/formats", func(c echo.Context) error {
type modifierAndFormat struct {
mod drm.Modifier