mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: loop: mutex already unlocked in loop_clr_fd() cfq-iosched: don't let idling interfere with plugging block: remove unused REQ_UNPLUG cfq-iosched: kill two unused cfqq flags cfq-iosched: change dispatch logic to deal with single requests at the time mflash: initial support cciss: change to discover first memory BAR cciss: kernel scan thread for MSA2012 cciss: fix residual count for block pc requests block: fix inconsistency in I/O stat accounting code block: elevator quiescing helpers
This commit is contained in:
commit
6a5d263866
18 changed files with 1624 additions and 149 deletions
|
|
@ -410,6 +410,23 @@ config ATA_OVER_ETH
|
|||
This driver provides Support for ATA over Ethernet block
|
||||
devices like the Coraid EtherDrive (R) Storage Blade.
|
||||
|
||||
config MG_DISK
|
||||
tristate "mGine mflash, gflash support"
|
||||
depends on ARM && ATA && GPIOLIB
|
||||
help
|
||||
mGine mFlash(gFlash) block device driver
|
||||
|
||||
config MG_DISK_RES
|
||||
int "Size of reserved area before MBR"
|
||||
depends on MG_DISK
|
||||
default 0
|
||||
help
|
||||
Define size of reserved area that usually used for boot. Unit is KB.
|
||||
All of the block device operation will be taken this value as start
|
||||
offset
|
||||
Examples:
|
||||
1024 => 1 MB
|
||||
|
||||
config SUNVDC
|
||||
tristate "Sun Virtual Disk Client support"
|
||||
depends on SUN_LDOMS
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
|
|||
obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
|
||||
obj-$(CONFIG_XILINX_SYSACE) += xsysace.o
|
||||
obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o
|
||||
obj-$(CONFIG_MG_DISK) += mg_disk.o
|
||||
obj-$(CONFIG_SUNVDC) += sunvdc.o
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_UMEM) += umem.o
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include <scsi/scsi_ioctl.h>
|
||||
#include <linux/cdrom.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
|
||||
#define DRIVER_NAME "HP CISS Driver (v 3.6.20)"
|
||||
|
|
@ -186,6 +187,8 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
|
|||
__u8 page_code, int cmd_type);
|
||||
|
||||
static void fail_all_cmds(unsigned long ctlr);
|
||||
static int scan_thread(void *data);
|
||||
static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static void cciss_procinit(int i);
|
||||
|
|
@ -735,6 +738,12 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c)
|
||||
{
|
||||
if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
|
||||
c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
|
||||
(void)check_for_unit_attention(host, c);
|
||||
}
|
||||
/*
|
||||
* ioctl
|
||||
*/
|
||||
|
|
@ -1029,6 +1038,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
|
|||
iocommand.buf_size,
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
|
||||
check_ioctl_unit_attention(host, c);
|
||||
|
||||
/* Copy the error information out */
|
||||
iocommand.error_info = *(c->err_info);
|
||||
if (copy_to_user
|
||||
|
|
@ -1180,6 +1191,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
|
|||
(dma_addr_t) temp64.val, buff_size[i],
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
}
|
||||
check_ioctl_unit_attention(host, c);
|
||||
/* Copy the error information out */
|
||||
ioc->error_info = *(c->err_info);
|
||||
if (copy_to_user(argp, ioc, sizeof(*ioc))) {
|
||||
|
|
@ -1287,6 +1299,7 @@ static void cciss_softirq_done(struct request *rq)
|
|||
{
|
||||
CommandList_struct *cmd = rq->completion_data;
|
||||
ctlr_info_t *h = hba[cmd->ctlr];
|
||||
unsigned int nr_bytes;
|
||||
unsigned long flags;
|
||||
u64bit temp64;
|
||||
int i, ddir;
|
||||
|
|
@ -1308,7 +1321,14 @@ static void cciss_softirq_done(struct request *rq)
|
|||
printk("Done with %p\n", rq);
|
||||
#endif /* CCISS_DEBUG */
|
||||
|
||||
if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
|
||||
/*
|
||||
* Store the full size and set the residual count for pc requests
|
||||
*/
|
||||
nr_bytes = blk_rq_bytes(rq);
|
||||
if (blk_pc_request(rq))
|
||||
rq->data_len = cmd->err_info->ResidualCnt;
|
||||
|
||||
if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, nr_bytes))
|
||||
BUG();
|
||||
|
||||
spin_lock_irqsave(&h->lock, flags);
|
||||
|
|
@ -2585,12 +2605,14 @@ static inline unsigned int make_status_bytes(unsigned int scsi_status_byte,
|
|||
((driver_byte & 0xff) << 24);
|
||||
}
|
||||
|
||||
static inline int evaluate_target_status(CommandList_struct *cmd)
|
||||
static inline int evaluate_target_status(ctlr_info_t *h,
|
||||
CommandList_struct *cmd, int *retry_cmd)
|
||||
{
|
||||
unsigned char sense_key;
|
||||
unsigned char status_byte, msg_byte, host_byte, driver_byte;
|
||||
int error_value;
|
||||
|
||||
*retry_cmd = 0;
|
||||
/* If we get in here, it means we got "target status", that is, scsi status */
|
||||
status_byte = cmd->err_info->ScsiStatus;
|
||||
driver_byte = DRIVER_OK;
|
||||
|
|
@ -2618,6 +2640,11 @@ static inline int evaluate_target_status(CommandList_struct *cmd)
|
|||
if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq))
|
||||
error_value = 0;
|
||||
|
||||
if (check_for_unit_attention(h, cmd)) {
|
||||
*retry_cmd = !blk_pc_request(cmd->rq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
|
||||
if (error_value != 0)
|
||||
printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
|
||||
|
|
@ -2657,7 +2684,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
|
|||
|
||||
switch (cmd->err_info->CommandStatus) {
|
||||
case CMD_TARGET_STATUS:
|
||||
rq->errors = evaluate_target_status(cmd);
|
||||
rq->errors = evaluate_target_status(h, cmd, &retry_cmd);
|
||||
break;
|
||||
case CMD_DATA_UNDERRUN:
|
||||
if (blk_fs_request(cmd->rq)) {
|
||||
|
|
@ -3008,6 +3035,63 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int scan_thread(void *data)
|
||||
{
|
||||
ctlr_info_t *h = data;
|
||||
int rc;
|
||||
DECLARE_COMPLETION_ONSTACK(wait);
|
||||
h->rescan_wait = &wait;
|
||||
|
||||
for (;;) {
|
||||
rc = wait_for_completion_interruptible(&wait);
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
if (!rc)
|
||||
rebuild_lun_table(h, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
|
||||
{
|
||||
if (c->err_info->SenseInfo[2] != UNIT_ATTENTION)
|
||||
return 0;
|
||||
|
||||
switch (c->err_info->SenseInfo[12]) {
|
||||
case STATE_CHANGED:
|
||||
printk(KERN_WARNING "cciss%d: a state change "
|
||||
"detected, command retried\n", h->ctlr);
|
||||
return 1;
|
||||
break;
|
||||
case LUN_FAILED:
|
||||
printk(KERN_WARNING "cciss%d: LUN failure "
|
||||
"detected, action required\n", h->ctlr);
|
||||
return 1;
|
||||
break;
|
||||
case REPORT_LUNS_CHANGED:
|
||||
printk(KERN_WARNING "cciss%d: report LUN data "
|
||||
"changed\n", h->ctlr);
|
||||
if (h->rescan_wait)
|
||||
complete(h->rescan_wait);
|
||||
return 1;
|
||||
break;
|
||||
case POWER_OR_RESET:
|
||||
printk(KERN_WARNING "cciss%d: a power on "
|
||||
"or device reset detected\n", h->ctlr);
|
||||
return 1;
|
||||
break;
|
||||
case UNIT_ATTENTION_CLEARED:
|
||||
printk(KERN_WARNING "cciss%d: unit attention "
|
||||
"cleared by another initiator\n", h->ctlr);
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING "cciss%d: unknown "
|
||||
"unit attention detected\n", h->ctlr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We cannot read the structure directly, for portability we must use
|
||||
* the io functions.
|
||||
|
|
@ -3181,12 +3265,21 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
|
|||
*/
|
||||
cciss_interrupt_mode(c, pdev, board_id);
|
||||
|
||||
/*
|
||||
* Memory base addr is first addr , the second points to the config
|
||||
* table
|
||||
*/
|
||||
/* find the memory BAR */
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
if (pci_resource_flags(pdev, i) & IORESOURCE_MEM)
|
||||
break;
|
||||
}
|
||||
if (i == DEVICE_COUNT_RESOURCE) {
|
||||
printk(KERN_WARNING "cciss: No memory BAR found\n");
|
||||
err = -ENODEV;
|
||||
goto err_out_free_res;
|
||||
}
|
||||
|
||||
c->paddr = pci_resource_start(pdev, i); /* addressing mode bits
|
||||
* already removed
|
||||
*/
|
||||
|
||||
c->paddr = pci_resource_start(pdev, 0); /* addressing mode bits already removed */
|
||||
#ifdef CCISS_DEBUG
|
||||
printk("address 0 = %lx\n", c->paddr);
|
||||
#endif /* CCISS_DEBUG */
|
||||
|
|
@ -3753,6 +3846,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
|||
hba[i]->busy_initializing = 0;
|
||||
|
||||
rebuild_lun_table(hba[i], 1);
|
||||
hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
|
||||
"cciss_scan%02d", i);
|
||||
if (IS_ERR(hba[i]->cciss_scan_thread))
|
||||
return PTR_ERR(hba[i]->cciss_scan_thread);
|
||||
|
||||
return 1;
|
||||
|
||||
clean4:
|
||||
|
|
@ -3828,6 +3926,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
|
|||
printk(KERN_ERR "cciss: Unable to remove device \n");
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_ptr = pci_get_drvdata(pdev);
|
||||
i = tmp_ptr->ctlr;
|
||||
if (hba[i] == NULL) {
|
||||
|
|
@ -3836,6 +3935,8 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
|
|||
return;
|
||||
}
|
||||
|
||||
kthread_stop(hba[i]->cciss_scan_thread);
|
||||
|
||||
remove_proc_entry(hba[i]->devname, proc_cciss);
|
||||
unregister_blkdev(hba[i]->major, hba[i]->devname);
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ struct ctlr_info
|
|||
struct sendcmd_reject_list scsi_rejects;
|
||||
#endif
|
||||
unsigned char alive;
|
||||
struct completion *rescan_wait;
|
||||
struct task_struct *cciss_scan_thread;
|
||||
};
|
||||
|
||||
/* Defining the diffent access_menthods */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,29 @@
|
|||
#define CMD_TIMEOUT 0x000B
|
||||
#define CMD_UNABORTABLE 0x000C
|
||||
|
||||
/* Unit Attentions ASC's as defined for the MSA2012sa */
|
||||
#define POWER_OR_RESET 0x29
|
||||
#define STATE_CHANGED 0x2a
|
||||
#define UNIT_ATTENTION_CLEARED 0x2f
|
||||
#define LUN_FAILED 0x3e
|
||||
#define REPORT_LUNS_CHANGED 0x3f
|
||||
|
||||
/* Unit Attentions ASCQ's as defined for the MSA2012sa */
|
||||
|
||||
/* These ASCQ's defined for ASC = POWER_OR_RESET */
|
||||
#define POWER_ON_RESET 0x00
|
||||
#define POWER_ON_REBOOT 0x01
|
||||
#define SCSI_BUS_RESET 0x02
|
||||
#define MSA_TARGET_RESET 0x03
|
||||
#define CONTROLLER_FAILOVER 0x04
|
||||
#define TRANSCEIVER_SE 0x05
|
||||
#define TRANSCEIVER_LVD 0x06
|
||||
|
||||
/* These ASCQ's defined for ASC = STATE_CHANGED */
|
||||
#define RESERVATION_PREEMPTED 0x03
|
||||
#define ASYM_ACCESS_CHANGED 0x06
|
||||
#define LUN_CAPACITY_CHANGED 0x09
|
||||
|
||||
//transfer direction
|
||||
#define XFER_NONE 0x00
|
||||
#define XFER_WRITE 0x01
|
||||
|
|
|
|||
|
|
@ -1431,6 +1431,7 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
|
|||
static int lo_release(struct gendisk *disk, fmode_t mode)
|
||||
{
|
||||
struct loop_device *lo = disk->private_data;
|
||||
int err;
|
||||
|
||||
mutex_lock(&lo->lo_ctl_mutex);
|
||||
|
||||
|
|
@ -1442,7 +1443,9 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
|
|||
* In autoclear mode, stop the loop thread
|
||||
* and remove configuration after last close.
|
||||
*/
|
||||
loop_clr_fd(lo, NULL);
|
||||
err = loop_clr_fd(lo, NULL);
|
||||
if (!err)
|
||||
goto out_unlocked;
|
||||
} else {
|
||||
/*
|
||||
* Otherwise keep thread (if running) and config,
|
||||
|
|
@ -1453,7 +1456,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
|
|||
|
||||
out:
|
||||
mutex_unlock(&lo->lo_ctl_mutex);
|
||||
|
||||
out_unlocked:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
1005
drivers/block/mg_disk.c
Normal file
1005
drivers/block/mg_disk.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue