📄 i2o_block.c
字号:
struct request_queue *q; u8 st; unsigned long flags; /* FAILed message */ if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) { struct i2o_message *pmsg; u32 pm; /* * FAILed message from controller * We increment the error count and abort it * * In theory this will never happen. The I2O block class * specification states that block devices never return * FAILs but instead use the REQ status field...but * better be on the safe side since no one really follows * the spec to the book :) */ pm = le32_to_cpu(msg->body[3]); pmsg = i2o_msg_in_to_virt(c, pm); req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt)); if (unlikely(!req)) { osm_err("NULL reply received!\n"); return -1; } ireq = req->special; dev = ireq->i2o_blk_dev; q = dev->gd->queue; req->errors++; spin_lock_irqsave(q->queue_lock, flags); while (end_that_request_chunk(req, !req->errors, le32_to_cpu(pmsg->body[1]))) ; end_that_request_last(req); dev->open_queue_depth--; list_del(&ireq->queue); blk_start_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); /* Now flush the message by making it a NOP */ i2o_msg_nop(c, pm); return -1; } req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); if (unlikely(!req)) { osm_err("NULL reply received!\n"); return -1; } ireq = req->special; dev = ireq->i2o_blk_dev; q = dev->gd->queue; if (unlikely(!dev->i2o_dev)) { /* * This is HACK, but Intel Integrated RAID allows user * to delete a volume that is claimed, locked, and in use * by the OS. We have to check for a reply from a * non-existent device and flag it as an error or the system * goes kaput... */ req->errors++; osm_warn("Data transfer to deleted device!\n"); spin_lock_irqsave(q->queue_lock, flags); while (end_that_request_chunk (req, !req->errors, le32_to_cpu(msg->body[1]))) ; end_that_request_last(req); dev->open_queue_depth--; list_del(&ireq->queue); blk_start_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); return -1; } /* * Lets see what is cooking. We stuffed the * request in the context. */ st = le32_to_cpu(msg->body[0]) >> 24; if (st != 0) { int err; char *bsa_errors[] = { "Success", "Media Error", "Failure communicating to device", "Device Failure", "Device is not ready", "Media not present", "Media is locked by another user", "Media has failed", "Failure communicating to device", "Device bus failure", "Device is locked by another user", "Device is write protected", "Device has reset", "Volume has changed, waiting for acknowledgement" }; err = le32_to_cpu(msg->body[0]) & 0xffff; /* * Device not ready means two things. One is that the * the thing went offline (but not a removal media) * * The second is that you have a SuperTrak 100 and the * firmware got constipated. Unlike standard i2o card * setups the supertrak returns an error rather than * blocking for the timeout in these cases. * * Don't stick a supertrak100 into cache aggressive modes */ osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name, bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]); if (le32_to_cpu(msg->body[0]) & 0x00ff0000) printk(KERN_ERR " - DDM attempted %d retries", (le32_to_cpu(msg->body[0]) >> 16) & 0x00ff); printk(KERN_ERR ".\n"); req->errors++; } else req->errors = 0; if (!end_that_request_chunk (req, !req->errors, le32_to_cpu(msg->body[1]))) { add_disk_randomness(req->rq_disk); spin_lock_irqsave(q->queue_lock, flags); end_that_request_last(req); dev->open_queue_depth--; list_del(&ireq->queue); blk_start_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); i2o_block_sglist_free(ireq); i2o_block_request_free(ireq); } else osm_err("still remaining chunks\n"); return 1;};static void i2o_block_event(struct i2o_event *evt){ osm_info("block-osm: event received\n");};/* * SCSI-CAM for ioctl geometry mapping * Duplicated with SCSI - this should be moved into somewhere common * perhaps genhd ? * * LBA -> CHS mapping table taken from: * * "Incorporating the I2O Architecture into BIOS for Intel Architecture * Platforms" * * This is an I2O document that is only available to I2O members, * not developers. * * From my understanding, this is how all the I2O cards do this * * Disk Size | Sectors | Heads | Cylinders * ---------------+---------+-------+------------------- * 1 < X <= 528M | 63 | 16 | X/(63 * 16 * 512) * 528M < X <= 1G | 63 | 32 | X/(63 * 32 * 512) * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512) * 1 < X <528M | 63 | 16 | X/(63 * 16 * 512) * */#define BLOCK_SIZE_528M 1081344#define BLOCK_SIZE_1G 2097152#define BLOCK_SIZE_21G 4403200#define BLOCK_SIZE_42G 8806400#define BLOCK_SIZE_84G 17612800static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls, unsigned char *hds, unsigned char *secs){ unsigned long heads, sectors, cylinders; sectors = 63L; /* Maximize sectors per track */ if (capacity <= BLOCK_SIZE_528M) heads = 16; else if (capacity <= BLOCK_SIZE_1G) heads = 32; else if (capacity <= BLOCK_SIZE_21G) heads = 64; else if (capacity <= BLOCK_SIZE_42G) heads = 128; else heads = 255; cylinders = (unsigned long)capacity / (heads * sectors); *cyls = (unsigned short)cylinders; /* Stuff return values */ *secs = (unsigned char)sectors; *hds = (unsigned char)heads;}/** * i2o_block_open - Open the block device * * Power up the device, mount and lock the media. This function is called, * if the block device is opened for access. * * Returns 0 on success or negative error code on failure. */static int i2o_block_open(struct inode *inode, struct file *file){ struct i2o_block_device *dev = inode->i_bdev->bd_disk->private_data; if (!dev->i2o_dev) return -ENODEV; if (dev->power > 0x1f) i2o_block_device_power(dev, 0x02); i2o_block_device_mount(dev->i2o_dev, -1); i2o_block_device_lock(dev->i2o_dev, -1); osm_debug("Ready.\n"); return 0;};/** * i2o_block_release - Release the I2O block device * * Unlock and unmount the media, and power down the device. Gets called if * the block device is closed. * * Returns 0 on success or negative error code on failure. */static int i2o_block_release(struct inode *inode, struct file *file){ struct gendisk *disk = inode->i_bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; u8 operation; /* * This is to deail with the case of an application * opening a device and then the device dissapears while * it's in use, and then the application tries to release * it. ex: Unmounting a deleted RAID volume at reboot. * If we send messages, it will just cause FAILs since * the TID no longer exists. */ if (!dev->i2o_dev) return 0; i2o_block_device_flush(dev->i2o_dev); i2o_block_device_unlock(dev->i2o_dev, -1); if (dev->flags & (1 << 3 | 1 << 4)) /* Removable */ operation = 0x21; else operation = 0x24; i2o_block_device_power(dev, operation); return 0;}/** * i2o_block_ioctl - Issue device specific ioctl calls. * @cmd: ioctl command * @arg: arg * * Handles ioctl request for the block device. * * Return 0 on success or negative error on failure. */static int i2o_block_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ struct gendisk *disk = inode->i_bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; void __user *argp = (void __user *)arg; /* Anyone capable of this syscall can do *real bad* things */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; switch (cmd) { case HDIO_GETGEO: { struct hd_geometry g; i2o_block_biosparam(get_capacity(disk), &g.cylinders, &g.heads, &g.sectors); g.start = get_start_sect(inode->i_bdev); return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0; } case BLKI2OGRSTRAT: return put_user(dev->rcache, (int __user *)arg); case BLKI2OGWSTRAT: return put_user(dev->wcache, (int __user *)arg); case BLKI2OSRSTRAT: if (arg < 0 || arg > CACHE_SMARTFETCH) return -EINVAL; dev->rcache = arg; break; case BLKI2OSWSTRAT: if (arg != 0 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) return -EINVAL; dev->wcache = arg; break; } return -ENOTTY;};/** * i2o_block_media_changed - Have we seen a media change? * @disk: gendisk which should be verified * * Verifies if the media has changed. * * Returns 1 if the media was changed or 0 otherwise. */static int i2o_block_media_changed(struct gendisk *disk){ struct i2o_block_device *p = disk->private_data; if (p->media_change_flag) { p->media_change_flag = 0; return 1; } return 0;}/** * i2o_block_transfer - Transfer a request to/from the I2O controller * @req: the request which should be transfered * * This function converts the request into a I2O message. The necessary * DMA buffers are allocated and after everything is setup post the message * to the I2O controller. No cleanup is done by this function. It is done * on the interrupt side when the reply arrives. * * Return 0 on success or negative error code on failure. */static int i2o_block_transfer(struct request *req){ struct i2o_block_device *dev = req->rq_disk->private_data; struct i2o_controller *c = dev->i2o_dev->iop; int tid = dev->i2o_dev->lct_data.tid; struct i2o_message __iomem *msg; void __iomem *mptr; struct i2o_block_request *ireq = req->special; struct scatterlist *sg; int sgnum; int i; u32 m; u32 tcntxt; u32 sg_flags; int rc; m = i2o_msg_get(c, &msg); if (m == I2O_QUEUE_EMPTY) { rc = -EBUSY; goto exit; } tcntxt = i2o_cntxt_list_add(c, req); if (!tcntxt) { rc = -ENOMEM; goto nop_msg; } if ((sgnum = i2o_block_sglist_alloc(ireq)) <= 0) { rc = -ENOMEM; goto context_remove; } /* Build the message based on the request. */ writel(i2o_block_driver.context, &msg->u.s.icntxt); writel(tcntxt, &msg->u.s.tcntxt); writel(req->nr_sectors << 9, &msg->body[1]); writel((((u64) req->sector) << 9) & 0xffffffff, &msg->body[2]); writel(req->sector >> 23, &msg->body[3]); mptr = &msg->body[4]; sg = ireq->sg_table; if (rq_data_dir(req) == READ) { writel(I2O_CMD_BLOCK_READ << 24 | HOST_TID << 12 | tid, &msg->u.head[1]); sg_flags = 0x10000000; switch (dev->rcache) { case CACHE_NULL: writel(0, &msg->body[0]); break; case CACHE_PREFETCH: writel(0x201F0008, &msg->body[0]); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -