mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: sound/core/memalloc.c
This commit is contained in:
commit
56c5d900db
3711 changed files with 190539 additions and 88192 deletions
|
|
@ -159,11 +159,8 @@ struct aoedev {
|
|||
sector_t ssize;
|
||||
struct timer_list timer;
|
||||
spinlock_t lock;
|
||||
struct sk_buff *sendq_hd; /* packets needing to be sent, list head */
|
||||
struct sk_buff *sendq_tl;
|
||||
struct sk_buff *skbpool_hd;
|
||||
struct sk_buff *skbpool_tl;
|
||||
int nskbpool;
|
||||
struct sk_buff_head sendq;
|
||||
struct sk_buff_head skbpool;
|
||||
mempool_t *bufpool; /* for deadlock-free Buf allocation */
|
||||
struct list_head bufq; /* queue of bios to work on */
|
||||
struct buf *inprocess; /* the one we're currently working on */
|
||||
|
|
@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size);
|
|||
|
||||
int aoenet_init(void);
|
||||
void aoenet_exit(void);
|
||||
void aoenet_xmit(struct sk_buff *);
|
||||
void aoenet_xmit(struct sk_buff_head *);
|
||||
int is_aoe_netif(struct net_device *ifp);
|
||||
int set_aoe_iflist(const char __user *str, size_t size);
|
||||
|
||||
|
|
|
|||
|
|
@ -109,12 +109,12 @@ static const struct attribute_group attr_group = {
|
|||
static int
|
||||
aoedisk_add_sysfs(struct aoedev *d)
|
||||
{
|
||||
return sysfs_create_group(&d->gd->dev.kobj, &attr_group);
|
||||
return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group);
|
||||
}
|
||||
void
|
||||
aoedisk_rm_sysfs(struct aoedev *d)
|
||||
{
|
||||
sysfs_remove_group(&d->gd->dev.kobj, &attr_group);
|
||||
sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp)
|
|||
static int
|
||||
aoeblk_make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
struct sk_buff_head queue;
|
||||
struct aoedev *d;
|
||||
struct buf *buf;
|
||||
struct sk_buff *sl;
|
||||
ulong flags;
|
||||
|
||||
blk_queue_bounce(q, &bio);
|
||||
|
|
@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
|
|||
list_add_tail(&buf->bufs, &d->bufq);
|
||||
|
||||
aoecmd_work(d);
|
||||
sl = d->sendq_hd;
|
||||
d->sendq_hd = d->sendq_tl = NULL;
|
||||
__skb_queue_head_init(&queue);
|
||||
skb_queue_splice_init(&d->sendq, &queue);
|
||||
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
aoenet_xmit(sl);
|
||||
aoenet_xmit(&queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -276,7 +276,7 @@ aoeblk_gdalloc(void *vp)
|
|||
gd->first_minor = d->sysminor * AOE_PARTITIONS;
|
||||
gd->fops = &aoe_bdops;
|
||||
gd->private_data = d;
|
||||
gd->capacity = d->ssize;
|
||||
set_capacity(gd, d->ssize);
|
||||
snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
|
||||
d->aoemajor, d->aoeminor);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include "aoe.h"
|
||||
|
||||
enum {
|
||||
|
|
@ -103,7 +104,12 @@ loop:
|
|||
spin_lock_irqsave(&d->lock, flags);
|
||||
goto loop;
|
||||
}
|
||||
aoenet_xmit(skb);
|
||||
if (skb) {
|
||||
struct sk_buff_head queue;
|
||||
__skb_queue_head_init(&queue);
|
||||
__skb_queue_tail(&queue, skb);
|
||||
aoenet_xmit(&queue);
|
||||
}
|
||||
aoecmd_cfg(major, minor);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t)
|
|||
static void
|
||||
skb_pool_put(struct aoedev *d, struct sk_buff *skb)
|
||||
{
|
||||
if (!d->skbpool_hd)
|
||||
d->skbpool_hd = skb;
|
||||
else
|
||||
d->skbpool_tl->next = skb;
|
||||
d->skbpool_tl = skb;
|
||||
__skb_queue_tail(&d->skbpool, skb);
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
skb_pool_get(struct aoedev *d)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb = skb_peek(&d->skbpool);
|
||||
|
||||
skb = d->skbpool_hd;
|
||||
if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) {
|
||||
d->skbpool_hd = skb->next;
|
||||
skb->next = NULL;
|
||||
__skb_unlink(skb, &d->skbpool);
|
||||
return skb;
|
||||
}
|
||||
if (d->nskbpool < NSKBPOOLMAX
|
||||
&& (skb = new_skb(ETH_ZLEN))) {
|
||||
d->nskbpool++;
|
||||
if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX &&
|
||||
(skb = new_skb(ETH_ZLEN)))
|
||||
return skb;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d)
|
|||
|
||||
skb->dev = t->ifp->nd;
|
||||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb) {
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
}
|
||||
if (skb)
|
||||
__skb_queue_tail(&d->sendq, skb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* some callers cannot sleep, and they can call this function,
|
||||
* transmitting the packets later, when interrupts are on
|
||||
*/
|
||||
static struct sk_buff *
|
||||
aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
|
||||
static void
|
||||
aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue)
|
||||
{
|
||||
struct aoe_hdr *h;
|
||||
struct aoe_cfghdr *ch;
|
||||
struct sk_buff *skb, *sl, *sl_tail;
|
||||
struct sk_buff *skb;
|
||||
struct net_device *ifp;
|
||||
|
||||
sl = sl_tail = NULL;
|
||||
|
||||
read_lock(&dev_base_lock);
|
||||
for_each_netdev(&init_net, ifp) {
|
||||
dev_hold(ifp);
|
||||
|
|
@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
|
|||
}
|
||||
skb_put(skb, sizeof *h + sizeof *ch);
|
||||
skb->dev = ifp;
|
||||
if (sl_tail == NULL)
|
||||
sl_tail = skb;
|
||||
__skb_queue_tail(queue, skb);
|
||||
h = (struct aoe_hdr *) skb_mac_header(skb);
|
||||
memset(h, 0, sizeof *h + sizeof *ch);
|
||||
|
||||
|
|
@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
|
|||
h->minor = aoeminor;
|
||||
h->cmd = AOECMD_CFG;
|
||||
|
||||
skb->next = sl;
|
||||
sl = skb;
|
||||
cont:
|
||||
dev_put(ifp);
|
||||
}
|
||||
read_unlock(&dev_base_lock);
|
||||
|
||||
if (tail != NULL)
|
||||
*tail = sl_tail;
|
||||
return sl;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
|
|||
skb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return;
|
||||
if (d->sendq_hd)
|
||||
d->sendq_tl->next = skb;
|
||||
else
|
||||
d->sendq_hd = skb;
|
||||
d->sendq_tl = skb;
|
||||
__skb_queue_tail(&d->sendq, skb);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) {
|
|||
static void
|
||||
rexmit_timer(ulong vp)
|
||||
{
|
||||
struct sk_buff_head queue;
|
||||
struct aoedev *d;
|
||||
struct aoetgt *t, **tt, **te;
|
||||
struct aoeif *ifp;
|
||||
struct frame *f, *e;
|
||||
struct sk_buff *sl;
|
||||
register long timeout;
|
||||
ulong flags, n;
|
||||
|
||||
d = (struct aoedev *) vp;
|
||||
sl = NULL;
|
||||
|
||||
/* timeout is always ~150% of the moving average */
|
||||
timeout = d->rttavg;
|
||||
|
|
@ -589,7 +563,7 @@ rexmit_timer(ulong vp)
|
|||
}
|
||||
}
|
||||
|
||||
if (d->sendq_hd) {
|
||||
if (!skb_queue_empty(&d->sendq)) {
|
||||
n = d->rttavg <<= 1;
|
||||
if (n > MAXTIMER)
|
||||
d->rttavg = MAXTIMER;
|
||||
|
|
@ -600,15 +574,15 @@ rexmit_timer(ulong vp)
|
|||
aoecmd_work(d);
|
||||
}
|
||||
|
||||
sl = d->sendq_hd;
|
||||
d->sendq_hd = d->sendq_tl = NULL;
|
||||
__skb_queue_head_init(&queue);
|
||||
skb_queue_splice_init(&d->sendq, &queue);
|
||||
|
||||
d->timer.expires = jiffies + TIMERTICK;
|
||||
add_timer(&d->timer);
|
||||
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
|
||||
aoenet_xmit(sl);
|
||||
aoenet_xmit(&queue);
|
||||
}
|
||||
|
||||
/* enters with d->lock held */
|
||||
|
|
@ -645,7 +619,7 @@ aoecmd_sleepwork(struct work_struct *work)
|
|||
unsigned long flags;
|
||||
u64 ssize;
|
||||
|
||||
ssize = d->gd->capacity;
|
||||
ssize = get_capacity(d->gd);
|
||||
bd = bdget_disk(d->gd, 0);
|
||||
|
||||
if (bd) {
|
||||
|
|
@ -707,7 +681,7 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
|
|||
if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
|
||||
return;
|
||||
if (d->gd != NULL) {
|
||||
d->gd->capacity = ssize;
|
||||
set_capacity(d->gd, ssize);
|
||||
d->flags |= DEVFL_NEWSIZE;
|
||||
} else
|
||||
d->flags |= DEVFL_GDALLOC;
|
||||
|
|
@ -756,23 +730,28 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
|
|||
unsigned long n_sect = bio->bi_size >> 9;
|
||||
const int rw = bio_data_dir(bio);
|
||||
struct hd_struct *part;
|
||||
int cpu;
|
||||
|
||||
part = get_part(disk, sector);
|
||||
all_stat_inc(disk, part, ios[rw], sector);
|
||||
all_stat_add(disk, part, ticks[rw], duration, sector);
|
||||
all_stat_add(disk, part, sectors[rw], n_sect, sector);
|
||||
all_stat_add(disk, part, io_ticks, duration, sector);
|
||||
cpu = part_stat_lock();
|
||||
part = disk_map_sector_rcu(disk, sector);
|
||||
|
||||
part_stat_inc(cpu, part, ios[rw]);
|
||||
part_stat_add(cpu, part, ticks[rw], duration);
|
||||
part_stat_add(cpu, part, sectors[rw], n_sect);
|
||||
part_stat_add(cpu, part, io_ticks, duration);
|
||||
|
||||
part_stat_unlock();
|
||||
}
|
||||
|
||||
void
|
||||
aoecmd_ata_rsp(struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff_head queue;
|
||||
struct aoedev *d;
|
||||
struct aoe_hdr *hin, *hout;
|
||||
struct aoe_atahdr *ahin, *ahout;
|
||||
struct frame *f;
|
||||
struct buf *buf;
|
||||
struct sk_buff *sl;
|
||||
struct aoetgt *t;
|
||||
struct aoeif *ifp;
|
||||
register long n;
|
||||
|
|
@ -893,21 +872,21 @@ aoecmd_ata_rsp(struct sk_buff *skb)
|
|||
|
||||
aoecmd_work(d);
|
||||
xmit:
|
||||
sl = d->sendq_hd;
|
||||
d->sendq_hd = d->sendq_tl = NULL;
|
||||
__skb_queue_head_init(&queue);
|
||||
skb_queue_splice_init(&d->sendq, &queue);
|
||||
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
aoenet_xmit(sl);
|
||||
aoenet_xmit(&queue);
|
||||
}
|
||||
|
||||
void
|
||||
aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
|
||||
{
|
||||
struct sk_buff *sl;
|
||||
struct sk_buff_head queue;
|
||||
|
||||
sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
|
||||
|
||||
aoenet_xmit(sl);
|
||||
__skb_queue_head_init(&queue);
|
||||
aoecmd_cfg_pkts(aoemajor, aoeminor, &queue);
|
||||
aoenet_xmit(&queue);
|
||||
}
|
||||
|
||||
struct sk_buff *
|
||||
|
|
@ -1076,7 +1055,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
|
|||
|
||||
spin_unlock_irqrestore(&d->lock, flags);
|
||||
|
||||
aoenet_xmit(sl);
|
||||
if (sl) {
|
||||
struct sk_buff_head queue;
|
||||
__skb_queue_head_init(&queue);
|
||||
__skb_queue_tail(&queue, sl);
|
||||
aoenet_xmit(&queue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ aoedev_downdev(struct aoedev *d)
|
|||
}
|
||||
|
||||
if (d->gd)
|
||||
d->gd->capacity = 0;
|
||||
set_capacity(d->gd, 0);
|
||||
|
||||
d->flags &= ~DEVFL_UP;
|
||||
}
|
||||
|
|
@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb)
|
|||
static void
|
||||
skbpoolfree(struct aoedev *d)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb, *tmp;
|
||||
|
||||
while ((skb = d->skbpool_hd)) {
|
||||
d->skbpool_hd = skb->next;
|
||||
skb->next = NULL;
|
||||
skb_queue_walk_safe(&d->skbpool, skb, tmp)
|
||||
skbfree(skb);
|
||||
}
|
||||
d->skbpool_tl = NULL;
|
||||
|
||||
__skb_queue_head_init(&d->skbpool);
|
||||
}
|
||||
|
||||
/* find it or malloc it */
|
||||
|
|
@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor)
|
|||
goto out;
|
||||
INIT_WORK(&d->work, aoecmd_sleepwork);
|
||||
spin_lock_init(&d->lock);
|
||||
skb_queue_head_init(&d->sendq);
|
||||
skb_queue_head_init(&d->skbpool);
|
||||
init_timer(&d->timer);
|
||||
d->timer.data = (ulong) d;
|
||||
d->timer.function = dummy_timer;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/hdreg.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include "aoe.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -95,13 +95,12 @@ mac_addr(char addr[6])
|
|||
}
|
||||
|
||||
void
|
||||
aoenet_xmit(struct sk_buff *sl)
|
||||
aoenet_xmit(struct sk_buff_head *queue)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb, *tmp;
|
||||
|
||||
while ((skb = sl)) {
|
||||
sl = sl->next;
|
||||
skb->next = skb->prev = NULL;
|
||||
skb_queue_walk_safe(queue, skb, tmp) {
|
||||
__skb_unlink(skb, queue);
|
||||
dev_queue_xmit(skb);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3460,8 +3460,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
|||
hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");
|
||||
|
||||
hba[i]->cmd_pool_bits =
|
||||
kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG -
|
||||
1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
|
||||
kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
|
||||
* sizeof(unsigned long), GFP_KERNEL);
|
||||
hba[i]->cmd_pool = (CommandList_struct *)
|
||||
pci_alloc_consistent(hba[i]->pdev,
|
||||
hba[i]->nr_cmds * sizeof(CommandList_struct),
|
||||
|
|
@ -3493,8 +3493,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
|||
/* command and error info recs zeroed out before
|
||||
they are used */
|
||||
memset(hba[i]->cmd_pool_bits, 0,
|
||||
((hba[i]->nr_cmds + BITS_PER_LONG -
|
||||
1) / BITS_PER_LONG) * sizeof(unsigned long));
|
||||
DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG)
|
||||
* sizeof(unsigned long));
|
||||
|
||||
hba[i]->num_luns = 0;
|
||||
hba[i]->highest_lun = -1;
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ struct scsi2map {
|
|||
|
||||
static int
|
||||
cciss_scsi_add_entry(int ctlr, int hostno,
|
||||
unsigned char *scsi3addr, int devtype,
|
||||
struct cciss_scsi_dev_t *device,
|
||||
struct scsi2map *added, int *nadded)
|
||||
{
|
||||
/* assumes hba[ctlr]->scsi_ctlr->lock is held */
|
||||
|
|
@ -384,12 +384,12 @@ cciss_scsi_add_entry(int ctlr, int hostno,
|
|||
lun = 0;
|
||||
/* Is this device a non-zero lun of a multi-lun device */
|
||||
/* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
|
||||
if (scsi3addr[4] != 0) {
|
||||
if (device->scsi3addr[4] != 0) {
|
||||
/* Search through our list and find the device which */
|
||||
/* has the same 8 byte LUN address, excepting byte 4. */
|
||||
/* Assign the same bus and target for this new LUN. */
|
||||
/* Use the logical unit number from the firmware. */
|
||||
memcpy(addr1, scsi3addr, 8);
|
||||
memcpy(addr1, device->scsi3addr, 8);
|
||||
addr1[4] = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
sd = &ccissscsi[ctlr].dev[i];
|
||||
|
|
@ -399,7 +399,7 @@ cciss_scsi_add_entry(int ctlr, int hostno,
|
|||
if (memcmp(addr1, addr2, 8) == 0) {
|
||||
bus = sd->bus;
|
||||
target = sd->target;
|
||||
lun = scsi3addr[4];
|
||||
lun = device->scsi3addr[4];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -420,8 +420,12 @@ cciss_scsi_add_entry(int ctlr, int hostno,
|
|||
added[*nadded].lun = sd->lun;
|
||||
(*nadded)++;
|
||||
|
||||
memcpy(&sd->scsi3addr[0], scsi3addr, 8);
|
||||
sd->devtype = devtype;
|
||||
memcpy(sd->scsi3addr, device->scsi3addr, 8);
|
||||
memcpy(sd->vendor, device->vendor, sizeof(sd->vendor));
|
||||
memcpy(sd->revision, device->revision, sizeof(sd->revision));
|
||||
memcpy(sd->device_id, device->device_id, sizeof(sd->device_id));
|
||||
sd->devtype = device->devtype;
|
||||
|
||||
ccissscsi[ctlr].ndevices++;
|
||||
|
||||
/* initially, (before registering with scsi layer) we don't
|
||||
|
|
@ -487,6 +491,22 @@ static void fixup_botched_add(int ctlr, char *scsi3addr)
|
|||
CPQ_TAPE_UNLOCK(ctlr, flags);
|
||||
}
|
||||
|
||||
static int device_is_the_same(struct cciss_scsi_dev_t *dev1,
|
||||
struct cciss_scsi_dev_t *dev2)
|
||||
{
|
||||
return dev1->devtype == dev2->devtype &&
|
||||
memcmp(dev1->scsi3addr, dev2->scsi3addr,
|
||||
sizeof(dev1->scsi3addr)) == 0 &&
|
||||
memcmp(dev1->device_id, dev2->device_id,
|
||||
sizeof(dev1->device_id)) == 0 &&
|
||||
memcmp(dev1->vendor, dev2->vendor,
|
||||
sizeof(dev1->vendor)) == 0 &&
|
||||
memcmp(dev1->model, dev2->model,
|
||||
sizeof(dev1->model)) == 0 &&
|
||||
memcmp(dev1->revision, dev2->revision,
|
||||
sizeof(dev1->revision)) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
adjust_cciss_scsi_table(int ctlr, int hostno,
|
||||
struct cciss_scsi_dev_t sd[], int nsds)
|
||||
|
|
@ -532,7 +552,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
|
|||
for (j=0;j<nsds;j++) {
|
||||
if (SCSI3ADDR_EQ(sd[j].scsi3addr,
|
||||
csd->scsi3addr)) {
|
||||
if (sd[j].devtype == csd->devtype)
|
||||
if (device_is_the_same(&sd[j], csd))
|
||||
found=2;
|
||||
else
|
||||
found=1;
|
||||
|
|
@ -548,22 +568,26 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
|
|||
cciss_scsi_remove_entry(ctlr, hostno, i,
|
||||
removed, &nremoved);
|
||||
/* remove ^^^, hence i not incremented */
|
||||
}
|
||||
else if (found == 1) { /* device is different kind */
|
||||
} else if (found == 1) { /* device is different in some way */
|
||||
changes++;
|
||||
printk("cciss%d: device c%db%dt%dl%d type changed "
|
||||
"(device type now %s).\n",
|
||||
ctlr, hostno, csd->bus, csd->target, csd->lun,
|
||||
scsi_device_type(csd->devtype));
|
||||
printk("cciss%d: device c%db%dt%dl%d has changed.\n",
|
||||
ctlr, hostno, csd->bus, csd->target, csd->lun);
|
||||
cciss_scsi_remove_entry(ctlr, hostno, i,
|
||||
removed, &nremoved);
|
||||
/* remove ^^^, hence i not incremented */
|
||||
if (cciss_scsi_add_entry(ctlr, hostno,
|
||||
&sd[j].scsi3addr[0], sd[j].devtype,
|
||||
if (cciss_scsi_add_entry(ctlr, hostno, &sd[j],
|
||||
added, &nadded) != 0)
|
||||
/* we just removed one, so add can't fail. */
|
||||
BUG();
|
||||
csd->devtype = sd[j].devtype;
|
||||
memcpy(csd->device_id, sd[j].device_id,
|
||||
sizeof(csd->device_id));
|
||||
memcpy(csd->vendor, sd[j].vendor,
|
||||
sizeof(csd->vendor));
|
||||
memcpy(csd->model, sd[j].model,
|
||||
sizeof(csd->model));
|
||||
memcpy(csd->revision, sd[j].revision,
|
||||
sizeof(csd->revision));
|
||||
} else /* device is same as it ever was, */
|
||||
i++; /* so just move along. */
|
||||
}
|
||||
|
|
@ -577,7 +601,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
|
|||
csd = &ccissscsi[ctlr].dev[j];
|
||||
if (SCSI3ADDR_EQ(sd[i].scsi3addr,
|
||||
csd->scsi3addr)) {
|
||||
if (sd[i].devtype == csd->devtype)
|
||||
if (device_is_the_same(&sd[i], csd))
|
||||
found=2; /* found device */
|
||||
else
|
||||
found=1; /* found a bug. */
|
||||
|
|
@ -586,16 +610,14 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
|
|||
}
|
||||
if (!found) {
|
||||
changes++;
|
||||
if (cciss_scsi_add_entry(ctlr, hostno,
|
||||
|
||||
&sd[i].scsi3addr[0], sd[i].devtype,
|
||||
if (cciss_scsi_add_entry(ctlr, hostno, &sd[i],
|
||||
added, &nadded) != 0)
|
||||
break;
|
||||
} else if (found == 1) {
|
||||
/* should never happen... */
|
||||
changes++;
|
||||
printk("cciss%d: device unexpectedly changed type\n",
|
||||
ctlr);
|
||||
printk(KERN_WARNING "cciss%d: device "
|
||||
"unexpectedly changed\n", ctlr);
|
||||
/* but if it does happen, we just ignore that device */
|
||||
}
|
||||
}
|
||||
|
|
@ -1012,7 +1034,8 @@ cciss_scsi_interpret_error(CommandList_struct *cp)
|
|||
|
||||
static int
|
||||
cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
|
||||
unsigned char *buf, unsigned char bufsize)
|
||||
unsigned char page, unsigned char *buf,
|
||||
unsigned char bufsize)
|
||||
{
|
||||
int rc;
|
||||
CommandList_struct *cp;
|
||||
|
|
@ -1032,8 +1055,8 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
|
|||
ei = cp->err_info;
|
||||
|
||||
cdb[0] = CISS_INQUIRY;
|
||||
cdb[1] = 0;
|
||||
cdb[2] = 0;
|
||||
cdb[1] = (page != 0);
|
||||
cdb[2] = page;
|
||||
cdb[3] = 0;
|
||||
cdb[4] = bufsize;
|
||||
cdb[5] = 0;
|
||||
|
|
@ -1053,6 +1076,25 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Get the device id from inquiry page 0x83 */
|
||||
static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr,
|
||||
unsigned char *device_id, int buflen)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *buf;
|
||||
|
||||
if (buflen > 16)
|
||||
buflen = 16;
|
||||
buf = kzalloc(64, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -1;
|
||||
rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64);
|
||||
if (rc == 0)
|
||||
memcpy(device_id, &buf[8], buflen);
|
||||
kfree(buf);
|
||||
return rc != 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cciss_scsi_do_report_phys_luns(ctlr_info_t *c,
|
||||
ReportLunData_struct *buf, int bufsize)
|
||||
|
|
@ -1142,25 +1184,21 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
|
|||
ctlr_info_t *c;
|
||||
__u32 num_luns=0;
|
||||
unsigned char *ch;
|
||||
/* unsigned char found[CCISS_MAX_SCSI_DEVS_PER_HBA]; */
|
||||
struct cciss_scsi_dev_t currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
|
||||
struct cciss_scsi_dev_t *currentsd, *this_device;
|
||||
int ncurrent=0;
|
||||
int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
|
||||
int i;
|
||||
|
||||
c = (ctlr_info_t *) hba[cntl_num];
|
||||
ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
|
||||
if (ld_buff == NULL) {
|
||||
printk(KERN_ERR "cciss: out of memory\n");
|
||||
return;
|
||||
}
|
||||
inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
|
||||
if (inq_buff == NULL) {
|
||||
printk(KERN_ERR "cciss: out of memory\n");
|
||||
kfree(ld_buff);
|
||||
return;
|
||||
currentsd = kzalloc(sizeof(*currentsd) *
|
||||
(CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL);
|
||||
if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) {
|
||||
printk(KERN_ERR "cciss: out of memory\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
this_device = ¤tsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
|
||||
if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
|
||||
ch = &ld_buff->LUNListLength[0];
|
||||
num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
|
||||
|
|
@ -1179,23 +1217,34 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
|
|||
|
||||
|
||||
/* adjust our table of devices */
|
||||
for(i=0; i<num_luns; i++)
|
||||
{
|
||||
int devtype;
|
||||
|
||||
for (i = 0; i < num_luns; i++) {
|
||||
/* for each physical lun, do an inquiry */
|
||||
if (ld_buff->LUN[i][3] & 0xC0) continue;
|
||||
memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
|
||||
memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
|
||||
|
||||
if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
|
||||
(unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
|
||||
if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff,
|
||||
(unsigned char) OBDR_TAPE_INQ_SIZE) != 0)
|
||||
/* Inquiry failed (msg printed already) */
|
||||
devtype = 0; /* so we will skip this device. */
|
||||
} else /* what kind of device is this? */
|
||||
devtype = (inq_buff[0] & 0x1f);
|
||||
continue; /* so we will skip this device. */
|
||||
|
||||
switch (devtype)
|
||||
this_device->devtype = (inq_buff[0] & 0x1f);
|
||||
this_device->bus = -1;
|
||||
this_device->target = -1;
|
||||
this_device->lun = -1;
|
||||
memcpy(this_device->scsi3addr, scsi3addr, 8);
|
||||
memcpy(this_device->vendor, &inq_buff[8],
|
||||
sizeof(this_device->vendor));
|
||||
memcpy(this_device->model, &inq_buff[16],
|
||||
sizeof(this_device->model));
|
||||
memcpy(this_device->revision, &inq_buff[32],
|
||||
sizeof(this_device->revision));
|
||||
memset(this_device->device_id, 0,
|
||||
sizeof(this_device->device_id));
|
||||
cciss_scsi_get_device_id(hba[cntl_num], scsi3addr,
|
||||
this_device->device_id, sizeof(this_device->device_id));
|
||||
|
||||
switch (this_device->devtype)
|
||||
{
|
||||
case 0x05: /* CD-ROM */ {
|
||||
|
||||
|
|
@ -1220,15 +1269,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
|
|||
if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
|
||||
printk(KERN_INFO "cciss%d: %s ignored, "
|
||||
"too many devices.\n", cntl_num,
|
||||
scsi_device_type(devtype));
|
||||
scsi_device_type(this_device->devtype));
|
||||
break;
|
||||
}
|
||||
memcpy(¤tsd[ncurrent].scsi3addr[0],
|
||||
&scsi3addr[0], 8);
|
||||
currentsd[ncurrent].devtype = devtype;
|
||||
currentsd[ncurrent].bus = -1;
|
||||
currentsd[ncurrent].target = -1;
|
||||
currentsd[ncurrent].lun = -1;
|
||||
currentsd[ncurrent] = *this_device;
|
||||
ncurrent++;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1240,6 +1284,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
|
|||
out:
|
||||
kfree(inq_buff);
|
||||
kfree(ld_buff);
|
||||
kfree(currentsd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ struct cciss_scsi_dev_t {
|
|||
int devtype;
|
||||
int bus, target, lun; /* as presented to the OS */
|
||||
unsigned char scsi3addr[8]; /* as presented to the HW */
|
||||
unsigned char device_id[16]; /* from inquiry pg. 0x83 */
|
||||
unsigned char vendor[8]; /* bytes 8-15 of inquiry data */
|
||||
unsigned char model[16]; /* bytes 16-31 of inquiry data */
|
||||
unsigned char revision[4]; /* bytes 32-35 of inquiry data */
|
||||
};
|
||||
|
||||
struct cciss_scsi_hba_t {
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev)
|
|||
hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
|
||||
&(hba[i]->cmd_pool_dhandle));
|
||||
hba[i]->cmd_pool_bits = kcalloc(
|
||||
(NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long),
|
||||
DIV_ROUND_UP(NR_CMDS, BITS_PER_LONG), sizeof(unsigned long),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
|
||||
|
|
|
|||
|
|
@ -423,8 +423,15 @@ static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
|
|||
* 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
|
||||
* side 0 is on physical side 0 (but with the misnamed sector IDs).
|
||||
* 'stretch' should probably be renamed to something more general, like
|
||||
* 'options'. Other parameters should be self-explanatory (see also
|
||||
* setfdprm(8)).
|
||||
* 'options'.
|
||||
*
|
||||
* Bits 2 through 9 of 'stretch' tell the number of the first sector.
|
||||
* The LSB (bit 2) is flipped. For most disks, the first sector
|
||||
* is 1 (represented by 0x00<<2). For some CP/M and music sampler
|
||||
* disks (such as Ensoniq EPS 16plus) it is 0 (represented as 0x01<<2).
|
||||
* For Amstrad CPC disks it is 0xC1 (represented as 0xC0<<2).
|
||||
*
|
||||
* Other parameters should be self-explanatory (see also setfdprm(8)).
|
||||
*/
|
||||
/*
|
||||
Size
|
||||
|
|
@ -1355,20 +1362,20 @@ static void fdc_specify(void)
|
|||
}
|
||||
|
||||
/* Convert step rate from microseconds to milliseconds and 4 bits */
|
||||
srt = 16 - (DP->srt * scale_dtr / 1000 + NOMINAL_DTR - 1) / NOMINAL_DTR;
|
||||
srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR);
|
||||
if (slow_floppy) {
|
||||
srt = srt / 4;
|
||||
}
|
||||
SUPBOUND(srt, 0xf);
|
||||
INFBOUND(srt, 0);
|
||||
|
||||
hlt = (DP->hlt * scale_dtr / 2 + NOMINAL_DTR - 1) / NOMINAL_DTR;
|
||||
hlt = DIV_ROUND_UP(DP->hlt * scale_dtr / 2, NOMINAL_DTR);
|
||||
if (hlt < 0x01)
|
||||
hlt = 0x01;
|
||||
else if (hlt > 0x7f)
|
||||
hlt = hlt_max_code;
|
||||
|
||||
hut = (DP->hut * scale_dtr / 16 + NOMINAL_DTR - 1) / NOMINAL_DTR;
|
||||
hut = DIV_ROUND_UP(DP->hut * scale_dtr / 16, NOMINAL_DTR);
|
||||
if (hut < 0x1)
|
||||
hut = 0x1;
|
||||
else if (hut > 0xf)
|
||||
|
|
@ -2236,9 +2243,9 @@ static void setup_format_params(int track)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (_floppy->stretch & FD_ZEROBASED) {
|
||||
if (_floppy->stretch & FD_SECTBASEMASK) {
|
||||
for (count = 0; count < F_SECT_PER_TRACK; count++)
|
||||
here[count].sect--;
|
||||
here[count].sect += FD_SECTBASE(_floppy) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2385,7 +2392,7 @@ static void rw_interrupt(void)
|
|||
|
||||
#ifdef FLOPPY_SANITY_CHECK
|
||||
if (nr_sectors / ssize >
|
||||
(in_sector_offset + current_count_sectors + ssize - 1) / ssize) {
|
||||
DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) {
|
||||
DPRINT("long rw: %x instead of %lx\n",
|
||||
nr_sectors, current_count_sectors);
|
||||
printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
|
||||
|
|
@ -2649,7 +2656,7 @@ static int make_raw_rw_request(void)
|
|||
}
|
||||
HEAD = fsector_t / _floppy->sect;
|
||||
|
||||
if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) ||
|
||||
if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) ||
|
||||
TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect)
|
||||
max_sector = _floppy->sect;
|
||||
|
||||
|
|
@ -2679,7 +2686,7 @@ static int make_raw_rw_request(void)
|
|||
CODE2SIZE;
|
||||
SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE;
|
||||
SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) +
|
||||
((_floppy->stretch & FD_ZEROBASED) ? 0 : 1);
|
||||
FD_SECTBASE(_floppy);
|
||||
|
||||
/* tracksize describes the size which can be filled up with sectors
|
||||
* of size ssize.
|
||||
|
|
@ -3311,7 +3318,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
|
|||
g->head <= 0 ||
|
||||
g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
|
||||
/* check if reserved bits are set */
|
||||
(g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_ZEROBASED)) != 0)
|
||||
(g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
|
||||
return -EINVAL;
|
||||
if (type) {
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
|
@ -3356,7 +3363,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
|
|||
if (DRS->maxblock > user_params[drive].sect ||
|
||||
DRS->maxtrack ||
|
||||
((user_params[drive].sect ^ oldStretch) &
|
||||
(FD_SWAPSIDES | FD_ZEROBASED)))
|
||||
(FD_SWAPSIDES | FD_SECTBASEMASK)))
|
||||
invalidate_drive(bdev);
|
||||
else
|
||||
process_fd_request();
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ static int nbd_do_it(struct nbd_device *lo)
|
|||
BUG_ON(lo->magic != LO_MAGIC);
|
||||
|
||||
lo->pid = current->pid;
|
||||
ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr);
|
||||
ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "nbd: sysfs_create_file failed!");
|
||||
return ret;
|
||||
|
|
@ -412,7 +412,7 @@ static int nbd_do_it(struct nbd_device *lo)
|
|||
while ((req = nbd_read_stat(lo)) != NULL)
|
||||
nbd_end_request(req);
|
||||
|
||||
sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr);
|
||||
sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2544,7 +2544,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
|
|||
if (last_zone != zone) {
|
||||
BUG_ON(last_zone != zone + pd->settings.size);
|
||||
first_sectors = last_zone - bio->bi_sector;
|
||||
bp = bio_split(bio, bio_split_pool, first_sectors);
|
||||
bp = bio_split(bio, first_sectors);
|
||||
BUG_ON(!bp);
|
||||
pkt_make_request(q, &bp->bio1);
|
||||
pkt_make_request(q, &bp->bio2);
|
||||
|
|
@ -2911,7 +2911,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
|
|||
if (!disk->queue)
|
||||
goto out_mem2;
|
||||
|
||||
pd->pkt_dev = MKDEV(disk->major, disk->first_minor);
|
||||
pd->pkt_dev = MKDEV(pktdev_major, idx);
|
||||
ret = pkt_new_dev(pd, dev);
|
||||
if (ret)
|
||||
goto out_new_dev;
|
||||
|
|
|
|||
|
|
@ -199,7 +199,8 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
|
|||
if (blk_fs_request(req)) {
|
||||
if (ps3disk_submit_request_sg(dev, req))
|
||||
break;
|
||||
} else if (req->cmd_type == REQ_TYPE_FLUSH) {
|
||||
} else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
|
||||
req->cmd[0] == REQ_LB_OP_FLUSH) {
|
||||
if (ps3disk_submit_flush_request(dev, req))
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -257,7 +258,8 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (req->cmd_type == REQ_TYPE_FLUSH) {
|
||||
if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
|
||||
req->cmd[0] == REQ_LB_OP_FLUSH) {
|
||||
read = 0;
|
||||
num_sectors = req->hard_cur_sectors;
|
||||
op = "flush";
|
||||
|
|
@ -405,7 +407,8 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req)
|
|||
|
||||
dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
|
||||
|
||||
req->cmd_type = REQ_TYPE_FLUSH;
|
||||
req->cmd_type = REQ_TYPE_LINUX_BLOCK;
|
||||
req->cmd[0] = REQ_LB_OP_FLUSH;
|
||||
}
|
||||
|
||||
static unsigned long ps3disk_mask;
|
||||
|
|
@ -538,7 +541,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
|
|||
struct ps3disk_private *priv = dev->sbd.core.driver_data;
|
||||
|
||||
mutex_lock(&ps3disk_mask_mutex);
|
||||
__clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS,
|
||||
__clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
|
||||
&ps3disk_mask);
|
||||
mutex_unlock(&ps3disk_mask_mutex);
|
||||
del_gendisk(priv->gendisk);
|
||||
|
|
|
|||
|
|
@ -47,20 +47,20 @@ static void blk_done(struct virtqueue *vq)
|
|||
|
||||
spin_lock_irqsave(&vblk->lock, flags);
|
||||
while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) {
|
||||
int uptodate;
|
||||
int error;
|
||||
switch (vbr->status) {
|
||||
case VIRTIO_BLK_S_OK:
|
||||
uptodate = 1;
|
||||
error = 0;
|
||||
break;
|
||||
case VIRTIO_BLK_S_UNSUPP:
|
||||
uptodate = -ENOTTY;
|
||||
error = -ENOTTY;
|
||||
break;
|
||||
default:
|
||||
uptodate = 0;
|
||||
error = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
end_dequeued_request(vbr->req, uptodate);
|
||||
__blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req));
|
||||
list_del(&vbr->list);
|
||||
mempool_free(vbr, vblk->pool);
|
||||
}
|
||||
|
|
@ -84,11 +84,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
|
|||
if (blk_fs_request(vbr->req)) {
|
||||
vbr->out_hdr.type = 0;
|
||||
vbr->out_hdr.sector = vbr->req->sector;
|
||||
vbr->out_hdr.ioprio = vbr->req->ioprio;
|
||||
vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
|
||||
} else if (blk_pc_request(vbr->req)) {
|
||||
vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
|
||||
vbr->out_hdr.sector = 0;
|
||||
vbr->out_hdr.ioprio = vbr->req->ioprio;
|
||||
vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
|
||||
} else {
|
||||
/* We don't put anything else in the queue. */
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -105,15 +105,17 @@ static DEFINE_SPINLOCK(blkif_io_lock);
|
|||
#define GRANT_INVALID_REF 0
|
||||
|
||||
#define PARTS_PER_DISK 16
|
||||
#define PARTS_PER_EXT_DISK 256
|
||||
|
||||
#define BLKIF_MAJOR(dev) ((dev)>>8)
|
||||
#define BLKIF_MINOR(dev) ((dev) & 0xff)
|
||||
|
||||
#define DEV_NAME "xvd" /* name in /dev */
|
||||
#define EXT_SHIFT 28
|
||||
#define EXTENDED (1<<EXT_SHIFT)
|
||||
#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
|
||||
#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
|
||||
|
||||
/* Information about our VBDs. */
|
||||
#define MAX_VBDS 64
|
||||
static LIST_HEAD(vbds_list);
|
||||
#define DEV_NAME "xvd" /* name in /dev */
|
||||
|
||||
static int get_id_from_freelist(struct blkfront_info *info)
|
||||
{
|
||||
|
|
@ -386,31 +388,60 @@ static int xlvbd_barrier(struct blkfront_info *info)
|
|||
}
|
||||
|
||||
|
||||
static int xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity,
|
||||
int vdevice, u16 vdisk_info, u16 sector_size,
|
||||
struct blkfront_info *info)
|
||||
static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
||||
struct blkfront_info *info,
|
||||
u16 vdisk_info, u16 sector_size)
|
||||
{
|
||||
struct gendisk *gd;
|
||||
int nr_minors = 1;
|
||||
int err = -ENODEV;
|
||||
unsigned int offset;
|
||||
int minor;
|
||||
int nr_parts;
|
||||
|
||||
BUG_ON(info->gd != NULL);
|
||||
BUG_ON(info->rq != NULL);
|
||||
|
||||
if ((minor % PARTS_PER_DISK) == 0)
|
||||
nr_minors = PARTS_PER_DISK;
|
||||
if ((info->vdevice>>EXT_SHIFT) > 1) {
|
||||
/* this is above the extended range; something is wrong */
|
||||
printk(KERN_WARNING "blkfront: vdevice 0x%x is above the extended range; ignoring\n", info->vdevice);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!VDEV_IS_EXTENDED(info->vdevice)) {
|
||||
minor = BLKIF_MINOR(info->vdevice);
|
||||
nr_parts = PARTS_PER_DISK;
|
||||
} else {
|
||||
minor = BLKIF_MINOR_EXT(info->vdevice);
|
||||
nr_parts = PARTS_PER_EXT_DISK;
|
||||
}
|
||||
|
||||
if ((minor % nr_parts) == 0)
|
||||
nr_minors = nr_parts;
|
||||
|
||||
gd = alloc_disk(nr_minors);
|
||||
if (gd == NULL)
|
||||
goto out;
|
||||
|
||||
if (nr_minors > 1)
|
||||
sprintf(gd->disk_name, "%s%c", DEV_NAME,
|
||||
'a' + minor / PARTS_PER_DISK);
|
||||
else
|
||||
sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
|
||||
'a' + minor / PARTS_PER_DISK,
|
||||
minor % PARTS_PER_DISK);
|
||||
offset = minor / nr_parts;
|
||||
|
||||
if (nr_minors > 1) {
|
||||
if (offset < 26)
|
||||
sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset);
|
||||
else
|
||||
sprintf(gd->disk_name, "%s%c%c", DEV_NAME,
|
||||
'a' + ((offset / 26)-1), 'a' + (offset % 26));
|
||||
} else {
|
||||
if (offset < 26)
|
||||
sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
|
||||
'a' + offset,
|
||||
minor & (nr_parts - 1));
|
||||
else
|
||||
sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME,
|
||||
'a' + ((offset / 26) - 1),
|
||||
'a' + (offset % 26),
|
||||
minor & (nr_parts - 1));
|
||||
}
|
||||
|
||||
gd->major = XENVBD_MAJOR;
|
||||
gd->first_minor = minor;
|
||||
|
|
@ -699,8 +730,13 @@ static int blkfront_probe(struct xenbus_device *dev,
|
|||
err = xenbus_scanf(XBT_NIL, dev->nodename,
|
||||
"virtual-device", "%i", &vdevice);
|
||||
if (err != 1) {
|
||||
xenbus_dev_fatal(dev, err, "reading virtual-device");
|
||||
return err;
|
||||
/* go looking in the extended area instead */
|
||||
err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device-ext",
|
||||
"%i", &vdevice);
|
||||
if (err != 1) {
|
||||
xenbus_dev_fatal(dev, err, "reading virtual-device");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
|
|
@ -861,9 +897,7 @@ static void blkfront_connect(struct blkfront_info *info)
|
|||
if (err)
|
||||
info->feature_barrier = 0;
|
||||
|
||||
err = xlvbd_alloc_gendisk(BLKIF_MINOR(info->vdevice),
|
||||
sectors, info->vdevice,
|
||||
binfo, sector_size, info);
|
||||
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
|
||||
info->xbdev->otherend);
|
||||
|
|
|
|||
Loading…
Reference in a new issue