aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/linux/modules/firewire.mk
blob: 1e2d94272a3e099b2e586cc5b4cc65436ea40be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#
# Copyright (C) 2008-2011 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

FIREWIRE_MENU:=FireWire support

define KernelPackage/firewire
  SUBMENU:=$(FIREWIRE_MENU)
  TITLE:=Support for FireWire (new stack)
  DEPENDS:=@PCI_SUPPORT +kmod-lib-crc-itu-t
  KCONFIG:=CONFIG_FIREWIRE
  FILES:=$(LINUX_DIR)/drivers/firewire/firewire-core.ko
endef

define KernelPackage/firewire/description
 Kernel support for FireWire (new stack)
endef

$(eval $(call KernelPackage,firewire))


define KernelPackage/firewire-net
  SUBMENU:=$(FIREWIRE_MENU)
  TITLE:=Support for IP networking over FireWire
  DEPENDS:=kmod-firewire
  KCONFIG:=CONFIG_FIREWIRE_NET
  FILES:=$(LINUX_DIR)/drivers/firewire/firewire-net.ko
  AUTOLOAD:=$(call AutoProbe,firewire-net)
endef

define KernelPackage/firewire-net/description
 Kernel support for IPv4 over FireWire
endef

$(eval $(call KernelPackage,firewire-net))


define KernelPackage/firewire-ohci
  SUBMENU:=$(FIREWIRE_MENU)
  TITLE:=Support for OHCI-1394 controllers
  DEPENDS:=kmod-firewire
  KCONFIG:= \
	CONFIG_FIREWIRE_OHCI \
	CONFIG_FIREWIRE_OHCI_DEBUG=n \
	CONFIG_FIREWIRE_OHCI_REMOTE_DMA=n
  FILES:=$(LINUX_DIR)/drivers/firewire/firewire-ohci.ko
  AUTOLOAD:=$(call AutoProbe,firewire-ohci)
endef


define KernelPackage/firewire-ohci/description
 Kernel support for FireWire OHCI-1394 controllers
endef

$(eval $(call KernelPackage,firewire-ohci))


define KernelPackage/firewire-sbp2
  SUBMENU:=$(FIREWIRE_MENU)
  TITLE:=Support for SBP-2 devices over FireWire
  DEPENDS:=kmod-firewire +kmod-scsi-core
  KCONFIG:=CONFIG_FIREWIRE_SBP2
  FILES:=$(LINUX_DIR)/drivers/firewire/firewire-sbp2.ko
  AUTOLOAD:=$(call AutoProbe,firewire-sbp2)
endef

define KernelPackage/firewire-sbp2/description
 Kernel support for SBP-2 devices over FireWire
endef

$(eval $(call KernelPackage,firewire-sbp2))
{ color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Copyright (c) 2005, XenSource Ltd.
import string, re

from xen.xend.server.blkif import BlkifController
from xen.xend.XendLogging import log
from xen.util.xpopen import xPopen3

phantomDev = 0;
phantomId = 0;

TAPDISK_SYSFS   = '/sys/class/blktap2'
TAPDISK_BINARY  = '/usr/sbin/tapdisk2'
TAPDISK_DEVICE  = '/dev/xen/blktap-2/tapdev'
TAPDISK_CONTROL = TAPDISK_SYSFS + '/blktap'

blktap1_disk_types = [
    'aio',
    'sync',
    'vmdk',
    'ram',
    'qcow',
    'qcow2',
    'ioemu',
    ]

blktap2_disk_types = [
    'aio',
    'ram',
    'qcow',
    'vhd',
    'remus',
    ]

blktap_disk_types = blktap1_disk_types + blktap2_disk_types

def doexec(args, inputtext=None):
    """Execute a subprocess, then return its return code, stdout and stderr"""
    proc = xPopen3(args, True)
    if inputtext != None:
        proc.tochild.write(inputtext)
    stdout = proc.fromchild
    stderr = proc.childerr
    rc = proc.wait()
    return (rc,stdout,stderr)

def parseDeviceString(device):
    if device.find('/dev') == -1:
        raise Exception, 'invalid tap device: ' + device

    pattern = re.compile(TAPDISK_DEVICE + '(\d+)$')
    groups  = pattern.search(device)
    if not groups:
        raise Exception, 'malformed tap device: ' + device

    minor   = groups.group(1)
    control = TAPDISK_CONTROL + minor

    return minor, device, control

# blktap1 device controller
class BlktapController(BlkifController):
    def __init__(self, vm):
        BlkifController.__init__(self, vm)
        
    def frontendRoot(self):
        """@see DevController#frontendRoot"""
        
        return "%s/device/vbd" % self.vm.getDomainPath()

    def getDeviceDetails(self, config):
        (devid, back, front) = BlkifController.getDeviceDetails(self, config)

        phantomDevid = 0
        wrapped = False

        try:
            imagetype = self.vm.info['image']['type']
        except:
            imagetype = ""

        if imagetype == 'hvm':
            tdevname = back['dev']
            index = ['c', 'd', 'e', 'f', 'g', 'h', 'i', \
                     'j', 'l', 'm', 'n', 'o', 'p']
            while True:
                global phantomDev
                global phantomId
                import os, stat

                phantomId = phantomId + 1
                if phantomId == 16:
                    if index[phantomDev] == index[-1]:
                        if wrapped:
                            raise VmError(" No loopback block \
                                       devices are available. ")
                        wrapped = True
                        phantomDev = 0
                    else:
                        phantomDev = phantomDev + 1
                    phantomId = 1
                devname = 'xvd%s%d' % (index[phantomDev], phantomId)
                try:
                    info = os.stat('/dev/%s' % devname)
                except:
                    break

            vbd = { 'mode': 'w', 'device': devname }
            fn = 'tap:%s' % back['params']

            # recurse ... by creating the vbd, then fallthrough
            # and finish creating the original device

            from xen.xend import XendDomain
            dom0 = XendDomain.instance().privilegedDomain()
            phantomDevid = dom0.create_phantom_vbd_with_vdi(vbd, fn)
            # we need to wait for this device at a higher level
            # the vbd that gets created will have a link to us
            # and will let them do it there

        # add a hook to point to the phantom device,
        # root path is always the same (dom0 tap)
        if phantomDevid != 0:
            front['phantom_vbd'] = '/local/domain/0/backend/tap/0/%s' \
                                   % str(phantomDevid)

        return (devid, back, front)

class Blktap2Controller(BlktapController):
    def __init__(self, vm):
        BlktapController.__init__(self, vm)

    def backendPath(self, backdom, devid):
        if self.deviceClass == 'tap2':
            deviceClass = 'vbd'
        else:
            deviceClass = 'tap'
        return "%s/backend/%s/%s/%d" % (backdom.getDomainPath(),
                                        deviceClass,
                                        self.vm.getDomid(), devid)

    def getDeviceDetails(self, config):

        (devid, back, front) = BlktapController.getDeviceDetails(self, config)
        if self.deviceClass == 'tap2':
        # since blktap2 uses blkback as a backend the 'params' feild contains
        # the path to the blktap2 device (/dev/xen/blktap-2/tapdev*). As well,
        # we need to store the params used to create the blktap2 device
        # (tap:tapdisk:<driver>:/<image-path>)
            tapdisk_uname = config.get('tapdisk_uname', '')
            (_, tapdisk_params) = string.split(tapdisk_uname, ':', 1)
            back['tapdisk-params'] = tapdisk_params 
            
        return (devid, back, front)

    def getDeviceConfiguration(self, devid, transaction = None):

        # this is a blktap2 device, so we need to overwrite the 'params' feild
        # with the actual blktap2 parameters. (the vbd parameters are of little
        # use to us)
        config = BlktapController.getDeviceConfiguration(self, devid, transaction)
        if transaction is None:
            tapdisk_params = self.readBackend(devid, 'tapdisk-params')
        else:
            tapdisk_params = self.readBackendTxn(transaction, devid, 'tapdisk-params')
        if tapdisk_params:
            config['uname'] = 'tap:' + tapdisk_params

        return config


    def createDevice(self, config):

        uname = config.get('uname', '')
        try:
            (typ, subtyp, params, file) = string.split(uname, ':', 3)
            if subtyp not in ('tapdisk', 'ioemu'):
                raise ValueError('invalid subtype')
        except:
            (typ, params, file) = string.split(uname, ':', 2)
            subtyp = 'tapdisk'

        #check for blktap2 installation.
        blktap2_installed=0;
        (rc,stdout, stderr) = doexec("cat /proc/devices");
        out = stdout.read();
        stdout.close();
        stderr.close();
        if( out.find("blktap2") >= 0 ):
            blktap2_installed=1;

        if typ in ('tap'):
            if subtyp in ('tapdisk', 'ioemu'):
                if params not in blktap2_disk_types or not blktap2_installed:
                    # pass this device off to BlktapController
                    log.warn('WARNING: using deprecated blktap module')
                    self.deviceClass = 'tap'
                    devid = BlktapController.createDevice(self, config)
                    self.deviceClass = 'tap2'
                    return devid

        if self.vm.image and self.vm.image.memory_sharing:
            cmd = [ TAPDISK_BINARY, '-n', '%s:%s' % (params, file), '-s', '%d' % self.vm.getDomid() ]
        else:
            cmd = [ TAPDISK_BINARY, '-n', '%s:%s' % (params, file) ]
        (rc,stdout,stderr) = doexec(cmd)

        if rc != 0:
            err = stderr.read();
            out = stdout.read();
            stdout.close();
            stderr.close();
            raise Exception, 'Failed to create device.\n    stdout: %s\n    stderr: %s\nCheck that target \"%s\" exists and that blktap2 driver installed in dom0.' % (out.rstrip(), err.rstrip(), file);

        minor, device, control = parseDeviceString(stdout.readline())
        stdout.close();
        stderr.close();

        # modify the configutration to create a blkback for the underlying
        # blktap2 device. Note: we need to preserve the original tapdisk uname
        # (it is used during save/restore and for managed domains).
        config.update({'tapdisk_uname' : uname})
        config.update({'uname' : 'phy:' + device.rstrip()})

        devid = BlkifController.createDevice(self, config)
        config.update({'uname' : uname})
        config.pop('tapdisk_uname')
        return devid

    # The new blocktap implementation requires a sysfs signal to close
    # out disks.  This function is called from a thread when the
    # domain is detached from the disk.
    def finishDeviceCleanup(self, backpath, path):
        """Perform any device specific cleanup

        @backpath backend xenstore path.
        @path frontend device path

        """

        #Figure out what we're going to wait on.
        self.waitForBackend_destroy(backpath)

        #Figure out the sysfs path.
        minor, dev, ctrl = parseDeviceString(path)

        #Close out the disk
        f = open(ctrl + '/remove', 'w')
        f.write('remove');
        f.close()

        return