text:
Keeping Remote Employees Engaged – How Technical Teams are Responding to Covid-19
Keeping Remote Employees Engaged – How Technical Teams are Responding to Covid-19.
According to Deloitte, 87% of today's business leaders cite culture and engagement as one of their top concerns. And a worldwide Gallup poll found that only 13% of employees stated they are actually engaged at work.
Before we were all forced to work in isolation as a result of Covid-19, employee engagement was something that many business leaders spent significant time trying to figure out.
Traditionally, engagement was viewed as a stand-alone problem. This leads leaders to think that if they could just solve the issue of engagement, they'd suddenly have a more productive, higher-performing workforce. But genuine employee engagement is woven into the very fabric of the organisation – the leadership, culture, communication, and talent development. When you begin to create change in one of these areas, it creates a ripple that affects many others.
But now, when teams are forced to operate apart from each other, true engagement is more important than ever.
To contribute to the employee engagement conversation during this time, we reached out to technical teams around the world who were now operating with distributed teams. We asked them a number of questions and now we're sharing their answers in these articles in the hopes that their stories might provide inspiration while adjusting to new and unusual working practices.
We recommend checking the World Health Organisation's website for the most accurate and up to date information on Covid-19.
Three Key Drivers of Employee Engagement
Before we get into the team's comments, it's important to note what drives engagement.
A 2012 report published by Dale Carnegie Training found the three key drivers of engagement.
We offer these 'key drivers' forward with full recognition that there will never be a silver bullet for what keeps employees engaged, people are just too complicated. Instead, think of these more as good places to start when considering how you can improve your employee engagement.
1. Relationship with immediate supervisor
The person responsible for your day to day success is usually the person you trust and listen to the most.
As business leaders it's sometimes best to concede that you're never going to be able to get enough time with each individual person to develop that one-to-one relationship immediate supervisors have.
So, take a step back.
Work closely with direct supervisors to support them with this relationship. Coach them on behaviours to look out, steps to take and empower them to build that relationship to keep key staff engaged.
2. Belief in senior leadership
That said, senior leadership still sets the tone and direction of the company. It's up to senior leadership to give the overall direction of the company, ensuring that it's clearly communicated and easy to understand.
Where possible, you should strive to make this a collaborative venture. Reach out to your staff and ask for their thoughts on the direction of the company.
3. Pride in working for the company
Hearing people talk about working for your company with pride is the hallmark of a company that cares and engages employees.
Think about your Corporate Social Responsibility (CSR) now more than ever, when companies who have the resources can make a real difference to employees who may find themselves at significant risk.
As you read the stories from technical teams still operating you'll notice a few of these 'drivers' being talked about as key elements for engagement.
How Technical Teams Across Europe Are Maintaining Remote Employee Engagement
We spoke to a wide range of different technical team leaders about how they're coping with the current climate.
Of particular interest was how they're continuing to maintain employee engagement while everyone operates remotely.
The UK was put into lockdown on 23 March in an unprecedented step to attempt to limit the spread of coronavirus.
Schools, public spaces and places of work were closed down to halt the spread. For those that weren't already working from home, this announcement signalled the start of a period of isolation for many of the working force in the UK.
We spoke to a few tech leaders in the UK to see what they're doing to support the staff who continue to work for them remotely.
Claire Thompson, CEO, Agility Health
Claire Thompson is the CEO of Agility Health and an Award-winning pharmaceutical scientist, strategist and innovator with 15 + years' experience in developing pharmaceutical products in global companies, virtual biotechs and contract research organisations (CROs).
Now in amongst Covid-19 outbreak, Claire and her team at Agility Health continue consulting globally to healthcare and technology companies, ranging from spin-out to multinational companies, on how to fast track their technologies to market and help them to convey the benefits of their science through impactful communications.
With her team now distributed and working from completely different locations and in completely different situations, she's had to get creative with how she keeps her colleagues engaged.
"Well over half of all of my colleagues have children at home and at times like these, people's priorities are naturally shifted."
The natural response for business leaders might be to double down on routine and provide structured days for staff who would normally be around for physical check-ins.
Claire, however, believes her more trusting approach is leading to increased engagement and increased productivity.
"We have a WhatsApp group to stay connected, as well as video calls with all staff and customers."
And this approach may well be fostering increased productivity, as according to a peoplemanagement.com survey, 39 percent of people who mostly work from home often work additional hours to complete their tasks compared with 24 percent of those in fixed workplaces. On average, those who work remotely work an extra two hours over their 'in-office' colleagues. This is largely attributed to not being reliant on office equipment and being set up easily at home to handle requests at any hour.
Many remote working critics will tell you that it's the isolation and lack of presence in the team that damages engagement and productivity. And while it's certainly true that someone working from home would be missing out on the workplace banter, the access to other people's feedback and thoughts with just a swivel of a chair.
But in some situations, those things are the problem. The workplace itself may be a source of massive distraction for those who need to get stuck in to deep, complicated work. In a 2019 Flex survey, it was found that 75 percent of people choose to work remotely because there are fewer distractions.
Subscribing to this methodology, Claire trusts her colleagues to get the job done, but she still holds herself accountable to meeting regularly.
"80% of my workforce have children including her – Wellbeing over workload is my motto."
Chris Gilbert, Head of Software Development @ Blue chip
Blue Chip is a British based technology company that provides the infrastructure and hardware maintenance behind many of the largest brands in the UK.
"I manage the software side. We write our own data centre monitoring software, we manage the internal applications, we're doing infrastructure automation, and predictive analytics."
Chris has 30 direct reports and an additional 20 software developers who he is accountable for. Like with most software development teams, Chris and his team operate with a high level of autonomy, transparency and flexibility.
"It's the expectation of software devs to not have to be in the office. We also have another development team in Sri Lanka so it's a necessity we can work seamlessly while remote."
Engagement with his team has been seamless with little to no direct changing being made to how they operate on a day to day. Where major changes in employee engagement are being seen are in the wider business.
"A lot of the tools we've introduced to the business have now proved absolutely critical. Tools software have been using internally, like Zoom, JIRA , these tools that allow transparency and ease of communication are now being adopted by the wider business with our guidance."
Chris expects to see this becoming commonplace and suspects many businesses will now begin to widely adopt software development working processes and practices after the lockdown is lifted. Those who have worked through this period will come out the otherside with a new frame of mind around how they can and should be working. Something that many will hope will rub off on senior leadership leading a step in the right direction towards more flexible working for all.
"I also expect the framing of questions to be changed. I used to be asked, 'why aren't the devs in the office'. Now i'm hoping i'll be asked: 'Why don't the developers need to be in the office?'"
But of course, engagement isn't always a question of what processes or tools you can provide, employee engagement at these times is also about what you maybe shouldn't be doing. This 'disruption avoidance' was something Chris witnessed in the early weeks of lockdown at Blue Chip.
"For the business, there was a reluctance to push on with things that might cause disruption, justifiably so. Major projects or delivery of projects that would change the way people work were being delayed and paused."
But instead of pausing these projects completely, Chris' team found a way to provide the same level of support the wider team expects when onboarding new software.
"We had a major software release that was paused but now it's being released. People are used to someone coming over to their desk to walk them through it, instead, we developed video walkthroughs and dedicated time to onboard people virtually."
But it's not all work at Blue Chip with the business enjoying a raft of engaging non-work related activities designed to not just keep staff engaged, but their families too.
"We've got a really good L&D guy who has done some amazing work with virtual breakfasts, we have a kids club on Wednesday. These are all done over zoom. This really helps people get over the lack of social interaction."
Strategies in the Nordic countries have been different from that of the UK and European countries, with some countries, like Sweden, only just entering full lockdown at the start of April.
We connected with a few Technical leaders in the Nordics to discuss how they're responding to the outbreak and how they're keeping technical staff engaged.
Fredrik Mistander – CEO at Invoier
Fredrik Mistander is the CEO @ Invoier, a Swedish company that specializes in billing analysis and provides a marketplace for factoring services.
"A friend of mine called me up and said i should look into the 'factoring business'. I wasn't convinced at first – after having had a past in gambling I didn't know if I wanted to be in another business grey zone. Then I realised this was a huge societal problem and we could really make a difference."
A passionate snowboarder who had one too many crashes, Fredrik, along with a few of his friends, founded Invoier with the goal to help SME's with their finances.
Having successfully established itself in the Nordics market, Invoier secured funding to expand into Europe before the outbreak of Covid-19, and aren't looking to slow down. They're currently upscaling their team during the Covid-19 crisis with their last hire being made just 3 weeks prior to the publishing of this piece.
With financial backing and a strong product, Invoier is able to continue to run interviews and look for the technical talent that will ensure the success of their European expansion.
But, like most companies who want to maintain their growth, changes have had to be made.
And one big item for discussion for many tech teams as they enter the murky waters of business during Covid-19 is the place of consultants and contractors. Many will see the quick cost-saving opportunity in letting contractors and consultants go, but others will see the opportunity to quickly scale their productivity with technical talent who are already used to working in remote conditions. For Fredrik and Invoier, it isn't just the scaling of talent and productivity that needs to be considered, but also the scaling of culture and engagement.
"With the funding in order we have a split strategy when it comes to building a team. Part of the budget is focused on hiring consultants while the remaining part is reserved for finding long term talent to build a permanent team."
"But we have to consider building the company value, in regards to VC's, who not only want to see the product building but also the team. Our investors want to see the team growing in people who are committed to the company, and that can be hard when you work with consultants."
Invoier will continue to advertise for both permanent and consultancy roles and are adjusting the way they onboard and engage with this talent. With Fredrik putting particular emphasis on ensuring the company has communicated the impact they want to make.
"We just need to stay on top of our culture and our offerings, making sure we provide our team with fun challenges. We focus on building a culture and a strong employer brand, not only specifically for tech tasks, but also the overall goal of the company and what kind of impact we want to make?"
But how do you do that when your teams are already stretched and your face-to-face contact is restricted? For Invoier, it's about taking time to find hires that set a president.
"So the first person we brought along, she set the company structure in terms of values and culture. We're hoping the people who follow will have the same methodology. We want that to be the secret sauce for keeping staff for the long haul."
One of the benefits of working in technical teams is that the decision to close public and working spaces will not pose too much of a problem to teams who are largely all integrated using remote tools. The problem, which Fredrik and Invoier quickly found, was keeping staff, particularly new hires engaged without face-to-face contact.
"We have a new member of the team. She's been here for three weeks and we've only met her twice. It's hard to build connections between the team. All of us look forward to being back to a normal office 9-5. At least for a few weeks."
Fredrik ensures that his teams attend regular 'Fika Breaks' and makes sure he catches up with everyone he can on 'walks and talks' where possible, especially when he's looking to hire for a new role.
"You always want to meet the person at least once but probably at this stage, we're having two interviews later which will be a video call and the next stage will be a walk and talk. We can take a walk, but we can't talk too much. So we had to change the way we interview. Less question and answer and more a discussion around their skills with a follow-up exercise."
Marcus Ljungberg, Tech Lead at Ping Pong AB
Marcus Ljungberg is Tech lead at Ping Pong AB, which offers a platform for education with various functions for tests, questionnaires, and assignments. Ping Pong school, academy, business, and government sectors in Sweden.
"My role is Tech lead, which is more hands-on. I code every day. We're a team of 7, including myself."
Day to day at Ping Pong AB has largely been unaffected, with more schools closing and being forced to use systems like the one Ping Pong AB designed and operates. Their adjustments come in the form of challenges facing a team used to seeing each other every day now only seeing each other over video.
"As a team, of course it has affected us. When I was at Klarna it was a lot of pair programming and mob programming and we tried to take that methodology over to Ping Pong. It didn't really work.
We have pivoted into dividing stuff. We use Slack as an instant messaging service and hangouts. We have spent more time trying out and looking for new tools than we will actually spend in them.
We also started using Discord so we could have different themed channels people could jump in and out of, to try and replicate the 'team environment' we had in the office."
The idea of setting up different channels themed around certain projects is an attractive one. It maintains the same 'compartmentalized' feeling of a regular working day and gives you a physical 'switch over' to compliment the mental one you make when you move on to another task.
Another important note for Marcus and his team is ensuring that processes are still followed.
"We're still making sure we're focusing people on the 'works in progress'. When you're working from home people get sloppy on aligning their workdays. If you don't have kids or a family, some people start twisting their hours and before you know it you're working at night.
So we make sure we have tools like Trello to help people stay on track."
Marcus' team has halted hiring for now but other technical teams in Ping Pong AB are continuing to look at both permanent and consultancy based talent, an approach that Marcus believes in wholeheartedly.
"When this is over, it's going to be a boom. If you invest in talent now I'm certain you will gain later.
Generally, a lot of people are cutting consultants because of cost and in three months' time they will rehire them. But for me, it's too hasty to do that."
How Are You Keeping Your Employees Engaged Through Covid-19?
Have you got a story you want to share? If you're a hiring manager who is working hard to create an engaging employee experience or someone who has benefitted from a different approach to engagement, we want to hear from you.


text:
/*
 * Emulation of a SCSI host adapter for IDE ATAPI devices.
 *
 * With this driver, one can use the Linux SCSI drivers instead of the
 * native IDE ATAPI drivers.
 *
 * Ver 0.1   Dec  3 96   Initial version.
 * Ver 0.2   Jan 26 97   Fixed bug in cleanup_module() and added emulation
 *                        of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks
 *                        to Janos Farkas for pointing this out.
 *                       Avoid using bitfields in structures for m68k.
 *                       Added Scatter/Gather and DMA support.
 * Ver 0.4   Dec  7 97   Add support for ATAPI PD/CD drives.
 *                       Use variable timeout for each command.
 * Ver 0.5   Jan  2 98   Fix previous PD/CD support.
 *                       Allow disabling of SCSI-6 to SCSI-10 transformation.
 * Ver 0.6   Jan 27 98   Allow disabling of SCSI command translation layer
 *                        for access through /dev/sg.
 *                       Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.
 * Ver 0.7   Dec 04 98   Ignore commands where lun != 0 to avoid multiple
 *                        detection of devices with CONFIG_SCSI_MULTI_LUN
 * Ver 0.8   Feb 05 99   Optical media need translation too. Reverse 0.7.
 * Ver 0.9   Jul 04 99   Fix a bug in SG_SET_TRANSFORM.
 * Ver 0.91  Jun 10 02   Fix "off by one" error in transforms
 * Ver 0.92  Dec 31 02   Implement new SCSI mid level API
 */

#define IDESCSI_VERSION "0.92"

#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/slab.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/mutex.h>

#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/sg.h>

#define IDESCSI_DEBUG_LOG		0

typedef struct idescsi_pc_s {
	u8 c[12];				/* Actual packet bytes */
	int request_transfer;			/* Bytes to transfer */
	int actually_transferred;		/* Bytes actually transferred */
	int buffer_size;			/* Size of our data buffer */
	struct request *rq;			/* The corresponding request */
	u8 *buffer;				/* Data buffer */
	u8 *current_position;			/* Pointer into the above buffer */
	struct scatterlist *sg;			/* Scatter gather table */
	int b_count;				/* Bytes transferred from current entry */
	struct scsi_cmnd *scsi_cmd;		/* SCSI command */
	void (*done)(struct scsi_cmnd *);	/* Scsi completion routine */
	unsigned long flags;			/* Status/Action flags */
	unsigned long timeout;			/* Command timeout */
} idescsi_pc_t;

/*
 *	Packet command status bits.
 */
#define PC_DMA_IN_PROGRESS		0	/* 1 while DMA in progress */
#define PC_WRITING			1	/* Data direction */
#define PC_TRANSFORM			2	/* transform SCSI commands */
#define PC_TIMEDOUT			3	/* command timed out */
#define PC_DMA_OK			4	/* Use DMA */

/*
 *	SCSI command transformation layer
 */
#define IDESCSI_TRANSFORM		0	/* Enable/Disable transformation */
#define IDESCSI_SG_TRANSFORM		1	/* /dev/sg transformation */

/*
 *	Log flags
 */
#define IDESCSI_LOG_CMD			0	/* Log SCSI commands */

typedef struct ide_scsi_obj {
	ide_drive_t		*drive;
	ide_driver_t		*driver;
	struct gendisk		*disk;
	struct Scsi_Host	*host;

	idescsi_pc_t *pc;			/* Current packet command */
	unsigned long flags;			/* Status/Action flags */
	unsigned long transform;		/* SCSI cmd translation layer */
	unsigned long log;			/* log flags */
} idescsi_scsi_t;

static DEFINE_MUTEX(idescsi_ref_mutex);
static int idescsi_nocd;			/* Set by module param to skip cd */

#define ide_scsi_g(disk) \
	container_of((disk)->private_data, struct ide_scsi_obj, driver)

static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)
{
	struct ide_scsi_obj *scsi = NULL;

	mutex_lock(&idescsi_ref_mutex);
	scsi = ide_scsi_g(disk);
	if (scsi)
		scsi_host_get(scsi->host);
	mutex_unlock(&idescsi_ref_mutex);
	return scsi;
}

static void ide_scsi_put(struct ide_scsi_obj *scsi)
{
	mutex_lock(&idescsi_ref_mutex);
	scsi_host_put(scsi->host);
	mutex_unlock(&idescsi_ref_mutex);
}

static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)
{
	return (idescsi_scsi_t*) (&host[1]);
}

static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive)
{
	return scsihost_to_idescsi(ide_drive->driver_data);
}

/*
 *	Per ATAPI device status bits.
 */
#define IDESCSI_DRQ_INTERRUPT		0	/* DRQ interrupt device */

/*
 *	ide-scsi requests.
 */
#define IDESCSI_PC_RQ			90

static void idescsi_discard_data (ide_drive_t *drive, unsigned int bcount)
{
	while (bcount--)
		(void) HWIF(drive)->INB(IDE_DATA_REG);
}

static void idescsi_output_zeros (ide_drive_t *drive, unsigned int bcount)
{
	while (bcount--)
		HWIF(drive)->OUTB(0, IDE_DATA_REG);
}

/*
 *	PIO data transfer routines using the scatter gather table.
 */
static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
{
	int count;
	char *buf;

	while (bcount) {
		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
			printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
			idescsi_discard_data (drive, bcount);
			return;
		}
		count = min(pc->sg->length - pc->b_count, bcount);
		if (PageHighMem(pc->sg->page)) {
			unsigned long flags;

			local_irq_save(flags);
			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
					pc->sg->offset;
			drive->hwif->atapi_input_bytes(drive,
						buf + pc->b_count, count);
			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
			local_irq_restore(flags);
		} else {
			buf = page_address(pc->sg->page) + pc->sg->offset;
			drive->hwif->atapi_input_bytes(drive,
						buf + pc->b_count, count);
		}
		bcount -= count; pc->b_count += count;
		if (pc->b_count == pc->sg->length) {
			pc->sg++;
			pc->b_count = 0;
		}
	}
}

static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
{
	int count;
	char *buf;

	while (bcount) {
		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
			printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
			idescsi_output_zeros (drive, bcount);
			return;
		}
		count = min(pc->sg->length - pc->b_count, bcount);
		if (PageHighMem(pc->sg->page)) {
			unsigned long flags;

			local_irq_save(flags);
			buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
						pc->sg->offset;
			drive->hwif->atapi_output_bytes(drive,
						buf + pc->b_count, count);
			kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
			local_irq_restore(flags);
		} else {
			buf = page_address(pc->sg->page) + pc->sg->offset;
			drive->hwif->atapi_output_bytes(drive,
						buf + pc->b_count, count);
		}
		bcount -= count; pc->b_count += count;
		if (pc->b_count == pc->sg->length) {
			pc->sg++;
			pc->b_count = 0;
		}
	}
}

/*
 *	Most of the SCSI commands are supported directly by ATAPI devices.
 *	idescsi_transform_pc handles the few exceptions.
 */
static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
{
	u8 *c = pc->c, *scsi_buf = pc->buffer, *sc = pc->scsi_cmd->cmnd;
	char *atapi_buf;

	if (!test_bit(PC_TRANSFORM, &pc->flags))
		return;
	if (drive->media == ide_cdrom || drive->media == ide_optical) {
		if (c[0] == READ_6 || c[0] == WRITE_6) {
			c[8] = c[4];		c[5] = c[3];		c[4] = c[2];
			c[3] = c[1] & 0x1f;	c[2] = 0;		c[1] &= 0xe0;
			c[0] += (READ_10 - READ_6);
		}
		if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
			unsigned short new_len;
			if (!scsi_buf)
				return;
			if ((atapi_buf = kmalloc(pc->buffer_size + 4, GFP_ATOMIC)) == NULL)
				return;
			memset(atapi_buf, 0, pc->buffer_size + 4);
			memset (c, 0, 12);
			c[0] = sc[0] | 0x40;
			c[1] = sc[1];
			c[2] = sc[2];
			new_len = sc[4] + 4;
			c[8] = new_len;
			c[7] = new_len >> 8;
			c[9] = sc[5];
			if (c[0] == MODE_SELECT_10) {
				atapi_buf[1] = scsi_buf[0];	/* Mode data length */
				atapi_buf[2] = scsi_buf[1];	/* Medium type */
				atapi_buf[3] = scsi_buf[2];	/* Device specific parameter */
				atapi_buf[7] = scsi_buf[3];	/* Block descriptor length */
				memcpy(atapi_buf + 8, scsi_buf + 4, pc->buffer_size - 4);
			}
			pc->buffer = atapi_buf;
			pc->request_transfer += 4;
			pc->buffer_size += 4;
		}
	}
}

static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
{
	u8 *atapi_buf = pc->buffer;
	u8 *sc = pc->scsi_cmd->cmnd;
	u8 *scsi_buf = pc->scsi_cmd->request_buffer;

	if (!test_bit(PC_TRANSFORM, &pc->flags))
		return;
	if (drive->media == ide_cdrom || drive->media == ide_optical) {
		if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) {
			scsi_buf[0] = atapi_buf[1];		/* Mode data length */
			scsi_buf[1] = atapi_buf[2];		/* Medium type */
			scsi_buf[2] = atapi_buf[3];		/* Device specific parameter */
			scsi_buf[3] = atapi_buf[7];		/* Block descriptor length */
			memcpy(scsi_buf + 4, atapi_buf + 8, pc->request_transfer - 8);
		}
		if (pc->c[0] == INQUIRY) {
			scsi_buf[2] |= 2;			/* ansi_revision */
			scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;	/* response data format */
		}
	}
	if (atapi_buf && atapi_buf != scsi_buf)
		kfree(atapi_buf);
}

static void hexdump(u8 *x, int len)
{
	int i;

	printk("[ ");
	for (i = 0; i < len; i++)
		printk("%x ", x[i]);
	printk("]\n");
}

static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_command)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	idescsi_pc_t   *pc;
	struct request *rq;
	u8             *buf;

	/* stuff a sense request in front of our current request */
	pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
	rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
	buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
	if (pc == NULL || rq == NULL || buf == NULL) {
		kfree(buf);
		kfree(rq);
		kfree(pc);
		return -ENOMEM;
	}
	memset (pc, 0, sizeof (idescsi_pc_t));
	memset (buf, 0, SCSI_SENSE_BUFFERSIZE);
	ide_init_drive_cmd(rq);
	rq->special = (char *) pc;
	pc->rq = rq;
	pc->buffer = buf;
	pc->c[0] = REQUEST_SENSE;
	pc->c[4] = pc->request_transfer = pc->buffer_size = SCSI_SENSE_BUFFERSIZE;
	rq->cmd_type = REQ_TYPE_SENSE;
	pc->timeout = jiffies + WAIT_READY;
	/* NOTE! Save the failed packet command in "rq->buffer" */
	rq->buffer = (void *) failed_command->special;
	pc->scsi_cmd = ((idescsi_pc_t *) failed_command->special)->scsi_cmd;
	if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
		printk ("ide-scsi: %s: queue cmd = ", drive->name);
		hexdump(pc->c, 6);
	}
	rq->rq_disk = scsi->disk;
	return ide_do_drive_cmd(drive, rq, ide_preempt);
}

static int idescsi_end_request(ide_drive_t *, int, int);

static ide_startstop_t
idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
{
	if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
		/* force an abort */
		HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);

	rq->errors++;

	idescsi_end_request(drive, 0, 0);

	return ide_stopped;
}

static ide_startstop_t
idescsi_atapi_abort(ide_drive_t *drive, struct request *rq)
{
#if IDESCSI_DEBUG_LOG
	printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n",
			((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number);
#endif
	rq->errors |= ERROR_MAX;

	idescsi_end_request(drive, 0, 0);

	return ide_stopped;
}

static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	struct request *rq = HWGROUP(drive)->rq;
	idescsi_pc_t *pc = (idescsi_pc_t *) rq->special;
	int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
	struct Scsi_Host *host;
	u8 *scsi_buf;
	int errors = rq->errors;
	unsigned long flags;

	if (!blk_special_request(rq) && !blk_sense_request(rq)) {
		ide_end_request(drive, uptodate, nrsecs);
		return 0;
	}
	ide_end_drive_cmd (drive, 0, 0);
	if (blk_sense_request(rq)) {
		idescsi_pc_t *opc = (idescsi_pc_t *) rq->buffer;
		if (log) {
			printk ("ide-scsi: %s: wrap up check %lu, rst = ", drive->name, opc->scsi_cmd->serial_number);
			hexdump(pc->buffer,16);
		}
		memcpy((void *) opc->scsi_cmd->sense_buffer, pc->buffer, SCSI_SENSE_BUFFERSIZE);
		kfree(pc->buffer);
		kfree(pc);
		kfree(rq);
		pc = opc;
		rq = pc->rq;
		pc->scsi_cmd->result = (CHECK_CONDITION << 1) |
					((test_bit(PC_TIMEDOUT, &pc->flags)?DID_TIME_OUT:DID_OK) << 16);
	} else if (test_bit(PC_TIMEDOUT, &pc->flags)) {
		if (log)
			printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",
					drive->name, pc->scsi_cmd->serial_number);
		pc->scsi_cmd->result = DID_TIME_OUT << 16;
	} else if (errors >= ERROR_MAX) {
		pc->scsi_cmd->result = DID_ERROR << 16;
		if (log)
			printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
	} else if (errors) {
		if (log)
			printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
		if (!idescsi_check_condition(drive, rq))
			/* we started a request sense, so we'll be back, exit for now */
			return 0;
		pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
	} else {
		pc->scsi_cmd->result = DID_OK << 16;
		idescsi_transform_pc2 (drive, pc);
		if (log) {
			printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number);
			if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) {
				printk(", rst = ");
				scsi_buf = pc->scsi_cmd->request_buffer;
				hexdump(scsi_buf, min_t(unsigned, 16, pc->scsi_cmd->request_bufflen));
			} else printk("\n");
		}
	}
	host = pc->scsi_cmd->device->host;
	spin_lock_irqsave(host->host_lock, flags);
	pc->done(pc->scsi_cmd);
	spin_unlock_irqrestore(host->host_lock, flags);
	kfree(pc);
	kfree(rq);
	scsi->pc = NULL;
	return 0;
}

static inline unsigned long get_timeout(idescsi_pc_t *pc)
{
	return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies);
}

static int idescsi_expiry(ide_drive_t *drive)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	idescsi_pc_t   *pc   = scsi->pc;

#if IDESCSI_DEBUG_LOG
	printk(KERN_WARNING "idescsi_expiry called for %lu at %lu\n", pc->scsi_cmd->serial_number, jiffies);
#endif
	set_bit(PC_TIMEDOUT, &pc->flags);

	return 0;					/* we do not want the ide subsystem to retry */
}

/*
 *	Our interrupt handler.
 */
static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	idescsi_pc_t *pc=scsi->pc;
	struct request *rq = pc->rq;
	atapi_bcount_t bcount;
	atapi_status_t status;
	atapi_ireason_t ireason;
	atapi_feature_t feature;

	unsigned int temp;

#if IDESCSI_DEBUG_LOG
	printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
#endif /* IDESCSI_DEBUG_LOG */

	if (test_bit(PC_TIMEDOUT, &pc->flags)){
#if IDESCSI_DEBUG_LOG
		printk(KERN_WARNING "idescsi_pc_intr: got timed out packet  %lu at %lu\n",
				pc->scsi_cmd->serial_number, jiffies);
#endif
		/* end this request now - scsi should retry it*/
		idescsi_end_request (drive, 1, 0);
		return ide_stopped;
	}
	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
#if IDESCSI_DEBUG_LOG
		printk ("ide-scsi: %s: DMA complete\n", drive->name);
#endif /* IDESCSI_DEBUG_LOG */
		pc->actually_transferred=pc->request_transfer;
		(void) HWIF(drive)->ide_dma_end(drive);
	}

	feature.all = 0;
	/* Clear the interrupt */
	status.all = HWIF(drive)->INB(IDE_STATUS_REG);

	if (!status.b.drq) {
		/* No more interrupts */
		if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
			printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
		local_irq_enable_in_hardirq();
		if (status.b.check)
			rq->errors++;
		idescsi_end_request (drive, 1, 0);
		return ide_stopped;
	}
	bcount.b.low	= HWIF(drive)->INB(IDE_BCOUNTL_REG);
	bcount.b.high	= HWIF(drive)->INB(IDE_BCOUNTH_REG);
	ireason.all	= HWIF(drive)->INB(IDE_IREASON_REG);

	if (ireason.b.cod) {
		printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
		return ide_do_reset (drive);
	}
	if (ireason.b.io) {
		temp = pc->actually_transferred + bcount.all;
		if (temp > pc->request_transfer) {
			if (temp > pc->buffer_size) {
				printk(KERN_ERR "ide-scsi: The scsi wants to "
					"send us more data than expected "
					"- discarding data\n");
				temp = pc->buffer_size - pc->actually_transferred;
				if (temp) {
					clear_bit(PC_WRITING, &pc->flags);
					if (pc->sg)
						idescsi_input_buffers(drive, pc, temp);
					else
						drive->hwif->atapi_input_bytes(drive, pc->current_position, temp);
					printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount.all);
				}
				pc->actually_transferred += temp;
				pc->current_position += temp;
				idescsi_discard_data(drive, bcount.all - temp);
				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
				return ide_started;
			}
#if IDESCSI_DEBUG_LOG
			printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
#endif /* IDESCSI_DEBUG_LOG */
		}
	}
	if (ireason.b.io) {
		clear_bit(PC_WRITING, &pc->flags);
		if (pc->sg)
			idescsi_input_buffers(drive, pc, bcount.all);
		else
			HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all);
	} else {
		set_bit(PC_WRITING, &pc->flags);
		if (pc->sg)
			idescsi_output_buffers (drive, pc, bcount.all);
		else
			HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all);
	}
	/* Update the current position */
	pc->actually_transferred += bcount.all;
	pc->current_position += bcount.all;

	/* And set the interrupt handler again */
	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
	return ide_started;
}

static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	idescsi_pc_t *pc = scsi->pc;
	atapi_ireason_t ireason;
	ide_startstop_t startstop;

	if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
		printk(KERN_ERR "ide-scsi: Strange, packet command "
			"initiated yet DRQ isn't asserted\n");
		return startstop;
	}
	ireason.all	= HWIF(drive)->INB(IDE_IREASON_REG);
	if (!ireason.b.cod || ireason.b.io) {
		printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while "
				"issuing a packet command\n");
		return ide_do_reset (drive);
	}
	BUG_ON(HWGROUP(drive)->handler != NULL);
	/* Set the interrupt routine */
	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry);
	/* Send the actual packet */
	drive->hwif->atapi_output_bytes(drive, scsi->pc->c, 12);
	if (test_bit (PC_DMA_OK, &pc->flags)) {
		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
		hwif->dma_start(drive);
	}
	return ide_started;
}

static inline int idescsi_set_direction(idescsi_pc_t *pc)
{
	switch (pc->c[0]) {
		case READ_6: case READ_10: case READ_12:
			clear_bit(PC_WRITING, &pc->flags);
			return 0;
		case WRITE_6: case WRITE_10: case WRITE_12:
			set_bit(PC_WRITING, &pc->flags);
			return 0;
		default:
			return 1;
	}
}

static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc)
{
	ide_hwif_t *hwif = drive->hwif;
	struct scatterlist *sg, *scsi_sg;
	int segments;

	if (!pc->request_transfer || pc->request_transfer % 1024)
		return 1;

	if (idescsi_set_direction(pc))
		return 1;

	sg = hwif->sg_table;
	scsi_sg = pc->scsi_cmd->request_buffer;
	segments = pc->scsi_cmd->use_sg;

	if (segments > hwif->sg_max_nents)
		return 1;

	if (!segments) {
		hwif->sg_nents = 1;
		sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer);
	} else {
		hwif->sg_nents = segments;
		memcpy(sg, scsi_sg, sizeof(*sg) * segments);
	}

	return 0;
}

/*
 *	Issue a packet command
 */
static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);
	ide_hwif_t *hwif = drive->hwif;
	atapi_feature_t feature;
	atapi_bcount_t bcount;

	scsi->pc=pc;							/* Set the current packet command */
	pc->actually_transferred=0;					/* We haven't transferred any data yet */
	pc->current_position=pc->buffer;
	bcount.all = min(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */

	feature.all = 0;
	if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
		hwif->sg_mapped = 1;
		feature.b.dma = !hwif->dma_setup(drive);
		hwif->sg_mapped = 0;
	}

	SELECT_DRIVE(drive);
	if (IDE_CONTROL_REG)
		HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);

	HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG);
	HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG);
	HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG);

	if (feature.b.dma)
		set_bit(PC_DMA_OK, &pc->flags);

	if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
		BUG_ON(HWGROUP(drive)->handler != NULL);
		ide_set_handler(drive, &idescsi_transfer_pc,
				get_timeout(pc), idescsi_expiry);
		/* Issue the packet command */
		HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
		return ide_started;
	} else {
		/* Issue the packet command */
		HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG);
		return idescsi_transfer_pc(drive);
	}
}

/*
 *	idescsi_do_request is our request handling function.
 */
static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
{
#if IDESCSI_DEBUG_LOG
	printk (KERN_INFO "dev: %s, cmd: %x, errors: %d\n", rq->rq_disk->disk_name,rq->cmd[0],rq->errors);
	printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDESCSI_DEBUG_LOG */

	if (blk_sense_request(rq) || blk_special_request(rq)) {
		return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special);
	}
	blk_dump_rq_flags(rq, "ide-scsi: unsup command");
	idescsi_end_request (drive, 0, 0);
	return ide_stopped;
}

#ifdef CONFIG_IDE_PROC_FS
static void idescsi_add_settings(ide_drive_t *drive)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);

/*
 *			drive	setting name	read/write	data type	min	max	mul_factor	div_factor	data pointer		set function
 */
	ide_add_setting(drive,	"bios_cyl",	SETTING_RW,	TYPE_INT,	0,	1023,	1,		1,		&drive->bios_cyl,	NULL);
	ide_add_setting(drive,	"bios_head",	SETTING_RW,	TYPE_BYTE,	0,	255,	1,		1,		&drive->bios_head,	NULL);
	ide_add_setting(drive,	"bios_sect",	SETTING_RW,	TYPE_BYTE,	0,	63,	1,		1,		&drive->bios_sect,	NULL);
	ide_add_setting(drive,	"transform",	SETTING_RW,	TYPE_INT,	0,	3,	1,		1,		&scsi->transform,	NULL);
	ide_add_setting(drive,	"log",		SETTING_RW,	TYPE_INT,	0,	1,	1,		1,		&scsi->log,		NULL);
}
#else
static inline void idescsi_add_settings(ide_drive_t *drive) { ; }
#endif

/*
 *	Driver initialization.
 */
static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi)
{
	if (drive->id && (drive->id->config & 0x0060) == 0x20)
		set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
	set_bit(IDESCSI_TRANSFORM, &scsi->transform);
	clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
#if IDESCSI_DEBUG_LOG
	set_bit(IDESCSI_LOG_CMD, &scsi->log);
#endif /* IDESCSI_DEBUG_LOG */
	idescsi_add_settings(drive);
}

static void ide_scsi_remove(ide_drive_t *drive)
{
	struct Scsi_Host *scsihost = drive->driver_data;
	struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost);
	struct gendisk *g = scsi->disk;

	ide_proc_unregister_driver(drive, scsi->driver);

	ide_unregister_region(g);

	drive->driver_data = NULL;
	g->private_data = NULL;
	put_disk(g);

	scsi_remove_host(scsihost);
	ide_scsi_put(scsi);
}

static int ide_scsi_probe(ide_drive_t *);

#ifdef CONFIG_IDE_PROC_FS
static ide_proc_entry_t idescsi_proc[] = {
	{ "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
	{ NULL, 0, NULL, NULL }
};
#endif

static ide_driver_t idescsi_driver = {
	.gen_driver = {
		.owner		= THIS_MODULE,
		.name		= "ide-scsi",
		.bus		= &ide_bus_type,
	},
	.probe			= ide_scsi_probe,
	.remove			= ide_scsi_remove,
	.version		= IDESCSI_VERSION,
	.media			= ide_scsi,
	.supports_dsc_overlap	= 0,
	.do_request		= idescsi_do_request,
	.end_request		= idescsi_end_request,
	.error                  = idescsi_atapi_error,
	.abort                  = idescsi_atapi_abort,
#ifdef CONFIG_IDE_PROC_FS
	.proc			= idescsi_proc,
#endif
};

static int idescsi_ide_open(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ide_scsi_obj *scsi;

	if (!(scsi = ide_scsi_get(disk)))
		return -ENXIO;

	return 0;
}

static int idescsi_ide_release(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ide_scsi_obj *scsi = ide_scsi_g(disk);

	ide_scsi_put(scsi);

	return 0;
}

static int idescsi_ide_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct block_device *bdev = inode->i_bdev;
	struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk);
	return generic_ide_ioctl(scsi->drive, file, bdev, cmd, arg);
}

static struct block_device_operations idescsi_ops = {
	.owner		= THIS_MODULE,
	.open		= idescsi_ide_open,
	.release	= idescsi_ide_release,
	.ioctl		= idescsi_ide_ioctl,
};

static int idescsi_slave_configure(struct scsi_device * sdp)
{
	/* Configure detected device */
	scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun);
	return 0;
}

static const char *idescsi_info (struct Scsi_Host *host)
{
	return "SCSI host adapter emulation for IDE ATAPI devices";
}

static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg)
{
	idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host);

	if (cmd == SG_SET_TRANSFORM) {
		if (arg)
			set_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
		else
			clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
		return 0;
	} else if (cmd == SG_GET_TRANSFORM)
		return put_user(test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform), (int __user *) arg);
	return -EINVAL;
}

static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd)
{
	idescsi_scsi_t *scsi = drive_to_idescsi(drive);

	/* this was a layering violation and we can't support it
	   anymore, sorry. */
#if 0
	struct gendisk *disk = cmd->request->rq_disk;

	if (disk) {
		struct struct scsi_device_Template **p = disk->private_data;
		if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
			return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
	}
#endif
	return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
}

static int idescsi_queue (struct scsi_cmnd *cmd,
		void (*done)(struct scsi_cmnd *))
{
	struct Scsi_Host *host = cmd->device->host;
	idescsi_scsi_t *scsi = scsihost_to_idescsi(host);
	ide_drive_t *drive = scsi->drive;
	struct request *rq = NULL;
	idescsi_pc_t *pc = NULL;

	if (!drive) {
		scmd_printk (KERN_ERR, cmd, "drive not present\n");
		goto abort;
	}
	scsi = drive_to_idescsi(drive);
	pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
	rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
	if (rq == NULL || pc == NULL) {
		printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name);
		goto abort;
	}

	memset (pc->c, 0, 12);
	pc->flags = 0;
	pc->rq = rq;
	memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
	if (cmd->use_sg) {
		pc->buffer = NULL;
		pc->sg = cmd->request_buffer;
	} else {
		pc->buffer = cmd->request_buffer;
		pc->sg = NULL;
	}
	pc->b_count = 0;
	pc->request_transfer = pc->buffer_size = cmd->request_bufflen;
	pc->scsi_cmd = cmd;
	pc->done = done;
	pc->timeout = jiffies + cmd->timeout_per_command;

	if (should_transform(drive, cmd))
		set_bit(PC_TRANSFORM, &pc->flags);
	idescsi_transform_pc1 (drive, pc);

	if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) {
		printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number);
		hexdump(cmd->cmnd, cmd->cmd_len);
		if (memcmp(pc->c, cmd->cmnd, cmd->cmd_len)) {
			printk ("ide-scsi: %s: que %lu, tsl = ", drive->name, cmd->serial_number);
			hexdump(pc->c, 12);
		}
	}

	ide_init_drive_cmd (rq);
	rq->special = (char *) pc;
	rq->cmd_type = REQ_TYPE_SPECIAL;
	spin_unlock_irq(host->host_lock);
	rq->rq_disk = scsi->disk;
	(void) ide_do_drive_cmd (drive, rq, ide_end);
	spin_lock_irq(host->host_lock);
	return 0;
abort:
	kfree (pc);
	kfree (rq);
	cmd->result = DID_ERROR << 16;
	done(cmd);
	return 0;
}

static int idescsi_eh_abort (struct scsi_cmnd *cmd)
{
	idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);
	ide_drive_t    *drive = scsi->drive;
	int		busy;
	int             ret   = FAILED;

	/* In idescsi_eh_abort we try to gently pry our command from the ide subsystem */

	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: abort called for %lu\n", cmd->serial_number);

	if (!drive) {
		printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_abort\n");
		WARN_ON(1);
		goto no_drive;
	}

	/* First give it some more time, how much is "right" is hard to say :-( */

	busy = ide_wait_not_busy(HWIF(drive), 100);	/* FIXME - uses mdelay which causes latency? */
	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: drive did%s become ready\n", busy?" not":"");

	spin_lock_irq(&ide_lock);

	/* If there is no pc running we're done (our interrupt took care of it) */
	if (!scsi->pc) {
		ret = SUCCESS;
		goto ide_unlock;
	}

	/* It's somewhere in flight. Does ide subsystem agree? */
	if (scsi->pc->scsi_cmd->serial_number == cmd->serial_number && !busy &&
	    elv_queue_empty(drive->queue) && HWGROUP(drive)->rq != scsi->pc->rq) {
		/*
		 * FIXME - not sure this condition can ever occur
		 */
		printk (KERN_ERR "ide-scsi: cmd aborted!\n");

		if (blk_sense_request(scsi->pc->rq))
			kfree(scsi->pc->buffer);
		kfree(scsi->pc->rq);
		kfree(scsi->pc);
		scsi->pc = NULL;

		ret = SUCCESS;
	}

ide_unlock:
	spin_unlock_irq(&ide_lock);
no_drive:
	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: abort returns %s\n", ret == SUCCESS?"success":"failed");

	return ret;
}

static int idescsi_eh_reset (struct scsi_cmnd *cmd)
{
	struct request *req;
	idescsi_scsi_t *scsi  = scsihost_to_idescsi(cmd->device->host);
	ide_drive_t    *drive = scsi->drive;
	int             ready = 0;
	int             ret   = SUCCESS;

	/* In idescsi_eh_reset we forcefully remove the command from the ide subsystem and reset the device. */

	if (test_bit(IDESCSI_LOG_CMD, &scsi->log))
		printk (KERN_WARNING "ide-scsi: reset called for %lu\n", cmd->serial_number);

	if (!drive) {
		printk (KERN_WARNING "ide-scsi: Drive not set in idescsi_eh_reset\n");
		WARN_ON(1);
		return FAILED;
	}

	spin_lock_irq(cmd->device->host->host_lock);
	spin_lock(&ide_lock);

	if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) {
		printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");
		spin_unlock(&ide_lock);
		spin_unlock_irq(cmd->device->host->host_lock);
		return FAILED;
	}

	/* kill current request */
	blkdev_dequeue_request(req);
	end_that_request_last(req, 0);
	if (blk_sense_request(req))
		kfree(scsi->pc->buffer);
	kfree(scsi->pc);
	scsi->pc = NULL;
	kfree(req);

	/* now nuke the drive queue */
	while ((req = elv_next_request(drive->queue))) {
		blkdev_dequeue_request(req);
		end_that_request_last(req, 0);
	}

	HWGROUP(drive)->rq = NULL;
	HWGROUP(drive)->handler = NULL;
	HWGROUP(drive)->busy = 1;		/* will set this to zero when ide reset finished */
	spin_unlock(&ide_lock);

	ide_do_reset(drive);

	/* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */

	do {
		spin_unlock_irq(cmd->device->host->host_lock);
		msleep(50);
		spin_lock_irq(cmd->device->host->host_lock);
	} while ( HWGROUP(drive)->handler );

	ready = drive_is_ready(drive);
	HWGROUP(drive)->busy--;
	if (!ready) {
		printk (KERN_ERR "ide-scsi: reset failed!\n");
		ret = FAILED;
	}

	spin_unlock_irq(cmd->device->host->host_lock);
	return ret;
}

static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev,
		sector_t capacity, int *parm)
{
	idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host);
	ide_drive_t *drive = idescsi->drive;

	if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
		parm[0] = drive->bios_head;
		parm[1] = drive->bios_sect;
		parm[2] = drive->bios_cyl;
	}
	return 0;
}

static struct scsi_host_template idescsi_template = {
	.module			= THIS_MODULE,
	.name			= "idescsi",
	.info			= idescsi_info,
	.slave_configure        = idescsi_slave_configure,
	.ioctl			= idescsi_ioctl,
	.queuecommand		= idescsi_queue,
	.eh_abort_handler	= idescsi_eh_abort,
	.eh_host_reset_handler  = idescsi_eh_reset,
	.bios_param		= idescsi_bios,
	.can_queue		= 40,
	.this_id		= -1,
	.sg_tablesize		= 256,
	.cmd_per_lun		= 5,
	.max_sectors		= 128,
	.use_clustering		= DISABLE_CLUSTERING,
	.emulated		= 1,
	.proc_name		= "ide-scsi",
};

static int ide_scsi_probe(ide_drive_t *drive)
{
	idescsi_scsi_t *idescsi;
	struct Scsi_Host *host;
	struct gendisk *g;
	static int warned;
	int err = -ENOMEM;

	if (!warned && drive->media == ide_cdrom) {
		printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n");
		warned = 1;
	}

	if (idescsi_nocd && drive->media == ide_cdrom)
		return -ENODEV;

	if (!strstr("ide-scsi", drive->driver_req) ||
	    !drive->present ||
	    drive->media == ide_disk ||
	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
		return -ENODEV;

	g = alloc_disk(1 << PARTN_BITS);
	if (!g)
		goto out_host_put;

	ide_init_disk(g, drive);

	host->max_id = 1;

#if IDESCSI_DEBUG_LOG
	if (drive->id->last_lun)
		printk(KERN_NOTICE "%s: id->last_lun=%u\n", drive->name, drive->id->last_lun);
#endif
	if ((drive->id->last_lun & 0x7) != 7)
		host->max_lun = (drive->id->last_lun & 0x7) + 1;
	else
		host->max_lun = 1;

	drive->driver_data = host;
	idescsi = scsihost_to_idescsi(host);
	idescsi->drive = drive;
	idescsi->driver = &idescsi_driver;
	idescsi->host = host;
	idescsi->disk = g;
	g->private_data = &idescsi->driver;
	ide_proc_register_driver(drive, &idescsi_driver);
	err = 0;
	idescsi_setup(drive, idescsi);
	g->fops = &idescsi_ops;
	ide_register_region(g);
	err = scsi_add_host(host, &drive->gendev);
	if (!err) {
		scsi_scan_host(host);
		return 0;
	}
	/* fall through on error */
	ide_unregister_region(g);
	ide_proc_unregister_driver(drive, &idescsi_driver);

	put_disk(g);
out_host_put:
	scsi_host_put(host);
	return err;
}

static int __init init_idescsi_module(void)
{
	return driver_register(&idescsi_driver.gen_driver);
}

static void __exit exit_idescsi_module(void)
{
	driver_unregister(&idescsi_driver.gen_driver);
}

module_param(idescsi_nocd, int, 0600);
MODULE_PARM_DESC(idescsi_nocd, "Disable handling of CD-ROMs so they may be driven by ide-cd");
module_init(init_idescsi_module);
module_exit(exit_idescsi_module);
MODULE_LICENSE("GPL");

redpajama_set_name: RedPajamaGithub


Echinostelium is a genus of slime mould, and the only genus in the family Echinosteliaceae, or Echinosteliidae. It was discovered by Heinrich Anton de Bary in 1855, apparently near Frankfurt am Main. Some species of Echinostelium have a sexual life cycle; others have been shown to be asexual. The plasmodium can divide vegetatively, in a process called plasmotomy, to distinguish it from true cell division.
^ Constantine J. Alexopoulos & T. E. Brooks (1971). "Taxonomic studies in the Myxomycetes. III. Clastodermataceae: a new family of the Echinosteliales". Mycologia 63 (4): 925–928. JSTOR 3758063. doi:10.2307/3758063.
^ Lynn Margulis, Michael J. Chapman (2009). "Pr-23 Myxomycota". Kingdoms and Domains: an illustrated guide to the phyla of life on earth (4th ed.). Elsevier. pp. 190–191. ISBN 978-0-7167-3027-9.
^ Constantine J. Alexopoulos (1960). "Morphology and laboratory cultivation of Echinostelium minutum". American Journal of Botany 47 (1): 37–43. JSTOR 2439491. doi:10.2307/2439491.
^ Clark, J.; Haskins, E.F. (2010). "Reproductive systems in the myxomycetes: a review" (PDF). Mycosphere 1 (4): 337–353.
^ Helmut W. Sauer (1982). "Lives of a true slime mould". Developmental biology of Physarum<span />. Volume 11 of Developmental and cell biology series. Cambridge University Press. pp. 7–35. ISBN 978-0-521-22703-2.
^ T. W. May (2003). "Echinosteliales". Basidiomycota p.p. & Myxomycota p.p. Volume 2 of Catalogue and bibliography of Australian macrofungi. CSIRO Publishing. pp. 2–3. ISBN 978-0-643-06907-7.


text:
LEFT ON MISSION TPB Giveaway Contest
Over at the DOUBLE O SECTION Blog, they are giving away 2 free copies of the LEFT ON MISSION TPB! Go here for more info! DOUBLE O SECTION is a daily must read for those that love the espionage genre!
STARDUST KID "…illustrations call to mind … fantasy adventures, from Alice in Wonderland to The Dark Crystal." – Comic Mix
"THE STARDUST KID works simply from the honesty and clarity of DeMatteis script. A lot of credit also goes to Mike Ploog, whose illustrations call to mind some of the classic fantasy adventures, from Alice in Wonderland to The Dark Crystal." – Comic Mix
JENNY FINN: DOOM MESSIAH "…a great piece of haunted fun." – Comic Mix
"…a great piece of haunted fun. And I forgot the best part: plenty of tentacles." – Comic Mix
In Stores Today (03/26/08)
Here is the BOOM! Studios titles in stores this week (03/26/08). Enjoy!
JENNY FINN: DOOM MESSIAH TPB
Written by Mike Mignola
Cover Art by Mike Mignola with new colors by Dave Stewart
Art by Troy Nixey and Farel Dalrymple
SC, 6×9, 128pgs, B&W SRP: $14.99
Diamond Code: DEC073492
Finally collected in one volume for the first time! From the mind of Mike Mignola, creator of HELLBOY, comes this Lovecraftian tale of a mysterious girl who arrives in Victorian England with carnage in her wake. Is she evil incarnate or a misled child? Just in time for HELLBOY 2!
STARDUST KID TPB
STARDUST KID HC
Written by J.M. DeMatteis
Art by Mike Ploog
SC, 6×9, 144pgs, FC, SRP: $14.99
HC, 7×10, 144pgs, FC SRP: $29.99
TP ISBN-10: 1934506044
TP ISBN-13: 978-1934506042
From the Eisner-award winning writer of JUSTICE LEAGUE and SPIDER-MAN and the artist of WEREWOLF BY NIGHT and MAN-THING comes the long-awaited collection of their fan-favorite follow-up to ABADAZAD! Last night, when Cody DiMarco went to bed, life was the same as it's always been. This morning, when he woke up, the world he knew was gone, victim to a magic older than time. Now four children, in order to restore their families and our planet, must solve the mystery of…The Stardust Kid. This edition collects all issues of this hard-to-find mini-series.
Kim at WonderCon 2008 thinks FALL OF CTHULHU is awesome!
SALEM "…has smartly found a way to have its cake and eat it too." – Underground Online
"Meanwhile, as little girls slap pentagrams onto their Trapper Keepers, some new comics are looking at bringing back the old scary witches that filled us with fear so long ago. One of these is SALEM: QUEEN OF THORNS, an action-horror comic from creators Chris Morgan and Kevin Walsh. SALEM takes place in the 1600s and follows a Grand Inquisitor who discovers innocents were killed in the famous Salem Trials and that though the church may be punishing heretics it is ignoring what really haunts the woods. Our hero packs up his weapons and sets off on his own to hunt down the real witches. By dismissing Wiccans and pagans and practitioners of the Craft as innocents separate from the monstrous elemental creatures of magic that are the real witches, Salem has smartly found a way to have its cake and eat it too." – Underground Online
March Previews 2008 / In Stores May 2008
Here are the BOOM! Studios titles that are solicited in March Previews 2008 and will be in-Store May 2008.
BLOOD BOWL: KILLER CONTRACT #2 (COVER A)
BLOOD BOWL: KILLER CONTRACT #2 (COVER B)
Written by Matt Forbeck
Illustrated by Lads Helloven
24pgs, FC, (2 of 5) SRP: $3.99
Cover A Diamond Code: MAR083543
Cover B Diamond Code: MAR083544
Welcome to the hyper-violent hilarity of BLOOD BOWL, the miniseries that puts the fantasy (as in elves, dwarves, orcs, and ogres) back into football! "Retired" assassin Kalter Mörder seeks redemption for the only contract he ever blew when his team, the Bad Bay Hackers, battles the feared Dwarf Giants. Mörder finally gets his shot at star Giants blitzer Snazkazi Ungrim, and he's going to take it, no matter who else might die in the process!
CTHULHU TALES #3 (COVER A) ONGOING
CTHULHU TALES #3 (COVER B) ONGOING
Written by William Messner-Loebs, Michael Alan Nelson
Drawn by Various
24pgs, FC, SRP: $3.99
Acclaimed writer William Messner-Loebs (JOURNEY) joins the BOOM! family! Don't tell the Elder Gods, or they'll take him from us! Messner-Loebs and Michael Alan (FALL OF CTHULHU) Nelson chill the blood in the new, monthly anthology series! Something big is happening in the Boom! horror universe in 2008…and it starts here! Heed the call of Cthulhu!
FALL OF CTHULHU #13 (COVER A) ONGOING
FALL OF CTHULHU #13 (COVER B) ONGOING
Written by Michael Alan Nelson
As Lucifer and the Sheriff continue their search for the elusive Gray Man, they find themselves the hunted rather than the hunters. Either way, they must stop the Gray Man or the Cthulhu cultists will have their way…and that can't be good for mankind's survival.
HERO SQUARED VOLUME 2: ANOTHER FINE MESS TP
Written by J.M. DeMatteis and Keith Giffen
Illustrated by Joe Abraham
Diamond Code: MAR083557
The twisted – and extremely hot – Caliginous starts to lay out a plan to set Stephie against Milo and Captain Valor, even as Milo and his super-heroic twin visit a therapist-in the endless talkfest that Giffen and DeMatteis, who've been known to talk endlessly themselves, consider their finest work together to date (their previous "finest work" involved an army of mutated penguins, so take that with a grain of salt)! If that's not enough to make you want to shell out Big Bucks for this collection, then how's this? Captain Valor is attacked by his evil clone – no it's not Ben Reilly- and Mile, who's wanted for murder, ends up in the hay with Caliginous! Still not convinced? Did we mention that Giffen and DeMatteis need the money? There! We thought that would do it!
SALEM: QUEEN OF THORNS #1 (COVER A)
SALEM: QUEEN OF THORNS #1 (COVER B)
Written by Chris Morgan and Kevin Walsh
Drawn by Wilfredo Torres
24pgs, FC, (1 of 4), SRP: $3.99
The already controversial series continues from the red-hot zero issue! Elias Hooke, dark crusader against the forces of magic, learns the secrets of his own origin, and the revelations nearly consume him! A new hero in the tradition of Robert E. Howard's SOLOMON KANE and Clint Eastwood's The Man with No Name, from the screenwriter of WANTED and THE FAST AND THE FURIOUS: TOKYO DRIFT!
SCREAM QUEEN #1 (COVER A)
SCREAM QUEEN #1 (COVER B)
Written by Brendan Hay
Illustrated by Nate Watson
Everyone wants to be loved. Even the shambling, macabre mockery of a man who brings terror to the town of Rumson and leaves blood in his wake. But when he sets his sights on Molly, beauty queen of Rumson High, she's going to be more than he can handle! THE DAILY SHOW staff writer Brendan Hay brings a HEATHERS-meets-CARRIE sensibility to his horror series debut!
WARHAMMER: CONDEMNED BY FIRE #3 (COVER A)
WARHAMMER: CONDEMNED BY FIRE #3 (COVER B)
Written by Dan Abnett and Ian Edginton
Drawn by Rahsan Ekedal
Having single-handedly put the Chaos-corrupted inhabitants of Loughville to the sword and flame, Witch Hunter Magnus Gault backtracks along the tainted river to find the source of the corruption. Gault's quest ends at the village of Mittlesedorf, which he finds miraculously untouched. However, there is a worm in the apple, and even Gault may not be a match for the foes that await him. has gone undetected beneath the city of Carrion Gulf?
ZOMBIE TALES #2 (COVER A) ONGOING
ZOMBIE TALES #2 (COVER B) ONGOING
Written by Joe R. Lansdale, Christine Boylan, and Brian Augustyn
Legendary author Joe R. Lansdale (The Drive-In, BATMAN: THE ANIMATED SERIES) continues his serialized "THE WAR AT HOME" zombie tale! Plus, award-winning playwright Christine Boylan and writer Brian Augustyn (BATMAN: GOTHAM BY GASLIGHT, COUNTDOWN: GOTHAM BY GASLIGHT) bring the undead love to your doorstep this month!
WARHAMMER 40,000: BLOOD & THUNDER "Four out of five stars!"
"Totally enjoyable! Four out of five stars!" – Shots in the Dark
Check out the whole review in the video below, the review begins at 1:25. Enjoy!
In Stores Today! (3/19/2008)
WARHAMMER 40,000 COVER GALLERY
32pgs FC SRP: $3.99
Collecting the stunning cover art from the hit mini-series WARHAMMER 40,000: DAMNATION CRUSADE and WARHAMMER 40,000: BLOOD AND THUNDER, the WARHAMMER 40,000 COVER GALLERY SPECIAL features 30 savage full-page, text-free images of Space Marines, Dreadnoughts, Imperial Guardsmen, Orks and other war-driven inhabitants of the bloody 41st Millennium. In the grim darkness of the far future, there is only war…
UNCLE CTHULHU "I WANT YOU" POSTER
12" x 18" FC
Cthulhu calls, yet again, this time taking on the guise of the iconic Uncle Sam, poster boy for liberty. Featuring art by FALL OF CTHULHU cover artist Patrick McEvoy, this 12" x 18" print features a never before seen take on Cthulhu, this time in the style of the classic U.S. Army recruitment poster. Limited to just 1,000, enlist today and show your support for the coming darkness!
THE FOUNDATION "4 out of 5 stars. Strong Read." – Major Spoilers
"If you are someone who believes the end times are upon us, are particularly keen on conspiracy theories, or just someone who likes a great thriller, THE FOUNDATION from BOOM! Studios is a page turner. I'm giving issue #3 another 4.5 out of 5 stars, and giving it a Strong Read recommendation." – Major Spoilers
THE FOUNDATION "Neat-o." – Brian K. Vaughn
"Fun high concept from BOOM! Studios: A secret society founded by Nostradamus with the wealth accumulated from sales of his prophetic books today uses his unpublished tomes to predict and prevent global disasters. Neat-o." – Brian K. Vaughn, writer/creator behind Y: The Last Man
Reneé at WonderCon 2008 loves WARHAMMER 40,000

redpajama_set_name: RedPajamaCommonCrawl


Take a look at the trade by tonnage, and the story is not nearly as dreary. Down 3.5 percent overall and 11.46 percent for exports, tonnage for imports actually increased in 2015, up 1.39 percent. On the downside, the "why" gets back to what's going on in Brazil and Venezuela, with gold and with computer chips.
Both PortMiami and Port Everglades — also primary hubs for South Florida's trade with the world — rank among the nation's top ports as well, at No. 35 and No. 36, respectively, and among the tops in the state for both containers and tonnage.
Combine the three and you have about two-thirds of all the trade that occurs in Florida. As was the case with MIA, trade in the South Florida Customs district, which also includes Fort Lauderdale International Airport and the Port of Palm Beach, also fell for an unprecedented third consecutive year in 2015.
Airports rank relatively high when ranked by the dollar value of trade but less so by tonnage, since ships are more suited to carry heavy cargo like steel, cement and oil. MIA ranked No. 90 by tonnage in 2015.
MIA's trade is being hard-hit by the acute economic and political challenges consuming Brazil and Venezuela; by the concurrent drop in the price of gold and diminishing interest in it by investors previously skittish about the global economy, particularly during the economic downtown of 2009 and 2010; and by Intel's decision to move computer chip manufacturing from outside San Jose in Costa Rica to Malaysia.
I will touch on each quickly, since I have addressed them all recently.
MIA trade with Brazil fell $2.71 billion in 2015 when compared to 2014. MIA's perennial largest trade partner, Brazil has historically quenched its appetite for cellphones, printers, medicine and computers as well as aircraft engines and parts by shipments originating at MIA and its leading seaports. With its steep currency devaluation against the strong dollar, Brazil and its citizens are finding it increasingly difficult to afford those items, whether luxuries or necessities. Venezuela is suffering the highest inflation rate in the world and its currency is, likewise, hobbled. Although most of the damage to its economy has been done in previous year, its trade with MIA fell another $604.08 million in 2015.
Only Brazil's trade with MIA fell more in dollars than Costa Rica's in 2015. Costa Rica's MIA trade dropped $2.52 billion in 2015. Because its trade with MIA is smaller than that of Brazil's, the percentage drop was far steeper, at 60.90 percent. Computer chip imports into MIA fell 97.85 percent, from a No. 5 ranking to No. 127 in one year. The drop in value was $2.17 billion — almost all of the decrease in the two-way trade between MIA and Costa Rica.
MIA became one of the nation's leading hubs for gold trade during the global economic crisis — with Switzerland rising from South Florida's No. 29-ranked trade partner to No. 3 thanks to gold mined in Mexico and Colombia and then whisked to the European nation. But the air escaped from that balloon over the last couple of years as the global economy, and the U.S. economy in particular, managed to convince investors that the worst was over.
Only Brazil's trade with MIA fell more in dollars than Costa Rica's in 2015. Costa Rica's MIA trade dropped $2.52 billion in 2015.
In 2015, the value of gold imported into MIA — it flies rather than sails because of the desire to keep a close watch on its safe passage, given its value — fell 20.03 percent to $3.88 billion. On the export side, gold fell 48.20 percent to $1.58 billion. While those numbers affected markets like Colombia and Mexico, where it was first mined, and Switzerland, where most of it initially flew, it also affected newer sources and destinations: Peru and Bolivia on the import side and Hong Kong and the United Arab Emirates on the export side.
But, as the chart shows, MIA trade with Switzerland is up sharply in 2015. That's after several years of sharp decline and could presage heightened insecurity about the global economy again. Stay tuned.
There is some unfettered good news in the trade data, and that is MIA's trade with Argentina, the long-beleaguered nation that appears to be making headway in resolving its issue with investors holding the small percentage of its bonds from its 2001 default. MIA's trade with Argentina increased $339.89 million, a 15.70 percent increase over 2014 to a record $2.50 billion in trade.
That bump in trade is positively affecting both PortMiami and Port Everglades.
This is the fourth of six columns examining South Florida's 2015 trade with the world. The next two will focus on PortMiami and Port Everglades. The first three focused on South Florida's overall trade, its exports and its imports, respectively.


text:
Cuba: Diversity and Tourism
The Cuban archipelago, a fast-growing tourist destination in the Caribbean region, is characterized by its tourism-oriented diversity, including traditional sun and beach options and rich history, culture and nature.
Dozens of kilometers of excellent beaches are favored by the warm water surrounding the island.
The Cuban capital offers excellent beaches as part of the so-called Circuito Azul (Blue Circuit), which runs along 15 kilometers on the north coast and where Santa María del Mar stands out as one of the most beautiful beaches in the region. In western Cuba, the world-famous Varadero beach, which runs along 22 kilometers on the Hicacos peninsula, is one of the most visited destinations by foreign vacationers.
In addition, Bibijagua beach, on Isla de la Juventud (Isle of Youth), is famous for its black sand, while Marea del Portillo, in eastern Granma province, is characterized by its brown sand.
The archipelago's geographic location turns Cuba into a corridor for migratory birds that travel long distances from North America to South America and vice versa.
A large number of birds come to Cuba in winter and nest near rivers, lagoons and dams, as well as on the keys, turning the island nation into an excellent place for bird watching.
Diving can be practiced in more than 70,000 kilometers of Cuban insular platform, which has some 5,000 kilometers of coast bathed by the Atlantic Ocean and the Caribbean Sea.
Nearly 6,500 species of fish, crustaceans, sponges and mollusks, as well as many varieties of corals, turn the island into one of the best-preserved ecosystems in the region.
The world's second largest coral reef, which runs for 400 kilometers parallel to the keys Sabinal, Guajaba, Romano and Cruz, gets closer to Cuba's north coast in Santa Lucía beach. The coral reef is a safe haven for 200 species of sponges, 500 of fish and even the remains of 27 sunken ships.
Cuba complements the beauty of its coast and exuberant nature with its rich culture and traditions, which are essential components of the island's tourist product.
Fusions of races and customs in a centuries-old process gave way to Cuban culture, which is made up of African, aboriginal, Chinese, French and, of course, Spanish elements, creating a unique and rich combination at the same time.
Cities with a well-preserved Spanish colonial architecture, hotels linked to plastic arts, patrimonial sites and a busy schedule of celebrations and festivities make up Cuba's tourist offer.
Club Sabinal Los Pinos
Mirador del Mar
Playa Hermosa


2019 - Sangeeta Industries Pvt. Ltd.
Why Does Stainless Steel Rust and How to Avoid it?
How to do Quality Testing of Sheet Metal?
What Type of Welding is used for Steel and Aluminium Sheets?
Why Is Stainless Steel Fabrication Easy and Popular?


text:
Felix Lluberes Follow Felix Lluberes is founder, CEO, and Applications Architect at Position Logic, a leading B2B provider of GPS-tracking solutions, service, and support. Felix has over 17 years of experience in the software development industry as an engineer, consultant, developer, and manager. Felix is proud of Position Logic's family culture and his efforts to make Position Logic an awesome place to work. He welcomes anyone to reach out to him on Twitter @FelixLluberesPL
Techi » Software
Mozilla brings Australis and improved sync to Firefox Beta 29
Following the release of Firefox 28 just two days ago, Mozilla today updated its Firefox Beta channel to version 29 for Windows, Mac, Linux, and Android. This is a major release: Firefox Sync has been revamped and is now powered by Firefox Accounts, there's a new customization mode, and the major user interface overhaul Australis has finally arrived.
A day after releasing the stable version ofFirefox 28, Mozilla today launched the firstbeta version of Firefox 29. While there wasn't all that much interesting in Firefox 28, the latest beta version represents a major step for Mozilla. It includes both the new — and very Chrome-like — Australis design, as well as support for Firefox Sync, Mozilla's cloud-based syncing service withend-to-end encryption. The new design will likely be a bit controversial with long-time Firefox users.
« Google's reportedly planning to release a 8.9-inch Nexus tablet
Microsoft accidentally teases Windows Phone 8.1 on its website »
Opera will soon come with a free and unlimited…
There was a time when Opera was at the forefront of web browser innovation, and some of the features that it pioneered have become...
Chome extensions won't be able to secretly spy on…
There's not a single web browser out there that comes with all the features you could ever want, which is why extensions are such...
Chrome and Firefox might finally have a serious competitor
Opera used to be one of the most-innovative web browsers on the market, and is responsible for pioneering many of the features that have become...


"Stop taking our picture, mom!"
They're so cute in their matching outfits.
Those are definitely the kids of a proud military man.
Owen and Troy to the rescue!
These boys are ready for a day of fun.
You just HAVE to smile at this!
Our spidey senses are tingling.


A day after Jammu and Kashmir Liberation Front (JKLF) chairman Yasin Malik asked United Jihad Council (UJC) chief Syed Sallahuddin to announce a probe and come clear on killing of innocent people in North Kashmir's Sopore area, many mainstream political parties have denounced the statement saying militants have no role in investigating the killings.
While speaking to press on Wednesday, Malik had said there were two guns in the state -- a militant gun and the state gun (militants and soldiers) and both were condemning the killing of employees of the telecom companies.
"UJC has condemned the attacks, I can't ask the government but I will ask Syed Sallahuddin to probe and then find out who is responsible for killing of the innocent people in Sopore,'' Mallik said.
Calling the statement "self-styled from a self-styled leader,'' the ruling PDP said that Malik's remarks are of "no substance."
"Police are investigating the case and they would not react just because some self-styled leader has said something,'' said Waheed ur Rehman Parra.
While Malik offered no explanation, a source close to him said that he was "asking the militants to point out the culprits if they were not involved.'' Hardline separatist leader Syed Ali Shah Geelani and head of militant group Hizbul Mujahideen Syed Sallahudin had condemned the Sopore killings. Geelani had called the killings "acts of terrorism."
Meanwhile, cellular services remained affected in Sopore after militants killed two persons working with telecom companies earlier this week. Another person was seriously injured when unknown gunmen shot at him in Pattan late on Wednesday evening. The man has been identified as Imtiyaz Ahmad Nadroo, 25, a resident of Saad Mohalla Pattan, was the brother of a person who has rented out the space for installing a cellular tower.
Most of the mobile tower operators have shut down signal after unknown gunmen killed owner of a mobile tower in Sopore, 50 km from Srinagar late on Tuesday evening. This was the second killing in two days when the employees or those associated with telecom are being directly targeted by militants.
All the outlets of cellular companies in Sopore town in Baramulla district are shut since May 1, the day when unknown pistol-borne masked men simultaneously raided Bharti Airtel, Aircel and Vodafone outlets in the town asking them to stop operations.


NOTE: THE SERVICES ARE NOT INTENDED FOR PERSONS UNDER THE AGE OF 18. If you are under the age of 18, please do not use the Services and do not install any mobile applications from the Services on your mobile phone.
1.1 User Information. Rocket Launcher collects information from you when you voluntarily provide it to Rocket Launcher or one of its partners, through websites (owned and operated by Rocket Launcher or a third party); social networking, mobile, and other applications providers or other means (together, these sources are referenced hereafter as "Publishers"), which may include, without limitation, through online or offline surveys, order forms, or registration pages operated by us or third parties (collectively, a "User Form"). In a User Form, Rocket Launcher or a third party may offer you incentives in exchange for providing information about yourself such as name, email address, street address, zip code, telephone numbers, birth date, gender, salary range, education and marital status, occupation, employment information, and personal and online interests (together, "User Information"). Completing the User Form is voluntary and you are under no obligation to provide User Information.
1.2 Device Information. Rocket Launcher collects device (such as mobile phone, computer, or tablet) specific information (such as device unique identifier, operating system version, and other mobile network information, such as phone number) when you use the Services. We, or third party service providers who we use to provide services on our behalf, may also collect information such as location data (which may be precise or imprecise), voice and text search queries, and whether mobile phone is powered on or off).
1.3 User Behaviors Collected with Cookies, Web Beacons, and Other Information. Rocket Launcher collects information regarding your use of the Service, such as search queries. Rocket Launcher uses cookie and web beacon technology to associate certain Internet-related information about you, such as your Internet Protocol address and what Web browser you are using, with certain of your online behaviors, such as opening or clicking on a particular online advertisement. In addition to the foregoing-referenced technology, Rocket Launcher may use other new and evolving sources of information and information gathering in the future (together, "Technology Information").
(b) Web beacons. A web beacon is programming code used to display an image on a web page and can also transfer an individual's user identification to a database and associate the individual with previously acquired information about the individual. Web beacons enable Rocket Launcher to track certain Web sites you visit or advertisements you view online. Web beacons help determine products or services in which you may be interested and help track online behaviors for marketing purposes. More information about web beacons is available at http://www.webopedia.com/TERM/W/Web_beacon.html.
Websites. Rocket Launcher may set a cookie on your device when you view advertisements delivered through our Service or on Publisher websites. After a cookie is set, Rocket Launcher may track how you interact with the advertisement and the Services or Publisher website (for example, registering, purchasing, browsing, etc.).
Software Programs. Similar to Websites, Rocket Launcher displays banner advertisements in software programs that you may use.
1.4 Outside Information. Rocket Launcher may lawfully receive information about you from third parties, such as information located in public databases ("Outside Information").
1.5 No Information Collected from Minors. MINORS UNDER THE AGE OF 18 SHOULD NOT PROVIDE ANY PERSONAL INFORMATION, INCLUDING THEIR EMAIL ADDRESS, TO Rocket Launcher. If Rocket Launcher is notified it has personal information about a minor under the age of 18, that information will be promptly deleted from our database.
1.6 Individual Information. As used herein, "Individual Information" means User Information, Technology Information, Outside Information, and any other information Rocket Launcher lawfully obtains about you.
1.7 Microphone Access. If granted permission by a user, Rocket Launcher uses access to a phone's microphone to facilitate voice enabled search queries. All interaction and access to the microphone is user initiated, voice queries are not shared with third party apps or providers.
2.1 Discretion to Use Information. Information voluntarily provided to Rocket Launcher or lawfully obtained by Rocket Launcher is the property of Rocket Launcher and may be used by Rocket Launcher for any lawful purpose, including the sale, lease or transfer of the information to Publishers, advertisers and data aggregators, for marketing purposes.
2.2 Targeted Advertising and Information. Rocket Launcher uses Individual Information to target advertising and other information more effectively. When an individual is online, Rocket Launcher uses Technology Information to associate an individual with their Individual Information and Rocket Launcher attempts to show information and advertising for products and services to which the person may respond. Rocket Launcher may use data collected from a response to one type of advertising or information for targeting advertisements or other information through a different venue. For example, Rocket Launcher may notice that you responded to a baseball banner advertisement and use that response to deliver a baseball-related advertisement and other information to you.
2.3 Service Providers. Individual Information may be disclosed to third parties who are performing services on our behalf (which may include, without limitation, collecting data from Publishers).
2.4 Legal Process. Rocket Launcher may disclose Individual Information to respond to subpoenas, court orders and other legal process as required by law.
2.5 Summary Data. Rocket Launcher may sell or transfer non-individualized information, such as summary or aggregated anonymous information about all persons or sub-groups of persons.
2.6 Business Transition. Rocket Launcher may transfer all or part of your Individual Information as part of a business transition such as a merger, acquisition, or asset sale.
2.7 Storage of Individual Information. Rocket Launcher stores Individual Information in a database on Rocket Launcher computers. Rocket Launcher's computers have security measures, such as a firewall, to protect against the loss, misuse, and alteration of the information under Rocket Launcher's control. Rocket Launcher also maintains physical and procedural safeguards to protect Individual Information. Notwithstanding such measures, Rocket Launcher cannot guarantee that its security measures will prevent these computers from being illegally accessed and the Individual Information on them stolen or altered.
3.2 Links. The Services may contain hypertext links to the Websites of third parties. Rocket Launcher is not responsible for the privacy practices or the content of such other Websites.
3.3 Affiliated Companies that are not Publishers. Rocket Launcher may disclose or transfer Individual Information to wholly-owned or controlled Rocket Launcher entities in Rocket Launcher's discretion.
How You May Exercise Your Privacy Rights.
4.1 Websites. To prevent the display of Publisher or Rocket Launcher advertising on a Website, for example, banner advertisements, do not visit the Website. To only prevent Rocket Launcher from tracking your behavior on a Website, turn off cookies from that Website and do not click on or interact with any advertisements. Rocket Launcher does not have a mechanism or process to respond to any "do not track" signals which a web browser may send or receive, other than as described in this section.
4.2 Software Programs. To prevent Rocket Launcher software programs from displaying advertisements on your computer, uninstall the software program provided by Rocket Launcher by following the instructions provided in the Services. Software programs should include an option to uninstall in the "Add/Remove Programs" section of the Windows® operating system, or by visiting the file director of the installed program and running an uninstaller executable.
4.3 Cookies. Check instructions about your web browser to learn how to prevent placement of, or how to remove, cookies placed on your computer by Rocket Launcher.


After WWII, the area entered a part of utmost dynamics. the united states outpaced all different international locations. greater than 50 years later, it now not has the novel esprit that led to its hegemony. nonetheless, the United States of the knowledge revolution continues to be the world's purely superpower. yet because the necessity of switch, expressed in numerous systemic crises, sped up, the us fell into styles of reactive politics just like those who ended in the downfall of the Soviet Union. knowledgeable extra by means of the earlier upon which glossy the United States was once erected, this present day the united states is now in a reactionary mode, usually opposed to commitment to her personal welfare, freedom, and chance.
Taking the rewards of swap with no consideration, american citizens don't understand—as the Soviets didn't understand—what switch includes. staring at into the rear-view reflect (of faith, background, politics, financial system) within the desire of seeing the place switch may take them, they get the semblance that they're within the driver's seat. within the such a lot individualistic society on the earth, the person is topic to innovative disempowerment. The stupidity of dwelling a lifetime of fake expectancies and skewed values is wonderful for a society emphasizing info and data. including entitlement, corruption, and opportunistic engineering of truth, stupidity is the end result of complicated chance with systemic risk.
•Stupidity corresponds to dumbing-down around the social spectrum. Human personality and power are actively eroded regardless of remarkable growth in expertise and technological know-how. Values are twisted, confusion is cultivated, self-delusion informs offerings.
•Entitlement is excessive on the extremes of the social continuum. the rich and strong shape an aristocracy that believes that money, privilege, the simplest of every little thing is theirs by means of correct. The terrible, frequently the recipients of social welfare, internalize as an everlasting correct transitority reduction meant to assist conquer problems. among the extremes, the social continuum is dotted with a variety of entitlements in schooling (as insufficient because it is), enterprise (focused on revenue and consumption), and monetary innovation (entrusted to speculators). the proper to leisure arches over society, contributing to its elevated mediocrity.
•Corruption displays the truth that the USA used to be based no longer as a state yet as an financial system. This interprets into 1) a central authority in servitude to the economic system; and a couple of) a shopper profile with out civic measurement. lacking is the feel of accountability with out which freedom is incomprehensible.
•Engineering truth describes the method wherein realities are conceived and produced in line with comfort and opportunistic predicaments. ambitions (the correct to hold hands, a home for everybody, loose contraceptives, etc.) sanctify the ability. frequently, theories create "realities." "Truths" (such as attainable threats) are built to slot preconceived plans (e.g. wars).
The united states used to be based in an international extra just like the first century than the twenty first, and the Constitution—its working manual—reflects this truth. A "second American Revolution"— no longer of pitchforks, yet of principles—means a moment conference, this time consultant of the entire humans, not just the few who known as themselves "We the People." Its objective will be to supply a starting place for all times and paintings less than situations of quick swap. In an built-in global of possibilities and hazards linked to the worldwide info age, americans must struggle their very own stupidity, rather than battling the area they rely on for conserving their prosperity. below conditions of quick cycles of discovery and innovation, freedom and chance consequence from expert engagement, no longer from indulgence on the fee of the remainder of humankind. the method of remaking the US also will remake american citizens, as accountable electorate of the realm. Addressing sustainability isn't like being addicted shoppers awaiting extra prosperity at regardless of whose expense.
This booklet addresses the relevant query of the way the pursuits of the bad achieve illustration within the political strategy via interpreting the curiosity workforce system.
The intelligence disasters surrounding the invasion of Iraq dramatically illustrate the need of constructing criteria for comparing specialist opinion. This ebook fills that want. right here, Philip E. Tetlock explores what constitutes common sense in predicting destiny occasions, and appears at why specialists are frequently flawed of their forecasts.
This is often an built-in diversity of stories targeting Wales through a original and internationally-recognised educational authority and member of the home of Lords at the enhance of democracy and the evolving proposal of nationwide id in sleek Britain. It casts again to the effect of swap in Europe and the broader global from the 1789 Revolution in France onwards, overlaying key personalities comparable to Lloyd George and the effect of the 1st international struggle in Wales.
The publication builds an leading edge theoretical framework, wherein formerly ignored foreign components are introduced into the research of transitions to democracy. The case of Algeria is then explored in nice aspect. This quantity is a crucial contribution to the literature on democratization and gives an attractive research of Algerian politics over the last twenty years.


The Nigerian Vice President has claimed that the Federal government spends 594 Cattle, 138,000 Chickens, 6.8 million Eggs, 83 Metric Tonnes of Fish Weekly to feed School Children in Nigeria. According to Yemi Osinbajo, while delivering a lecture titled 'Nigeria Rising: The Path to Prosperity' at the University of Lagos (UNILAG) 50th convocation, he said that at a cost of $0.19 per child per day, the FG is able to provide a balanced meal for every one of the 9,300,892 pupils in 49,837 public primary schools in 26 states across Nigeria.
The programme, according to him, employs 95,422 cooks and over 100,000 small holder farmers linked to the programme supplying locally sourced ingredients.
"The programme aims to provide 50% of the recommended nutrient intake targets for protein and prioritized micro-nutrients including iron, iodine, zinc, vitamin A, folate and vitamin C and 30% of energy because of the high burden of under-nutrition and micro-nutrient deficiencies in Nigeria.


text:
Nicholas Negroponte: Steve Jobs - Influence, Not Influenced.
Forbes Guest Contributor
Velocity Contributor Group
Gallery: Steve Jobs
By Nicholas Negroponte, founder and chairman of One Laptop per Child
I first met Steve in 1979, when the idea of merging design and computation was considered sissy or silly. Not to Steve. A fact not widely known: He was one of the first funders (1980) of the MIT Media Lab, then a mere inkling rather than a place, with a gift of $500,000, which he could ill afford at the time.
Shortly after, my partner Jerome Wiesner introduced Steve to Edwin Land. I recall the meeting in Cambridge well. It lead to a fast friendship with Land and the subsequent strong influence of Polaroid's graphics and style. Soon thereafter Steve was the influence, not influenced.
When I started One Laptop per Child (OLPC), the first person I went to was Steve. In 2003 I believed that the most expensive part of a laptop was the display (50-65% at the time) and the way to drop that cost, and to make a less than $100 laptop, was to project the image rather than use an LCD. We made an unfolding laptop that rear-projected the image from a tiny chip, itself possibly less than $5.
I took my mechanical model to Steve's house in Palo Alto and showed him. He smiled. He said, "Nicholas, this looks like a science project." Forget rear-projection. Use an LCD. He was right.
Complete Coverage: Steve Jobs
Three years later, April 2007, I brought him one of the first XO laptops, which has a wonderful and special LCD. We spent two hours. He promised to use the laptop over the weekend and write me. Three weeks later he did:
Date: Fri, 18 May 2007 20:00:08 -0700
From: Steve Jobs
To: Nicholas Negroponte
Cc: Steve Jobs
Nicholas,
We've know each other a long time - too long for me to do anything
other than tell you what I think….the software is some of the worst
I've ever seen…
Please don't be too mad at me...
Your old friend,
Harsh, but right. It took the next three years to fix the software.
I wish I could show him our tablet.
Nicholas Negroponte is founder and chairman of the One Laptop per Child non-profit association, and formerly co-founder and director of the MIT Media Lab.
Fred Anderson: There Will Never Be Another Steve Jobs
Yves Béhar: Steve Jobs Changed My Life
The Statement From Apple's Board
Steve Jobs 2005 Stamford Commencement Address
Forbes Guest


text:
Q: Create index on existing table Oracle Is it safe to create an index on an existing table in oracle?
Like this:
CREATE INDEX table_sample_ix03
      ON table_sample
(
  col4,
  col22
)
TABLESPACE data
STORAGE
(
  INITIAL        10M    NEXT          2M
  MINEXTENTS      1     MAXEXTENTS  100
  PCTINCREASE     0
)
;

A: Yes. But if possible, you should do it while no one is updating the table, because they would suffer performance-wise (it is still safe to do it anyway, there will be no data corruption).

A: The ONLINE clause is recommended when you create the index while DML queries are being run on the table. See http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_5010.htm
Example:
CREATE  INDEX "MYINDEX" ON "MYTABLE" ("MYCOLUMN")  ONLINE;

A: Yes. Why wouldn't it be?
I can only think of possible performance issues just after issuing the command. If the table is very large, the indexing can take some time but other than that, it should be fine.

redpajama_set_name: RedPajamaStackExchange


The Adventures of Pajama Girl: The Coronation of the Cupcake Queen by Sandra Hagee Parker is a Christian story is about two sisters who have delightful dreams inspired by their pajamas. Ellie, AKA Pajama Girl, has an awesome bedtime routine of choosing out pajamas that will inspire her dreams that night. In this story, she chose cupcake printed pajamas and dreamed about the Cupcake Kingdom where she met the Cupcake Queen. Ellie's younger sister, Princess Sis, was there for the adventures as well.
The Adventures of Pajama Girl is best suited for children 4-8 years old. My youngest is 3, and my cousin who we babysit is 1, both enjoyed this story as well. I honestly believe children of any age will enjoy this story.
The illustrations in this story are cute and hand-drawn. The imagination of children is limitless and this story reflects on that. All children will be able to relate to Ellie and her sister. It may even inspire children to wear their own magical pajamas to create wonderful dreams for themselves. So join the Pajama Girls and go on an adventure to help the Cupcake Queen find the sprinkles for her coronation ceremony!
Like many books for children, there is a moral to the story. This story deals with the effects of stealing and how it can effects others feelings. The children are able to work together to fix the situation to make it right for everyone!
If you decide to pre-order the book, be sure to sign up for free updates and coloring pages!
Be sure to enter our giveaway for a chance to win a copy of The Adventures of Pajama Girl!


SDR Ventures is pleased to announce that Ketelsen Campers of Colorado ("Ketelsen Campers") has been acquired by Camping World Holdings Inc. ("Camping World"). SDR served as the exclusive sell-side advisor to Ketelsen Campers throughout the transaction process.
Founded by Johnny Ketelsen, a pioneer in the Midwest in the emerging RV industry in the 1960s, Ketelsen Campers of Colorado is one of the oldest and most well-respected RV dealers in Colorado. The dealership, located in Wheat Ridge, Colorado, maintains a selection of hundreds of new and used towable campers and has been awarded many honors including being named a "Top 5 RV Dealership in North America" by RV Business Magazine in 2015. Second-generation President Randy Ketelsen enlisted SDR Ventures to sell the Company so that he could retire from the business.


Remove the two silver T6 Torx screws securing the battery connector to the lower case.
Disconnect the large gray and black battery connector cable from the left I/O board.
Thread the gray and black power cable beneath the speaker cable, and lift the battery connector out of the computer.


text:
A Birthday Meal At One Of The Best Restaurants In The Country
John Patrick June 21st, 2022
So, her birthday falls on the 17th. She enjoys birthdays. They're a big deal in her world. She likes a "fuss"
I decided that this year, her gift wouldn't be a "thing", but an "experience".
Quite possibly her favorite restaurant is "The Grey" in Savannah.
The Grey is co-owned by John Morisano (he bought the land on which the old Greyhound bus station sat) and Mashama Bailey, who also serves as head chef. As a matter of fact, Chef Bailey, just last week, was named the James Beard award winner as Best Chef in the country.
Four years ago, The Grey made Time magazine's list of one of the World's 100 Greatest Places.
It's not why we went. We went because it's her favorite. But the accolades don't hurt.
I made reservations about six weeks ago, and could only get them for 5:15pm. They open at 5pm.
Interesting concept. There's a "Diner Bar" in the front of the restaurant. It's "first come, first serve", which explained the line when we arrived. The Diner Bar has more of a tapas feel, with numerous choices on the menu.
We were taken to the main dining room for our meal, which remember, used to be a bus station.
Right from the start, you notice the service. The attention to detail, nothing is missed.
The menu is a bit different. There are four categories, "Dirt", "Water", "Pasture" and "Pantry". It's a three course meal at $75 per person. You then choose three items from the choices. She chose from the Dirt category, the Butternut Squash. I chose two from the Water category, the Tuna Crudo and Middlins. She also chose Middlins. For the entree, she chose a fish that was off the menu, I chose the chicken.
It's almost impossible to describe the plates, the flavors, the brilliance of a chef named the best in the Country. By the way, Chef Bailey was not there. She was in Austin, opening another "Diner Bar" located in one of Austin's many high end hotels.
It's not inexpensive. Be prepared to pay. But also be prepared to have one of the best meals you've ever had.
Oh, my desert, and orange/chocolate torte, with orange zest and orange ice cream, which they make. (Of course they do)
There are a lot of dining options in Savannah. As I've mentioned this experience to people, they've countered with favorites of theirs and one day, we might try other options. But I'm pretty sure that any future trip to the city, will include a stop at The Grey.
The next time you're there, you should consider the same.
WGAC
WGAC On Air